如何设置滚动触发的SVG线条绘制动画从指定section区块开始启动
SVG线条滚动动画指定区块触发实现方案
你的原有代码是基于整页滚动比例计算线条绘制进度,所以会从页面顶部就开始动画。只要把进度计算的基准区间改成目标触发区块的可见范围,就能实现区块进入视口后才开始绘制、区块滚动完成时线条刚好画完的效果,不需要额外引入第三方库。
具体修改步骤
- 第一步:给你想要触发动画的目标区块加唯一id,比如
id="anim-trigger-area",方便JS获取位置信息 - 第二步:调整原有JS的滚动计算逻辑,新增区块位置判断、动画区间阈值计算、边界状态处理三个部分
- 可选优化:给滚动事件加节流,避免高频触发导致页面掉帧
修改后完整可运行代码
$(document).ready(function() { const myline = document.getElementById("myline"); const triggerArea = document.getElementById("anim-trigger-area"); // 初始化线条状态 const length = myline.getTotalLength(); myline.style.strokeDasharray = length; myline.style.strokeDashoffset = length; // 节流函数,优化滚动性能,60帧对应16ms触发间隔 function throttle(func, delay = 16) { let timer = null; return function(...args) { if (!timer) { timer = setTimeout(() => { func.apply(this, args); timer = null; }, delay); } } } function updateLineDraw() { const scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop; const viewportHeight = window.innerHeight; const areaRect = triggerArea.getBoundingClientRect(); const areaTopToDoc = areaRect.top + scrollTop; const areaHeight = areaRect.height; // 自定义动画触发/结束的滚动阈值,可根据需求自行调整 const animStart = areaTopToDoc - viewportHeight; // 区块刚进入视口底部时开始动画 const animEnd = areaTopToDoc + areaHeight; // 区块完全离开视口顶部时结束动画 let drawPercent = 0; if (scrollTop < animStart) { // 未到触发位置:保持线条完全隐藏 drawPercent = 0; } else if (scrollTop > animEnd) { // 超过动画区间:保持线条完全绘制完成 drawPercent = 1; } else { // 区间内:按当前滚动占比计算绘制进度 drawPercent = (scrollTop - animStart) / (animEnd - animStart); } const drawLength = length * drawPercent; myline.style.strokeDashoffset = length - drawLength; const endPoint = myline.getPointAtLength(drawLength); // 后续如果需要用endPoint做跟随点之类的逻辑,直接在这里写即可 } window.addEventListener("scroll", throttle(updateLineDraw)); // 页面初始化时先执行一次,避免刷新页面停在中间位置时线条状态不对 updateLineDraw(); });
自定义调整说明
- 如果想调整动画触发时机,直接修改
animStart和animEnd的计算值即可:比如想等区块滚动到视口中间才开始画,就把animStart改成areaTopToDoc - viewportHeight / 2 - 如果想让线条绘制速度和区块滚动速度不同步,可以给
drawPercent乘一个系数,比如drawPercent * 1.2就是绘制速度加快20% - 如果SVG是外部引入或者动态加载的,记得等SVG加载完成后再获取
myline元素计算总长度,否则会拿不到长度值导致动画失效
内容的提问来源于stack exchange,提问作者integraweb21
相关产品推荐
相关产品推荐

