我有一个具有缩放功能的 Web 应用程序,它可以缩放一些绝对定位的 DIV 并保持当前的滚动位置。缩放是动画的,问题是明显的滚动位置似乎在动画期间上下闪烁。换句话说,这些盒子看起来就像在播放动画时上下跳跃几个像素。如果可能的话,我希望它更流畅。
问题可以看这里:http://codepen.io/excelkobayashi/pen/EKVmrK .向下滚动到底部并使用 +/- 按钮。向下滚动越远,闪烁越严重。在实际应用中闪烁更明显,可能是因为 DOM 更复杂。
特别注意顶部边缘和文字:
下面是滚动的相关代码:
var oldZoom = zoom;
zoom += step;
render();
scrollPos = ((zoom / oldZoom) * scrollPos) || 0;
$("#container").scrollTop(scrollPos);
一些注意事项:
- 这整个 block 是从 requestAnimationFrame 循环中调用的,以动画缩放级别的变化
- step 是当前缩放和目标缩放之间差异的一小部分,以创建缓出效果。
- render 是在可滚动区域内调整和移动 DIV 的函数
var zoom = 1;
var targetZoom = 1;
var lastTick = null;
var scrollPos = 0;
function render() {
$(".main").height(1000 * zoom).each(function() {
var pos = 10 * zoom;
var height = 30 * zoom;
$(this).find(".stuff").each(function() {
$(this).css("top", pos + "px");
$(this).css("height", height + "px");
pos += 50 * zoom;
});
})
}
function animate() {
var diff = targetZoom - zoom;
if (!diff) {
lastTick = null;
return;
}
var tick = new Date().getTime();
if (lastTick) {
var minDiff = 0.01;
var timeDiff = tick - lastTick;
var step = diff * timeDiff / 100;
if (diff > 0 && step <= minDiff)
step = Math.min(minDiff, diff);
else if (diff < 0 && step >= -minDiff)
step = Math.max(-minDiff, diff);
var oldZoom = zoom;
zoom += step;
render();
scrollPos = ((zoom / oldZoom) * scrollPos) || 0;
$("#container").scrollTop(scrollPos);
}
lastTick = tick;
requestAnimationFrame(animate);
}
function startAnimation() {
if (lastTick)
return;
animate();
}
$("#zoomIn").click(function() {
targetZoom += 0.2;
startAnimation();
})
$("#zoomOut").click(function() {
targetZoom -= 0.2;
startAnimation();
})
$("#container").scroll(function() {
var scrollTop = $(this).scrollTop();
var diff = scrollPos - scrollTop;
if (isNaN(diff) || diff < 0 || diff >= 1)
scrollPos = scrollTop;
})
render();
div {
border: 1px solid black;
box-sizing: border-box;
}
#container {
margin: 10px;
width: 1200px;
height: 400px;
overflow: auto;
display: flex;
flex-direction: row;
}
.main {
width: 200px;
overflow: hidden;
position: relative;
/* Slow rendering (simulate complex content) */
box-shadow: 5px 5px 10px #888;
background-image: linear-gradient(to right, #fdd, #ddf);
}
.stuff {
position: absolute;
left: 10px;
right: 10px;
overflow: hidden;
/* Slow rendering (simulate complex content) */
box-shadow: 5px 5px 10px #888;
background-image: linear-gradient(white, #aaa);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="zoomOut">-</button>
<button id="zoomIn">+</button>
<div id="container">
<div class="main">
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
</div>
<div class="main">
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
</div>
<div class="main">
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
</div>
<div class="main">
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
</div>
<div class="main">
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
</div>
<div class="main">
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
<div class="stuff">Stuff</div>
</div>
</div>
关于我调查过的事情的一些笔记:
- 浏览器舍入 scrollTop 值。
- 这应该被考虑在内,因为我有一个单独的变量存储预期的位置,但这个舍入可能仍然是罪魁祸首。
- 在调用 scrollTop 之前添加一个圆形/地板似乎没有效果。
- 不能使用 CSS 转换,因为我不希望它影响内部 DIV 的内容;放大应该会显示更多内容。
- 调换调用 render 和 scrollTop 的顺序不会改变任何东西。
- 设置 scrollTop 会导致重绘,但据我所知调用 render 应该不会。
- Google map 等服务通过缩放上一张图像,然后隐藏它并在其后面显示下一张加载的图像来处理此问题。在这种情况下,这似乎不是一个选项,因为这不是基于图像的。
最佳答案
它闪烁是因为你用某个步骤设置了容器的scrollTop
值。如果您想逐渐更改 scrollTop
,您可能需要查看 jQuery 的 .animate()
函数 (http://api.jquery.com/animate/)。
关于javascript - 如何在不闪烁的情况下缩放+滚动JavaScript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35800615/