【问题标题】:Animating svg text using framer motion in React在 React 中使用成帧器运动为 svg 文本设置动画
【发布时间】:2021-06-17 23:28:00
【问题描述】:

我想使用 Framer Motion 在 React 中为 svg 文本的字母轮廓设置动画,使线条从某个点开始,然后在一段时间内逐渐完成。我有以下示例代码

import { useState, useRef, useEffect } from "react";
import { motion } from "framer-motion";
import "./styles.css";

export default function App() {
  const [letterLength, setLetterLength] = useState(0);
  const letterRef = useRef();

  useEffect(() => {
    setLetterLength(letterRef.current.getTotalLength());
  }, []);

  return (
    <svg
      id="logo"
      width="998"
      height="108"
      viewBox="0 0 998 108"
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
    >
      <mask
        id="path-1-outside-1"
        maskUnits="userSpaceOnUse"
        x="0.867188"
        y="0.21875"
        width="998"
        height="108"
        fill="black"
      >
        <rect fill="white" x="0.867188" y="0.21875" width="998" height="108" />
        <path d="M15.3672 105H1.86719V2.625H15.3672V105Z" />
      </mask>
      <motion.path
        initial={{
          strokeDasharray: letterLength,
          strokeDashoffset: letterLength
        }}
        animate={{
          strokeDasharray: letterLength,
          strokeDashoffset: 0
        }}
        transition={{ duration: 2 }}
        d="M15.3672 105H1.86719V2.625H15.3672V105Z"
        stroke="#EAE3DC"
        strokeWidth="2"
        mask="url(#path-1-outside-1)"
        ref={letterRef}
      />
    </svg>
  );
}

然而,上面的代码表现得很奇怪。在我不想要的预期结果之前,这条线似乎被动画了多次。使用 vanilla JS 和 CSS 为字母设置动画时,我没有这个问题。我认为这个问题与状态变量有关,但我不确定它到底是什么。

这是codesandbox上的代码。

【问题讨论】:

    标签: reactjs svg framer-motion


    【解决方案1】:

    奇怪之处在于被动画的破折号数组的大小。我不认为这是您的意图,但 letterLength 被初始化为 0,然后在第二次渲染时更改为 230。

    我只是通过将 letterLength 设置为 const 值发现了这一点。

    我建议不要在这里乱用参考,而只使用百分比

          <motion.path
            initial={{
              strokeDasharray: "100%",
              strokeDashoffset: "100%"
            }}
            animate={{
              strokeDashoffset: "0%"
            }}
            transition={{ duration: 2 }}
            d="M15.3672 105H1.86719V2.625H15.3672V105Z"
            stroke="#EAE3DC"
            strokeWidth="2"
            mask="url(#path-1-outside-1)"
          />
    

    像这样:https://codesandbox.io/s/framer-motion-animate-stroke-with-dasharrayoffset-ezyuj?file=/src/App.js

    注意:我还没有找到一种在动画中使用 ref 的好方法,而不仅仅是在 ref 初始化期间隐藏具有不透明度的元素。如果您发现任何关于该主题的内容,请告诉我 ?

    **当天晚些时候编辑:**

    您也可以将 pathLength 设置为 100,以便提前知道长度。

            <motion.path
              // this line is the important part
              pathLength={100}
              initial={{
                strokeDasharray: 100,
                strokeDashoffset: 100
              }}
              animate={{
                strokeDashoffset: 0
              }}
              transition={{ duration: 2 }}
              d="M15.3672 105H1.86719V2.625H15.3672V105Z"
              stroke="#aceca1"
              strokeWidth="2"
              mask="url(#path-1-outside-1)"
            />
    

    感谢@kirdes https://discordapp.com/channels/341919693348536320/716908973713784904/855851823578218507

    【讨论】:

    • 还有一个问题:如何在绘制轮廓后为同一路径元素的填充颜色设置动画?这涉及同一元素上的两个不同动画!如何在成帧器运动中做到这一点?
    • 你想在上面做什么样的动画?如果您正在寻找的只是淡入,您可以在 animate 道具内为 fill 设置动画
    • 在上面的代码中,我为字母的轮廓设置了动画。 之后这是动画,我想自己填充字母,这意味着我需要延迟fill动画,以便首先完成轮廓动画。我假设这需要单独的动画配置。这样的事情是使用react-spring 完成的,但我想在framer-motion dev.to/tomdohnal/react-svg-animation-with-react-spring-3-3c91
    猜你喜欢
    • 2020-01-29
    • 1970-01-01
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-19
    • 2021-05-06
    相关资源
    最近更新 更多