如何为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
相关产品推荐
相关产品推荐

