平滑缩放 img 并自动 scrollIntoView

Posted

技术标签:

【中文标题】平滑缩放 img 并自动 scrollIntoView【英文标题】:Smoothly scale an img and automatically scrollIntoView 【发布时间】:2022-01-03 18:25:02 【问题描述】:

我正在尝试设置一个基本功能,以平滑地将点击时的 img 从比屏幕长切换到显示(适合窗口大小)(来回)。它已经使用百分比等工作了。

我的问题是我希望在 2 个状态之间进行平滑的动画转换,但 img 被粗暴地缩放。 此外,每当我尝试使用“过渡”或“动画”时,当 img 恢复到其原始大小时,它会阻止滚动。我尝试使用关键帧后也出现了同样的问题。

<!DOCTYPE html>
<html>
<head>
    <script src="jquery.js"></script>
    <style>
        img 
            margin: auto;
            display: block;
            padding: 2%;
            width: 90vw;
            box-sizing: border-box;
        
        .scaled 
            width: auto;
            height: 100vh;
        
        
    </style>
</head>
<body>
    <img class="item" src="images/kitten1.png"> 
    <img class="item" src="images/kitten2.png">
    <img class="item" src="images/kitten3.png">
</body>
<script>
    $(".item").click(function() 
        $(this).toggleClass('scaled');
        $(this).scrollIntoView();
    );
</script>
</html>

我还想让窗口视图(我的意思是页面上滚动的位置)在缩放时以 img 为中心。我目前正在尝试为此目的使用 scrollIntoView,但似乎没有任何反应。

提前谢谢你。第一次在这里发帖。我不觉得这应该太难,但可能与我现在能想出的水平不同ଘ(੭ˊᵕˋ)੭ ̀ˋ


还尝试了以下方法,但 img 停留在 90vw 和 100vh ...

<!DOCTYPE html>
<html>

<head>
    <script src="jquery.js"></script>
    <style>
        img 
            margin: auto;
            display: block;
            padding: 2%;
            width: 90vw;
            box-sizing: border-box;
            object-fit: contain;
        
    </style>
</head>

<body>

    <img class="item" src="images/kitten1.png">
    <img class="item" src="images/kitten2.png">
    <img class="item" src="images/kitten3.png">

</body>
<script>
    $(".item").click(function() 
    if ($(this).hasClass('scaled')) 
        $(this).animate(
            height: "none",
            width: "90vw"
        , 1000);
        $(this).removeClass('scaled');
    
        else 
            $(this).animate(
            width: "none",
            height: "100vh"
        , 1000);
        $(this).addClass('scaled');
        
    );

</script></html>

【问题讨论】:

【参考方案1】:

要滚动到单击的项目,请使用 $(this)[0].scrollIntoView();,因为 .scrollIntoView()javascript 函数,而不是 jQuery。

平滑缩放(过渡)。

CSS 不支持从自动宽度到特定宽度或从相同到高度的过渡。参考:1,2

选项 1。改用一侧。

您只能使用max-heightmax-width。好消息是您编写的 JavaScript 和 CSS 响应式(媒体查询)更少,也无需任何添加即可支持。不好的是它只支持一侧(宽度或高度)。

完整代码:

<!DOCTYPE html>
<html>
<head>
    <script src="jquery.js"></script>
    <style>
        img 
            margin: auto;
            display: block;
            padding: 2%;
            max-width: 100vw;
            box-sizing: border-box;
            transition: all .3s;
        

        .scaled 
            max-width: 50vw;
        
    </style>
</head>
<body>
    <img class="item" src="images/kitten1.png"> 
    <img class="item" src="images/kitten2.png">
    <img class="item" src="images/kitten3.png">
</body>
<script>
    $(".item").click(function() 
        $(this).toggleClass('scaled');
        $(this)[0].scrollIntoView(
            behavior: "smooth"
        );
    );
</script>
</html>

See it in action

选项 2. 使用 JavaScript。

下面的代码将使用大量的 JavaScript 来使 CSS 从宽度到高度的转换正常工作。好事:当然支持宽度和高度之间的过渡。坏事:响应式图像的 CSS 媒体查询将无法正常工作。需要更多的 JS。

<!DOCTYPE html>
<html>
<head>
    <script src="jquery.js"></script>
    <style>
        img 
        margin: auto;
        display: block;
        padding: 2%;
        box-sizing: border-box;
        transition: all .3s;
        height: auto;
        width: 90vw;
    

    .scaled 
        height: 100vh;
        width: auto;
    
    </style>
</head>
<body>
    <img class="item" src="images/kitten1.png"> 
    <img class="item" src="images/kitten2.png">
    <img class="item" src="images/kitten3.png">
</body>
<script>
  $(window).on("load", function() 
    // wait until all images loaded.
    // loop each <img> that has class `item` and set height.
    $('img.item').each((index, item) => 
      $(item).attr('data-original-height', $(item)[0].offsetHeight);
      $(item).css(
        'height': $(item)[0].offsetHeight
      );
    );
  );


  $(".item").click(function() 
    if ($(this).hasClass('scaled')) 
      // if already has class `scaled`
      // going to remove that class after this.
      if ($(this).attr('data-scaled-width') === undefined) 
        // get and set original width to data attribute.
        $(this).attr('data-scaled-width', $(this)[0].offsetWidth);
      
      $(this).css(
        'height': $(this).data('originalHeight'),
        'width': ''
      );
      $(this).removeAttr('data-original-height');

      $(this).removeClass('scaled');
     else 
      // if going to add `scaled` class.
      if ($(this).attr('data-original-height') === undefined) 
        // get and set original height to data attribute.
        $(this).attr('data-original-height', $(this)[0].offsetHeight);
      
      $(this).css(
        'height': '',
        'width': $(this).data('scaledWidth')
      );
      $(this).removeAttr('data-scaled-width');

      $(this).addClass('scaled');
      // check again to make sure that width has been set.
      if ($(this)[0].style.width === '') 
        setTimeout(() => 
          console.log($(this)[0].style.width);
          $(this).css(
            'width': $(this)[0].offsetWidth
          );
          console.log('css width for image was set after added class.');
        , 500);// set timeout more than transition duration in CSS.
      
    

    $(this)[0].scrollIntoView(
      behavior: "smooth"
    );
  );
</script>
</html>

See it in action

【讨论】:

在小提琴上看起来很完美,谢谢。我仍然不知道为什么,但是当我尝试在我的括号上使用它时,点击后滚动卡住了。您认为这是由于 Bracket 造成的,我应该使用其他软件吗? 确保scrollIntoView()$(this)[0] 一起使用(必须有[0] 才能成为普通的JS 选择器)。 不得不改变vscode这不是一件坏事,最后没问题。但是有一个问题:我希望图像从最大宽度变为最大高度,这不适用于此解决方案(注意到它很晚,因为我认为我已经解决了这个问题)。你对此有什么想法或技巧吗? 我试过了,但不可能。对不起。 @AlexandreD。我已更新代码以使用更多 JS,请重试。它现在应该在宽度 高度之间的过渡交叉处工作。

以上是关于平滑缩放 img 并自动 scrollIntoView的主要内容,如果未能解决你的问题,请参考以下文章

Qt应用程序中的高dpi缩放使图标平滑

UIView中矢量图形的平滑缩放

用imgproxy自动缩放图片

适用于 Android/IOS 的 Canvas 上的 Unity 平滑移动和缩放 UI

自动缩放图像以匹配文本高度

Flexbox 使用原始 SVG 宽度而不是缩放宽度