You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 22:45:32