如何让ScrollMagic驱动的SVG路径动画与滚动速度同步?
解决ScrollMagic线条动画与滚动不同步的问题
滚动一段时间后线条动画会滞后,希望绘制线条时进度与滚动操作完全同步,已尝试为Tween设置ease:none但未解决问题。
原代码
JavaScript
var controller = new ScrollMagic.Controller(); var $line = $("#line"); $line.attr("stroke-dashoffset", $line[0].getTotalLength()); $line.attr("stroke-dasharray", $line[0].getTotalLength()); var tween = TweenMax.to($line, 1, { strokeDashoffset: 0, ease: "none" }); var tlPath = new TimelineMax().add( tween ); var pathScene = new ScrollMagic.Scene({ triggerElement: "#trigger", duration: 2100, offset: 0, tweenChanges: true }) .setTween(tlPath) .addIndicators({ name: "path" }) .addTo(controller);
CSS
body { margin: 0; } .scrollContent { height: 3000px; margin: 300px; }
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/gsap/1.17.0/TweenMax.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/ScrollMagic.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.7/plugins/animation.gsap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.6/plugins/debug.addIndicators.js"></script> <script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/DrawSVGPlugin.min.js"></script> <div class="scrollContent"> <section class="demo"> <div id="trigger" class="spacer s0"></div> <div class="spacer s2"></div> <svg data-name="Ebene 1" xmlns="http://www.w3.org/2000/svg" width="50" height="2100" viewBox="0 0 50 2100"> <path id="line" d="M48.17,.5V2094c0,5.5-4.5,5.5-4.5,5.5" style="fill: #fff; stroke: #000; stroke-miterlimit: 10; stroke-width: 4px;"/> </svg> </section> </div>
解决方案
问题出在通过TweenMax驱动动画,即便设置了ease:none,Tween的更新机制和ScrollMagic的滚动触发节奏无法完全绑定,导致滞后。换成直接在滚动更新时计算进度的方式,就能实现完全同步:
修改后的JavaScript代码:
var controller = new ScrollMagic.Controller(); var $line = $("#line"); var totalLength = $line[0].getTotalLength(); // 初始化线条的dash属性 $line.attr("stroke-dashoffset", totalLength); $line.attr("stroke-dasharray", totalLength); var pathScene = new ScrollMagic.Scene({ triggerElement: "#trigger", duration: 2100, offset: 0, tweenChanges: true }) // 去掉setTween,改用onUpdate回调实时计算 .on("update", function (e) { // 获取当前场景的滚动进度(0=未开始,1=完成) var progress = e.progress; // 根据进度实时计算dashoffset值 var currentOffset = totalLength * (1 - progress); $line.attr("stroke-dashoffset", currentOffset); }) .addIndicators({ name: "path" }) .addTo(controller);
原理说明
- 每次滚动触发场景更新时,
onUpdate回调会立即执行,直接获取当前滚动的进度值 - 根据进度实时计算
stroke-dashoffset,完全跟随滚动节奏,没有中间的tween过渡延迟 - 不再依赖TweenMax的动画驱动,彻底避免了同步偏差
内容的提问来源于stack exchange,提问作者Maharkus
相关产品推荐
相关产品推荐

