簡體   English   中英

framer.motion animation 是即時的,而不是動畫

[英]framer.motion animation is instant instead of animating

我有幾個想要動畫的盒子,

這是一個簡單的應用程序示例(這里也是一個代碼框

每個“盒子”都應該淡入和淡出,但是,在這個例子中,animation 發生的時間很短。

const Box = styled.div`
  width: 100px;
  height: 100px;
  background: green;
`;

const Test = ({ isActive }) => {
  return (
    <motion.div
      animate={isActive ? { opacity: 1 } : { opacity: 0 }}
      transition={{ duration: 3 }}
    >
      <Box>hello world</Box>
    </motion.div>
  );
};

export default function App() {
  const [currentIndex, setCurrentIndex] = useState(0);

  const boxes = [
    {
      component: ({ isActive }) => <Test isActive={isActive} />
    },
    {
      component: ({ isActive }) => <Test isActive={isActive} />
    }
  ];

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>Start editing to see some magic happen!</h2>
      <div onClick={() => setCurrentIndex(currentIndex === 0 ? 1 : 0)}>
        {boxes.map((box, index) => {
          const isActive = index === currentIndex;
          return <box.component isActive={isActive} />;
        })}
      </div>
    </div>
  );

我以前從未使用過 framer.motion,但是查看他們的文檔,我認為您可以使用變體來實現您所需要的。 https://www.framer.com/api/motion/examples/

我稍微重構了您的代碼,以使其正常工作:

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

const Box = styled.div`
  width: 100px;
  height: 100px;
  background: green;
`;

const variants = {
  open: { opacity: 1 },
  closed: { opacity: 0 }
};

const Test = ({ index, currentIndex }) => {
  return (
    <motion.div
      animate={index === currentIndex ? "open" : "closed"}
      variants={variants}
      transition={{ duration: 3 }}
    >
      <Box>hello world</Box>
    </motion.div>
  );
};

export default function App() {
  const [currentIndex, setCurrentIndex] = useState(0);
  const boxes = ["a", "b"];

  return (
    <div className="App">
      <h1>Hello CodeSandbox</h1>
      <h2>{currentIndex}</h2>
      <div onClick={() => setCurrentIndex(currentIndex === 0 ? 1 : 0)}>
        {boxes.map((box, i) => {
          return <Test index={i} currentIndex={currentIndex} />;
        })}
      </div>
    </div>
  );
}

currentIndex 作為 props 傳遞給子 Test 組件,它們檢查自己的索引是否與 currentIndex 匹配並相應地更新其動畫。

在此處編輯代碼框: https://codesandbox.io/s/suspicious-austin-tymvx

在成幀器運動中,您具有useCycle屬性。 這是一個例子

示例中的代碼:

import * as React from "react";
import { render } from "react-dom";
import { Frame, useCycle } from "framer";
import "./styles.css";

export function MyComponent() {
  const [animate, cycle] = useCycle(
    { scale: 1.5, rotate: 0, opacity: 1 },
    { scale: 1.0, rotate: 90, opacity: 0 }
  );
  return (
    <Frame
      animate={animate}
      onTap={() => cycle()}
      size={150}
      radius={30}
      background={"#fff"}
    />
  );
}

const rootElement = document.getElementById("root");
render(<MyComponent />, rootElement);

和一些簡單的 css:

body {
  margin: 0;
  padding: 0;
}

#root {
  font-family: sans-serif;
  text-align: center;
  width: 100vw;
  height: 100vh;
  display: flex;
  place-content: center;
  place-items: center;
  background: rgba(0, 85, 255, 1);
  margin: 0;
  padding: 0;
  perspective: 1000px;
}

我不建議你使用這種類型的構造: animate={index === currentIndex? "open": "closed"} animate={index === currentIndex? "open": "closed"} ,因為您可能有一些滯后/破壞 animation。 始終嘗試搜索 MotionAPI 庫的示例/元素。 您將擁有更少的代碼行,並且大部分是“干凈”的代碼,沒有無用的變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM