如何实现SVG文字滚动触发单次动画(仿weaintplastic.com)
实现SVG文字描边滚动触发动画
第一步:调整SVG结构与基础样式
先修改你提供的SVG,给所有字母路径统一添加类名,同时切换为描边模式(路径动画需要依赖描边属性):
<?xml version="1.0" encoding="utf-8"?> <svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 315 45" xml:space="preserve"> <style type="text/css"> .letter-path { fill: none; stroke: #000; /* 可自定义描边颜色 */ stroke-width: 2; stroke-dasharray: 0; stroke-dashoffset: 0; } .st0{fill:none;} </style> <g id="text-group"> <!-- 给每个字母路径添加统一类名 --> <path class="letter-path" d="M78.55,26.83l-2,5.75h-2.57l6.53-18.3h2.99l6.56,18.3h-2.65l-2.05-5.75H78.55z M84.85,24.98l-1.88-5.27 c-0.43-1.19-0.71-2.28-1-3.34h-0.06c-0.29,1.09-0.6,2.2-0.97,3.31l-1.88,5.29H84.85z"/> <path class="letter-path" d="M92.61,32.58c0.06-0.9,0.11-2.23,0.11-3.39V13.31h2.48v8.25h0.06c0.88-1.47,2.48-2.42,4.71-2.42c3.42,0,5.85,2.71,5.82,6.7 c0,4.7-3.11,7.03-6.19,7.03c-2,0-3.59-0.73-4.62-2.47h-0.09l-0.11,2.17H92.61z M95.2,27.32c0,0.3,0.06,0.6,0.11,0.87 c0.48,1.66,1.94,2.8,3.76,2.8c2.62,0,4.19-2.04,4.19-5.05c0-2.63-1.43-4.89-4.11-4.89c-1.71,0-3.31,1.11-3.82,2.93 c-0.06,0.27-0.14,0.6-0.14,0.98V27.32z"/> <path class="letter-path" d="M121.44,25.9c0,4.86-3.54,6.98-6.87,6.98c-3.74,0-6.62-2.61-6.62-6.76c0-4.4,3.02-6.98,6.84-6.98 C118.75,19.15,121.44,21.89,121.44,25.9z M110.48,26.04c0,2.88,1.74,5.05,4.19,5.05c2.4,0,4.19-2.14,4.19-5.1 c0-2.23-1.17-5.05-4.14-5.05S110.48,23.54,110.48,26.04z"/> <path class="letter-path" d="M136.15,29c0,1.36,0.03,2.55,0.11,3.58h-2.22l-0.14-2.14h-0.06c-0.66,1.06-2.11,2.44-4.56,2.44 c-2.17,0-4.76-1.14-4.76-5.75v-7.68h2.51v7.27c0,2.5,0.8,4.18,3.08,4.18c1.68,0,2.85-1.11,3.31-2.17c0.14-0.35,0.23-0.79,0.23-1.22 v-8.06h2.51V29z"/> <path class="letter-path" d="M143.33,15.67v3.77h3.59v1.82h-3.59v7.09c0,1.63,0.48,2.55,1.88,2.55c0.66,0,1.14-0.08,1.45-0.16l0.11,1.79 c-0.48,0.19-1.25,0.33-2.22,0.33c-1.17,0-2.11-0.35-2.71-1c-0.71-0.71-0.97-1.87-0.97-3.42v-7.17h-2.14v-1.82h2.14v-3.15 L143.33,15.67z"/> <path class="letter-path" d="M172.08,24.55c-0.14-2.55-0.31-5.62-0.29-7.9h-0.09c-0.66,2.14-1.45,4.42-2.42,6.95l-3.39,8.88h-1.88l-3.11-8.71 c-0.91-2.58-1.68-4.94-2.22-7.11h-0.06c-0.06,2.28-0.2,5.35-0.37,8.09l-0.51,7.84h-2.37l1.34-18.3h3.17l3.28,8.85 c0.8,2.25,1.46,4.26,1.94,6.16h0.09c0.48-1.85,1.17-3.86,2.02-6.16l3.42-8.85h3.17l1.2,18.3h-2.42L172.08,24.55z"/> <path class="letter-path" d="M188.76,24h-7.47v6.6h8.33v1.98H178.8v-18.3h10.38v1.98h-7.9v5.78h7.47V24z"/> </g> <g> <rect x="54.72" y="8.99" class="st0" width="69.62" height="7.96"/> </g> </svg>
第二步:编写CSS动画
无需为每个字母单独编写代码,通过类选择器和:nth-child实现批量控制与依次动画效果:
/* 定义描边绘制动画 */ @keyframes drawLetter { to { stroke-dashoffset: 0; } } /* 动画激活类 */ .letter-path.animate { animation: drawLetter 1s ease forwards; } /* 给每个字母设置递增延迟,实现依次出现的节奏 */ .letter-path:nth-child(1) { animation-delay: 0s; } .letter-path:nth-child(2) { animation-delay: 0.1s; } .letter-path:nth-child(3) { animation-delay: 0.2s; } .letter-path:nth-child(4) { animation-delay: 0.3s; } .letter-path:nth-child(5) { animation-delay: 0.4s; } .letter-path:nth-child(6) { animation-delay: 0.5s; } .letter-path:nth-child(7) { animation-delay: 0.6s; }
第三步:JS实现滚动触发与路径初始化
核心逻辑:页面加载时计算每个路径的总长度,设置初始隐藏状态;监听滚动,当SVG进入视口时触发动画,且仅执行一次。
document.addEventListener('DOMContentLoaded', function() { const textGroup = document.getElementById('text-group'); const letterPaths = textGroup.querySelectorAll('.letter-path'); let animationTriggered = false; // 初始化每个路径的描边参数,让路径初始不可见 letterPaths.forEach(path => { const pathLength = path.getTotalLength(); path.style.strokeDasharray = pathLength; path.style.strokeDashoffset = pathLength; }); // 滚动监听函数 function checkScroll() { if (animationTriggered) return; const rect = textGroup.getBoundingClientRect(); // 判断元素是否进入视口 const isInViewport = rect.top <= window.innerHeight && rect.bottom >= 0; if (isInViewport) { letterPaths.forEach(path => path.classList.add('animate')); animationTriggered = true; // 触发后移除监听,避免重复执行 window.removeEventListener('scroll', checkScroll); } } // 绑定滚动监听 window.addEventListener('scroll', checkScroll); // 初始检查一次,防止元素一开始就在视口内 checkScroll(); });
关键说明
- 无需单独编写每个字母的代码:通过统一类名批量控制,JS遍历所有路径元素处理,减少冗余代码。
- 滚动触发逻辑:利用
getBoundingClientRect()判断元素位置,进入视口后添加动画类,通过变量确保动画仅执行一次。 - SVG模式切换:原SVG为填充模式,路径动画需要依赖描边属性,因此设置
fill:none并添加stroke相关样式。
内容的提问来源于stack exchange,提问作者Newbee033
相关产品推荐
相关产品推荐

