css - 放大溢出 : scroll

标签 css

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

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

我有几个问题:

  1. 我能以某种方式去掉 .zoomed 类中的 margin-leftmargin-top 吗?我没有设法在没有必要以这些边距移动它的情况下对其进行缩放。
  2. 点击时,我可以通过clientX获取点击位置。我想用它在缩放过程中流畅地滚动到点击的位置。 但是我无法使滚动变得流畅,并且当移除 margin-left 时它有点跳动而且不太好。
  3. 当您放大并将滚动条移动到中心然后缩小时,您可以看到缩放效果不佳,因为它首先滚动到右侧。有什么办法可以预防吗?
  4. 当您在 OSX 上的 Chrome 中滚动到 Angular 落时,它往往会在浏览器中向后/向前导航。有没有办法防止这种行为?

更新:

第一部分可以用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 不能滚动元素。太棒了。

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


所以嗯,写一个答案只是说这是不可能的有点让人失望,所以我想也许我可以建议一个替代方案,使用拖动来滚动内容(类似于谷歌地图的工作方式):

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>

这个变体通过牺牲滚动条(在我看来,这是非常丑陋的,谁需要它?)并改用 css left 来设法让 CSS 执行这两种动画。

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

关于css - 放大溢出 : scroll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34196639/

相关文章:

javascript - 使用 CSS3 向 DIV 添加倾斜背景

html - 如何控制我的 Chart.JS 饼图图例的位置及其外观?

javascript - 如何更改 div css 属性 none 以阻止

javascript - 当 Javascript 仅为特殊视口(viewport)构建时,我如何实现它?

带有 :after selector 的 Javascript addClass

html - 如何使用动态生成的 HTML 代码进行视觉更改?

javascript - Bootstrap 轮播在第一张图片上向左滑动消失

CSS 动画 : Curve Arrows

css - 如何使此菜单代码响应? (一位专家)

javascript - Ajax 在没有用户交互的情况下以 1 秒的间隔显示文件