放大溢出:滚动 [英] Zooming in overflow: scroll

查看:122
本文介绍了放大溢出:滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现正确缩放和缩放css的方式。我创建了一个缩放视图的示例。点击时,视图应缩放,然后可以滚动。



https://jsfiddle.net/opb5tcy8/4/



我遇到了几个问题:

$ b $我可以以某种方式摆脱 margin-left margin-left。
<在 .zoomed 类上的

  • 点击时,我可以通过 clientX
  • 获得点击位置。 code>。我想使用它在缩放过程中流畅地滚动到点击位置。 但是我不能管理滚动流畅,当删除边距左边是一种跳跃和不好。
  • 当放大和移动滚动到中心,然后缩小,你可以看到缩放不好,因为它第一次向右滚动。有什么方法可以防止吗?

  • 当您在OSX上滚动到Chrome的角落时,它往往会在浏览器中向后/向前浏览。是否有办法防止此行为?

  • UPDATE:



    第一部分可以用 transform-origin:0 0 解决。

    解决方案

    Hm ...我可以说不可能满足点2你的条件与当前浏览器的支持。其他是可能的,如在这个演示:



      $(document).ready(function(){var windowHalfWidth = $(#window)。width()/ 2; var scalingFactor = 0.55; var throtte = false; $(#slider)。 up; if(throtte)return false; throtte = true; setTimeout(function(){throtte = false;},1000); var xSelf = event.pageX  -  $(#window)。 #window)。scrollLeft(); if($(this).hasClass(zoomed)){$(#window)。animate({scrollLeft:(xSelf / scalingFactor  -  windowHalfWidth)},1000,线性);} else {$(#window)。animate({scrollLeft:(xSelf * scalingFactor  -  windowHalfWidth)},1000,linear );});});  

     

     < script src =https://ajax.googleapis.com /ajax/libs/jquery/2.1.1/jquery.min.js\"> ;</script> ;<div id =window> < div id =sliderclass =zoomed> < div id =obj1> 1< / div> < div id =obj2> 2< / div> < div id =obj3> 3< / div> < div id =obj4> 4< / div> < div id =obj5> 5< / div> < / div>< / div>  



    参见,缩放&滚动是相当滞后,特别是当最右边的大小放大。



    原因很简单,因为jQuery和css都有自己的动画循环,他们不是同步中。为了解决这个问题,我们需要以某种方式管理滚动和放大。缩放动画只有一个系统,jQuery或CSS。



    问题是:jQuery没有缩放功能,并且css不能滚动元素。很好。



    如果你的缩放比例可以通过宽度/高度来完成,那么可以使用jquery width& height animate()。但是如果 #slider 由许多组件组成,我想它不能做。






    所以um写一个答案只是说这是不可能的是一种让步,所以我想也许我可以建议一个替代,使用拖动滚动内容(类似于Google地图工作的方式):



      var windowHalfWidth,startX,startLeft,minLeft,dragging = false,zooming = false; var zoomElement = function(event){ var xSelf = event.pageX  -  $(#window)。offset()。left  -  parseFloat($(#slider)。css(left)); if($(#slider)。hasClass(zoomed)){minLeft = windowHalfWidth * 2  -  900; var newLeft = Math.min(Math.max(( - (xSelf / 0.55- windowHalfWidth)),minLeft),0); $(#slider)。css(left,newLeft +px); } else {minLeft = windowHalfWidth * 2  -  900 * 0.55; var newLeft = Math.min(Math.max(( - (xSelf * 0.55- windowHalfWidth)),minLeft),0); $(#slider)。css(left,newLeft +px); }; $(#slider)。toggleClass(zoomed);} $(document).ready(function(){windowHalfWidth = $(#window)。width()/ 2; minLeft = windowHalfWidth * 900 * 0.55; $(#slider)。on({mousedown:function(event){dragging = true; startX = event.pageX; startLeft = parseFloat($(this).css(left));} ,mousemove:function(event){if(dragging&!; zooming){var newLeft = Math.min(Math.max((startLeft + event.pageX-startX),minLeft),0); $(滑块)css(left,newLeft +px);}},mouseup:function(event){dragging = false; if(Math.abs(startX- event.pageX)< 30& !zooming){//简单事件阻止以防止点击垃圾邮件zooming = true; $(#slider)css(transition,1s); setTimeout(function(){zooming =滑块)css(transition,initial);},1000); zoomElement(event);}},mouseleave:function(){dragging = false; }});});  

      body {background-color :#eee; margin-top:10px; / *在SO *中减少边距以便查看* /}#window {width:500px; height:200px; margin:0 auto; overflow:hidden; border:1px solid#999;位置:相对; background-color:white;}#slider {width:900px; height:600px; background-color:#fff; position:absolute; top:0;左:0; transform-origin:0 0;}#slider.zoomed {transform:scale(0.55);}#slider div {width:50px; height:50px; line-height:50px; position:absolute; top:75px; background-color:#eee; text-align:center; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none;}#obj1 {left:10px;}#obj2 {left:210px;}#obj3 {left:410px;}#obj4 {left:610px;}#obj5 {left:810px;}  

     < script src =https://ajax.googleapis.com /ajax/libs/jquery/2.1.1/jquery.min.js\"> ;</script> ;<div id =window> < div id =sliderclass =zoomed> < div id =obj1> 1< / div> < div id =obj2> 2< / div> < div id =obj3> 3< / div> < div id =obj4> 4< / div> < div id =obj5> 5< / div> < / div>< / div>  



    通过牺牲滚动条(这是相当丑陋的imo,谁需要它?)并使用css left 代替。 b

    所以我希望如果最终你找不到一个好的解决方案,至少你有这个考虑作为后退版本。


    I am trying to implement correctly scaling and zooming in css way. I created an example with scaled view. When click, the view should be zoomed and then to be able to scroll.

    https://jsfiddle.net/opb5tcy8/4/

    I have several issues with it:

    1. Can I somehow get rid of the margin-left and margin-top on the .zoomed class? I did not manage to scale it without necessity to shift it with these margins.
    2. When clicked, I can get the click position by clientX. I would like to use it to fluently scroll to the clicked position during zooming. However I can't manage the scroll to be fluent and when removing the margin-left it is kind of jumpy and not nice.
    3. When you zoom in and move the scroll to the center and then zoom out, you can see the zoom is not nice as it first scrolls to the right. Is there a way to prevent it?
    4. When you scroll to corners in Chrome on OSX it tends do navigate back/forward in browser. Is there a way to prevent this behaviour?

    UPDATE:

    The first part can be solved with transform-origin: 0 0. The other issues stays mostly the same as it is demonstrated.

    解决方案

    Hm... I could say it is impossible to satisfy point 2 your condition with current browsers' support. The other are possible, as in this demo:

    $(document).ready(function() {
      var windowHalfWidth = $("#window").width() / 2;
      var scalingFactor = 0.55;
      var throtte = false;
      
      $("#slider").click(function(event) {
        
        //Simple event throtte to prevent click spamming breaking stuff up
        if (throtte) return false;
        throtte = true;
        setTimeout(function() {
          throtte = false;
        }, 1000);
        
        var xSelf = event.pageX - $("#window").offset().left + $("#window").scrollLeft();
    
        if ($(this).hasClass("zoomed")) {
    
          $("#window").animate({
            scrollLeft: (xSelf / scalingFactor - windowHalfWidth)
          }, 1000, "linear");
        } else {
    
          $("#window").animate({
            scrollLeft: (xSelf * scalingFactor - windowHalfWidth)
          }, 1000, "linear");
        }
    
        $("#slider").toggleClass("zoomed");
      });
    });

    body {
      background-color: #eee;
      margin-top: 10px; /*reduced margin for easier view in SO */
    }
    
    #window {
      width: 500px;
      height: 200px;
      margin: 0 auto;
      overflow-x: auto;
      overflow-y: hidden;
      border: 1px solid #999;
      position: relative;
      background-color: white;
    }
    
    #slider {
      width: 900px;
      height: 600px;
      background-color: #fff;
      position: absolute;
      transition: 1s linear;
      top: 0;
      left: 0;
      transform-origin: 0 0;
    }
    
    #slider.zoomed {
      transform: scale(0.55);
    }
    
    #slider div {
      width: 50px;
      height: 50px;
      line-height: 50px;
      position: absolute;
      top: 75px;
      background-color: #eee;
      text-align: center;
    }
    
    #obj1 {
      left: 10px;
    }
    
    #obj2 {
      left: 210px;
    }
    
    #obj3 {
      left: 410px;
    }
    
    #obj4 {
      left: 610px;
    }
    
    #obj5 {
      left: 810px;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="window">
      <div id="slider" class="zoomed">
        <div id="obj1">1</div>
        <div id="obj2">2</div>
        <div id="obj3">3</div>
        <div id="obj4">4</div>
        <div id="obj5">5</div>
      </div>
    </div>

    As you can see, the zooming & scrolling is quite laggy, especially when the far right size is zoomed in.

    The reason is simple, because jQuery and css both have their own animation loop, and they are not in sync. In order to solve this we'll need to somehow manage to do both scrolling & scaling animations with only one system, either jQuery or CSS.

    Problem is: jQuery don't have a scaling feature, and css can't scroll elements. Wonderful.

    If your scaling can be done with width/height though, it would be possible, using jquery width&height animate(). But if the #slider consists of many components I guess it can't be done.


    So um writing an answer just to say it's impossible is kind of a let down, so I think maybe I can suggest an alternative, using dragging to scroll content (similar to the way Google map work):

    var windowHalfWidth, startX, startLeft, minLeft, dragging = false,
      zooming = false;
    
    var zoomElement = function(event) {
      var xSelf = event.pageX - $("#window").offset().left - parseFloat($("#slider").css("left"));
    
      if ($("#slider").hasClass("zoomed")) {
    
        minLeft = windowHalfWidth * 2 - 900;
    
        var newLeft = Math.min(Math.max((-(xSelf / 0.55 - windowHalfWidth)), minLeft), 0);
        $("#slider").css("left", newLeft + "px");
      } else {
    
        minLeft = windowHalfWidth * 2 - 900 * 0.55;
    
        var newLeft = Math.min(Math.max((-(xSelf * 0.55 - windowHalfWidth)), minLeft), 0);
        $("#slider").css("left", newLeft + "px");
      }
    
      $("#slider").toggleClass("zoomed");
    }
    
    $(document).ready(function() {
      windowHalfWidth = $("#window").width() / 2;
      minLeft = windowHalfWidth * 2 - 900 * 0.55;
    
      $("#slider").on({
        mousedown: function(event) {
          dragging = true;
          startX = event.pageX;
          startLeft = parseFloat($(this).css("left"));
        },
        mousemove: function(event) {
          if (dragging && !zooming) {
            var newLeft = Math.min(Math.max((startLeft + event.pageX - startX), minLeft), 0);
            $("#slider").css("left", newLeft + "px");
          }
        },
        mouseup: function(event) {
          dragging = false;
    
          if (Math.abs(startX - event.pageX) < 30 && !zooming) {
            // Simple event throtte to prevent click spamming
            zooming = true;
            $("#slider").css("transition", "1s");
    
            setTimeout(function() {
              zooming = false;
              $("#slider").css("transition", "initial");
            }, 1000);
    
            zoomElement(event);
          }
        },
        mouseleave: function() {
          dragging = false;
        }
      });
    });

    body {
      background-color: #eee;
      margin-top: 10px; /*reduced margin for easier view in SO */
    }
    #window {
      width: 500px;
      height: 200px;
      margin: 0 auto;
      overflow: hidden;
      border: 1px solid #999;
      position: relative;
      background-color: white;
    }
    #slider {
      width: 900px;
      height: 600px;
      background-color: #fff;
      position: absolute;
      top: 0;
      left: 0;
      transform-origin: 0 0;
    }
    #slider.zoomed {
      transform: scale(0.55);
    }
    #slider div {
      width: 50px;
      height: 50px;
      line-height: 50px;
      position: absolute;
      top: 75px;
      background-color: #eee;
      text-align: center;
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
      user-select: none;
    }
    #obj1 {
      left: 10px;
    }
    #obj2 {
      left: 210px;
    }
    #obj3 {
      left: 410px;
    }
    #obj4 {
      left: 610px;
    }
    #obj5 {
      left: 810px;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
    <div id="window">
      <div id="slider" class="zoomed">
        <div id="obj1">1</div>
        <div id="obj2">2</div>
        <div id="obj3">3</div>
        <div id="obj4">4</div>
        <div id="obj5">5</div>
      </div>
    </div>

    This variation manages to get CSS to do both animation, by sacrificing the scrollbar (which is pretty ugly imo, who needs it?) and use css left instead.

    So I hope if in the end you can't find a good solution, at least you have this to consider as fall back version.

    这篇关于放大溢出:滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆