放大溢出:滚动

Vojtech

我正在尝试以CSS方式正确执行缩放和缩放。我创建了一个带有缩放视图的示例。单击时,应先缩放视图,然后才能滚动视图。

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

我有几个问题:

  1. 我可以以某种方式摆脱margin-leftmargin-top.zoomed类?我没有设法扩大规模,而不必以这些余量来转移它。
  2. 单击后,我可以通过点击获得位置clientX我想用它在缩放过程中流畅地滚动到单击位置。但是我无法使滚动条流畅,并且在删除左边距时,它有点跳动并且不好。
  3. 放大并将滚动条移到中心然后缩小时,您会看到缩放效果不好,因为它先滚动到右侧。有办法防止吗?
  4. 当您在OSX上的Chrome中滚动到角落时,往往会在浏览器中向后/向前导航。有办法防止这种行为吗?

更新:

第一部分可以用解决transform-origin: 0 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>

如您所见,缩放和滚动非常缓慢,尤其是在放大最右边的尺寸时。

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

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

如果可以使用width / height进行缩放,则可以使用jquery width&height animate()进行缩放。但是,如果#slider由许多组件组成,我想那是不可能完成的。


因此,让我写一个答案只是说不可能是一件令人失望的事情,所以我想也许我可以建议一种替代方法,使用拖动来滚动内容(类似于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 * 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>

通过牺牲滚动条(这是非常丑陋的imo,谁需要它?)并使用css,此变体设法使CSS能够同时执行这两种动画left

因此,我希望最后找不到一个好的解决方案,至少您可以将此作为后备版本。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章