簡體   English   中英

如何在JavaScript中縮放+滾動而不閃爍

[英]How to zoom + scroll in JavaScript without flickering

我有一個具有縮放功能的Web應用程序,該功能可縮放某些絕對定位的DIV並保持當前滾動位置。 縮放是動畫的,問題在於在動畫過程中,明顯的滾動位置似乎在上下閃爍。 換句話說,在播放動畫時,框看起來像在上下跳躍幾個像素。 如果可能的話,我希望它更平滑。

可以在這里看到問題: http : //codepen.io/excelkobayashi/pen/EKVmrK 向下滾動至底部,然后使用+/-按鈕。 滾動越遠,閃爍越嚴重。 在實際應用中,閃爍更明顯,可能是因為DOM更復雜。

特別要注意頂部邊緣和文字:

http://i.imgur.com/fbkx1nJ.gifv

這是進行滾動的相關代碼:

    var oldZoom = zoom;
    zoom += step;

    render();

    scrollPos = ((zoom / oldZoom) * scrollPos) || 0;
    $("#container").scrollTop(scrollPos);

一些注意事項:

  • 從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 Maps之類的服務通過縮放上一張圖像,然后將其隱藏並在其后顯示下一張加載的圖像來處理此問題。 在這種情況下,這似乎不是一個選擇,因為它不是基於圖像的。

之所以閃爍,是因為您以特定步驟設置了容器的scrollTop值。 如果要逐漸更改scrollTop ,則可能需要查看jQuery的.animate()函數( http://api.jquery.com/animate/ )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM