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

如何在SVG中同步重启多动画并保留起始时间(React嵌入场景)

Alright, let's break down how to fix your SVG animation sync issue and get this embedded into a React component smoothly.

1. Syncing Animation Restarts While Keeping Staggered Starts

Your original setup uses fixed start times (0s, 3s, 6s) which makes it hard to restart all animations in sync. The solution is to tie all animations to a shared trigger event that repeats every 9 seconds (the total duration of your full sequence). Here's how to adjust your SVG:

First, we'll add a hidden "trigger" animation that runs on a 9-second loop. Then, each line's animation will start relative to this trigger's start time instead of fixed timestamps.

Here's the revised SVG code:

<svg viewBox="0 0 74 2" height="2" width="74">
  <!-- Static background lines -->
  <line x1="0" y1="0" x2="20" y2="0" style="stroke:black;stroke-width:3" />
  <line x1="27" y1="0" x2="47" y2="0" style="stroke:black;stroke-width:3" />
  <line x1="54" y1="0" x2="74" y2="0" style="stroke:black;stroke-width:3" />

  <!-- Animated red fill lines -->
  <line x1="0" y1="0" x2="0" y2="0" style="stroke:red;stroke-width:4">
    <animate 
      id="first" 
      dur="3s" 
      attributeName="x2" 
      from="0" 
      to="20" 
      begin="restartTrigger.begin+0s" 
      fill="freeze" 
    />
  </line>
  <line x1="27" y1="0" x2="27" y2="0" style="stroke:red;stroke-width:4">
    <animate 
      id="second" 
      dur="3s" 
      attributeName="x2" 
      from="27" 
      to="47" 
      begin="restartTrigger.begin+3s" 
      fill="freeze" 
    />
  </line>
  <line x1="54" y1="0" x2="54" y2="0" style="stroke:red;stroke-width:4">
    <animate 
      id="third" 
      dur="3s" 
      attributeName="x2" 
      from="54" 
      to="74" 
      begin="restartTrigger.begin+6s" 
      fill="freeze" 
    />
  </line>

  <!-- Hidden loop trigger to sync restarts every 9s -->
  <animate 
    id="restartTrigger" 
    attributeName="visibility" 
    from="visible" 
    to="visible" 
    dur="9s" 
    repeatCount="indefinite" 
  />
</svg>

How this works:

  • The restartTrigger is a hidden animation that runs on a 9-second loop (matching your total sequence length).
  • Each line's animation uses restartTrigger.begin+[delay] as its start time. This means every time the trigger restarts, the first line animates immediately, the second starts 3 seconds later, and the third starts 6 seconds later—keeping your original timing.
  • After each 9-second cycle, the trigger restarts, and all animations reset and run through their sequence again in sync.
2. Embedding the SVG in a React Component

There are two straightforward ways to do this, depending on whether you need programmatic control over the animation.

Option 1: Inline SVG Component

Just drop the revised SVG into a React component, adjusting the style attributes to fit React's JSX syntax (using object-style style props instead of inline strings):

import React from 'react';

const StaggeredLoadingLines = () => {
  return (
    <svg viewBox="0 0 74 2" height="2" width="74">
      {/* Static background lines */}
      <line 
        x1="0" y1="0" x2="20" y2="0" 
        style={{ stroke: 'black', strokeWidth: 3 }} 
      />
      <line 
        x1="27" y1="0" x2="47" y2="0" 
        style={{ stroke: 'black', strokeWidth: 3 }} 
      />
      <line 
        x1="54" y1="0" x2="74" y2="0" 
        style={{ stroke: 'black', strokeWidth: 3 }} 
      />

      {/* Animated red lines */}
      <line 
        x1="0" y1="0" x2="0" y2="0" 
        style={{ stroke: 'red', strokeWidth: 4 }}
      >
        <animate 
          id="first" 
          dur="3s" 
          attributeName="x2" 
          from="0" 
          to="20" 
          begin="restartTrigger.begin+0s" 
          fill="freeze" 
        />
      </line>
      <line 
        x1="27" y1="0" x2="27" y2="0" 
        style={{ stroke: 'red', strokeWidth: 4 }}
      >
        <animate 
          id="second" 
          dur="3s" 
          attributeName="x2" 
          from="27" 
          to="47" 
          begin="restartTrigger.begin+3s" 
          fill="freeze" 
        />
      </line>
      <line 
        x1="54" y1="0" x2="54" y2="0" 
        style={{ stroke: 'red', strokeWidth: 4 }}
      >
        <animate 
          id="third" 
          dur="3s" 
          attributeName="x2" 
          from="54" 
          to="74" 
          begin="restartTrigger.begin+6s" 
          fill="freeze" 
        />
      </line>

      {/* Restart trigger */}
      <animate 
        id="restartTrigger" 
        attributeName="visibility" 
        from="visible" 
        to="visible" 
        dur="9s" 
        repeatCount="indefinite" 
      />
    </svg>
  );
};

export default StaggeredLoadingLines;

Option 2: Programmatic Restart Control (e.g., Button Click)

If you want to manually trigger a restart (like with a button), use React's useRef to access the trigger animation and call beginElement() on it:

import React, { useRef } from 'react';

const StaggeredLoadingLines = () => {
  const restartTriggerRef = useRef(null);

  const handleManualRestart = () => {
    // Trigger the animation sequence to restart immediately
    restartTriggerRef.current?.beginElement();
  };

  return (
    <div>
      <svg viewBox="0 0 74 2" height="2" width="74">
        {/* Same lines and animations as above */}
        <animate 
          ref={restartTriggerRef}
          id="restartTrigger" 
          attributeName="visibility" 
          from="visible" 
          to="visible" 
          dur="9s" 
          repeatCount="indefinite" 
        />
      </svg>
      <button onClick={handleManualRestart}>Restart Loading Animation</button>
    </div>
  );
};

export default StaggeredLoadingLines;

This lets you restart the entire sequence on demand, while still keeping the staggered start times for each line.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:16:24