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

如何为SVG <animate>的begin属性绑定点击事件或条件触发动画?

解决SVG 绑定点击事件/条件触发的问题

方案一:直接绑定SVG animate到按钮点击事件(最简洁)

无需额外JS逻辑,直接利用SVG原生的begin属性绑定按钮点击事件,通过时间偏移保持动画时序:

<script>
</script>

<svg>
{#each Array(8) as _,i}
    <g transform="translate(150 150)">
        <line
            class="spark"
            x1={0}
            y1={20}
            x2={0}
            y2={50}
            transform="rotate({i*45})"
        >
        <animate 
            attributeName="y2" 
            from="0" 
            to="50" 
            begin="sparkBtn.click" 
            dur="0.2s" 
            fill="freeze"
        />
        <animate 
            attributeName="y1" 
            from="0" 
            to="50" 
            begin="sparkBtn.click+0.2s" 
            dur="0.2s" 
            fill="freeze"
        />
        <animate 
            attributeName="opacity" 
            from="1" 
            to="0" 
            begin="sparkBtn.click+0.4s" 
            dur="0.1s" 
            fill="freeze"
        />
        </line>
    </g>
{/each}
</svg>
<br>
<button id="sparkBtn">Click</button>

<style>
    svg {
        width:300px;
        height:300px;
        border:solid;
    }
    .spark {
        stroke:green;
        stroke-width:5;
        stroke-linecap:round;
    }
</style>

方案二:Svelte反应式+元素引用控制动画

通过收集所有<animate>元素的引用,利用Svelte反应式特性在条件变更时触发动画:

<script>
let sparkCond = false;
let animateElements = [];

function spark() {
    sparkCond = true;
}

$: if (sparkCond) {
    animateElements.forEach(anim => {
        // 重置并启动动画
        anim.endElement();
        anim.beginElement();
    });
    sparkCond = false;
}
</script>

<svg>
{#each Array(8) as _,i}
    <g transform="translate(150 150)">
        <line
            class="spark"
            x1={0}
            y1={20}
            x2={0}
            y2={50}
            transform="rotate({i*45})"
        >
        <animate 
            attributeName="y2" 
            from="0" 
            to="50" 
            begin="indefinite" 
            dur="0.2s" 
            fill="freeze"
            bind:this={el => animateElements.push(el)}
        />
        <animate 
            attributeName="y1" 
            from="0" 
            to="50" 
            begin="indefinite" 
            dur="0.2s" 
            fill="freeze"
            bind:this={el => animateElements.push(el)}
        />
        <animate 
            attributeName="opacity" 
            from="1" 
            to="0" 
            begin="indefinite" 
            dur="0.1s" 
            fill="freeze"
            bind:this={el => animateElements.push(el)}
        />
        </line>
    </g>
{/each}
</svg>
<br>
<button on:click={spark}>Click</button>

<style>
    svg {
        width:300px;
        height:300px;
        border:solid;
    }
    .spark {
        stroke:green;
        stroke-width:5;
        stroke-linecap:round;
    }
</style>

方案三:原生JavaScript控制动画

不依赖Svelte特性,直接通过原生JS获取元素并触发动画:

<script>
function spark() {
    const anims = document.querySelectorAll('svg animate');
    anims.forEach(anim => {
        anim.endElement();
        anim.beginElement();
    });
}
</script>

<svg>
{#each Array(8) as _,i}
    <g transform="translate(150 150)">
        <line
            class="spark"
            x1={0}
            y1={20}
            x2={0}
            y2={50}
            transform="rotate({i*45})"
        >
        <animate 
            attributeName="y2" 
            from="0" 
            to="50" 
            begin="indefinite" 
            dur="0.2s" 
            fill="freeze"
        />
        <animate 
            attributeName="y1" 
            from="0" 
            to="50" 
            begin="indefinite" 
            dur="0.2s" 
            fill="freeze"
        />
        <animate 
            attributeName="opacity" 
            from="1" 
            to="0" 
            begin="indefinite" 
            dur="0.1s" 
            fill="freeze"
        />
        </line>
    </g>
{/each}
</svg>
<br>
<button on:click={spark}>Click</button>

<style>
    svg {
        width:300px;
        height:300px;
        border:solid;
    }
    .spark {
        stroke:green;
        stroke-width:5;
        stroke-linecap:round;
    }
</style>

内容的提问来源于stack exchange,提问作者louislugas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 08:14:54