放大溢出:滚动

时间:2015-12-10 08:07:37

标签: css

我正在尝试以css方式正确实现缩放和缩放。我用缩放视图创建了一个示例。单击时,视图应缩放,然后才能滚动。

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

我有几个问题:

  1. 我可以以某种方式摆脱margin-left班级上的margin-top.zoomed吗?我没有设法扩展它,没有必要转移它与这些边距。
  2. 点击后,我可以按clientX获取点击位置。我想用它在缩放过程中流畅地滚动到点击的位置。 但是我无法管理滚动流畅,当删除边距时,它有点跳跃并且不好看。
  3. 放大并将滚动条移动到中央然后缩小时,您可以看到缩放效果不佳,因为它首先向右滚动。有没有办法阻止它?
  4. 当您在OSX上滚动到Chrome中的角落时,它往往会在浏览器中向后/向前导航。有没有办法防止这种行为?
  5. 更新:

    第一部分可以用transform-origin: 0 0解决。其他问题与证明的大致相同。

2 个答案:

答案 0 :(得分:2)

嗯......我可以说用现有的浏览器来满足你的条件是不可能的。支持。另一种是可能的,如本演示所示:



$(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>
&#13;
&#13;
&#13;

正如你所看到的,缩放&amp;滚动非常滞后,特别是当最右边的尺寸放大时。

原因很简单,因为jQuery和css都有自己的动画循环,并且它们不同步。为了解决这个问题,我们需要以某种方式设法同时进行滚动和放大。仅使用一个系统(jQuery或CSS)缩放动画。

问题是:jQuery没有缩放功能,css无法滚动元素。精彩。

如果您可以使用宽度/高度进行缩放,则可以使用jquery width&amp; height animate()。但如果#slider由许多组件组成,我想它无法完成。

所以,写一个答案只是为了说它不可能是一种失望,所以我想也许我可以提出一个替代方案,使用拖动来滚动内容(类似于Google地图的工作方式):< / p>

&#13;
&#13;
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;
    }
  });
});
&#13;
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;
}
&#13;
<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>
&#13;
&#13;
&#13;

这种变化通过牺牲滚动条(这是非常丑陋的imo,谁需要它?)并使用css left来设法让CSS做两个动画。

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

答案 1 :(得分:1)

我将单独解决这些问题,然后在最后给出一个例子。

  

点击后,我可以通过clientX获取点击位置。我想要   在缩放过程中使用它可以流畅地滚动到单击的位置。

在我看来,在过渡期间滚动动画在webkit浏览器中可能有些不稳定。尝试平衡jQuery效果的动画时间和css过渡的动画时间。

  

放大并将滚动条移动到中央然后缩小时,您可以看到缩放效果不佳,因为它首先向右滚动。有没有办法阻止它?

scrollLeft的{​​{1}}属性恢复为div#window。再次,调整动画时间会使这不那么生涩。

  

当您在OSX上滚动到Chrome中的角落时,它往往会在浏览器中向后/向前导航。有没有办法防止这种行为?

您可以使用0pxmouseover个事件在mouseout上切换overflow:hidden css。

以下是您的代码的示例更改:

body

updated fiddle