使用JavaScript实现SVG高度方向渐变填充动画(替代CSS实现)
用JavaScript实现SVG垂直渐变填充动画
针对你提供的两个SVG,下面是改用JavaScript实现沿高度方向的渐变填充动画的具体方案:
第一个圆形SVG的改造
原SVG通过<animate>标签实现渐变偏移动画,我们改用JavaScript动态更新渐变stop的offset属性来复刻效果:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="200" height="200"> <linearGradient id="lg" x1="0.5" y1="1" x2="0.5" y2="0"> <stop offset="0%" stop-opacity="1" stop-color="royalblue"/> <stop id="stop1" offset="40%" stop-opacity="1" stop-color="royalblue"/> <stop id="stop2" offset="40%" stop-opacity="0" stop-color="royalblue"/> <stop offset="100%" stop-opacity="0" stop-color="royalblue"/> </linearGradient> <circle cx="50" cy="50" r="45" fill="url(#lg)" stroke="crimson" stroke-width="5"/> </svg> <script> const stop1 = document.getElementById('stop1'); const stop2 = document.getElementById('stop2'); const duration = 10000; // 动画总时长10秒 let startTime = null; function animateCircleGradient(timestamp) { if (!startTime) startTime = timestamp; const progress = ((timestamp - startTime) % duration) / duration; // 计算offset值:0→1→0的循环变化 let offset = progress < 0.5 ? progress * 2 : (1 - progress) * 2; // 更新两个stop的偏移量 stop1.setAttribute('offset', `${offset * 100}%`); stop2.setAttribute('offset', `${offset * 100}%`); requestAnimationFrame(animateCircleGradient); } requestAnimationFrame(animateCircleGradient); </script>
第二个矩形SVG的改造
先将原水平渐变改为垂直方向,再用JavaScript实现渐变整体沿高度滚动的动画:
<svg id="xcustom2" data-fill-gradient="true" fill-gradient-property="gt,0,2000" viewBox="0 0 124 135"> <g id="_shape28570" fill="url(#_GradLFF02X02X02X0002X02X02X0NA_)" fill-opacity="1" fill-rule="evenodd" stroke="rgb(0,0,0)" stroke-opacity="1" stroke-width="2" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10"> <rect x="12" y="5" width="100" height="125"/> </g> <defs> <linearGradient id="_GradLFF02X02X02X0002X02X02X0NA_" x1="0.5" y1="1" x2="0.5" y2="0"> <stop id="rectStop1" offset="0%" stop-color="rgb(255,255,0)" stop-opacity="1.0"/> <stop id="rectStop2" offset="50%" stop-color="rgb(0,176,80)" stop-opacity="1.0"/> <stop id="rectStop3" offset="100%" stop-color="rgb(255,255,0)" stop-opacity="1.0"/> </linearGradient> </defs> </svg> <script> const rectStop1 = document.getElementById('rectStop1'); const rectStop2 = document.getElementById('rectStop2'); const rectStop3 = document.getElementById('rectStop3'); const rectDuration = 8000; // 自定义动画时长8秒 let rectStartTime = null; function animateRectGradient(timestamp) { if (!rectStartTime) rectStartTime = timestamp; const progress = ((timestamp - rectStartTime) % rectDuration) / rectDuration; // 计算渐变整体偏移量:0→1→0循环 const offsetShift = progress < 0.5 ? progress : 1 - progress; // 同步偏移所有渐变stop的位置,实现垂直滚动效果 rectStop1.setAttribute('offset', `${offsetShift * 100}%`); rectStop2.setAttribute('offset', `${50 + offsetShift * 50}%`); rectStop3.setAttribute('offset', `${100 + offsetShift * 50}%`); requestAnimationFrame(animateRectGradient); } requestAnimationFrame(animateRectGradient); </script>
核心说明
- 用
requestAnimationFrame实现浏览器原生流畅动画循环,替代SVG原生<animate>标签 - 圆形动画通过同步更新两个stop的offset,保留原有的"蓝色填充块上下移动"效果
- 矩形动画先调整渐变方向为垂直,再通过偏移所有stop的offset,实现渐变色彩沿高度滚动的效果
- 修改
duration参数可直接调整动画速度
内容的提问来源于stack exchange,提问作者user17862529
相关产品推荐
相关产品推荐

