Задать вопрос
@sergejskolodkin

Как анимировать SVG в react?

Есть SVG файл:

<?xml version="1.0"?>
<svg width="320" height="240" xmlns="http://www.w3.org/2000/svg" xmlns:svg="http://www.w3.org/2000/svg">
 <!-- Created with SVG-edit - http://svg-edit.googlecode.com/ -->
 <g>
  <title>Layer 1</title>
  <rect stroke="#000000" fill="none" stroke-width="4" stroke-dasharray="null" stroke-linejoin="null" stroke-linecap="null" x="37.94335" y="79.25392" width="248.405285" height="94.552735" id="svg_5"/>

 </g>
 <g display="inline">
  <title>Layer 2</title>
 </g>
</svg>

Нужно, чтобы анимация, движение зелёной линии, начиналась не с начала обводки, а с середины. Вот моя попытка:

useEffect(() => {
        if (!svgRef.current) return;

        const svgElement = svgRef.current;
        const animatedElement = svgElement.querySelector('#svg_5');
       

        // Инициализация stroke dasharray
        const length = animatedElement.getTotalLength ? animatedElement.getTotalLength() : 1000;
        animatedElement.style.strokeDasharray = length;
        animatedElement.style.strokeDashoffset = length;
        animatedElement.style.strokeWidth = 2;
        animatedElement.style.stroke = "#00ff7f";

        if (!isAnimated) return;

        let startTime = null;
        const duration = 6000;

        const animate = (timestamp) => {
            if (!startTime) startTime = timestamp;
            const elapsed = timestamp - startTime;
            const progress = Math.min(elapsed / duration, 1);

            setIsProgress(progress);

            
            const totalLength = animatedElement.getTotalLength ? animatedElement.getTotalLength() : 1000;
            const startOffset = (startStoke / 100) * totalLength;
            // const endOffset = (endStoke / 100) * totalLength;
            const endOffset = 0.6 * totalLength;
            // const startOffset = 0.5 * totalLength;
            
    
            const currentOffset = endOffset + (startOffset-endOffset) * progress;
            
            
            animatedElement.style.strokeDashoffset = currentOffset;
            animatedElement.style.stroke = "#00ff7f";

            if (progress < 1 && isAnimated) {
                animationRef.current = requestAnimationFrame(animate);
            } else if (progress >= 1) {
                setIsAnimated(false);
            }
        };

        animationRef.current = requestAnimationFrame(animate);

        return () => {
            if (animationRef.current) {
                cancelAnimationFrame(animationRef.current);
            }
        };
    }, [isAnimated, startStoke, endStoke]);
  • Вопрос задан
  • 57 просмотров
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Яндекс Практикум
    Мидл фронтенд-разработчик
    5 месяцев
    Далее
  • Яндекс Практикум
    React-разработчик
    3 месяца
    Далее
  • Яндекс Практикум
    Фронтенд-разработчик
    10 месяцев
    Далее
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
ITK academy Нижний Новгород
от 80 000 до 120 000 ₽
ITK academy Воронеж
от 50 000 до 90 000 ₽