Как использовать framer-motion с material-ui? (reactjs) (@material-ui/core) (движение кадра)

Я просто хочу знать, есть ли способ использовать framer-motion с Material-Ui. Я пытался, но я не понимаю.

🤔 А знаете ли вы, что...
React - это библиотека JavaScript, разработанная компанией Facebook.


12
12 243
5

Ответы:

Ваш вопрос меня заинтересовал. Я никогда не пробовал фреймер-движение, но недавно планировал научиться этому.

Так что я попробовал, создал песочницу, добавил в нее Material UI и пакеты кадров.

Только что создал маленькую кнопку в середине страницы, используя Material UI. И завернули кнопку тегом <motion.div>, вот так:

import React from "react";
import { motion } from "framer-motion";
import Button from "@material-ui/core/Button";

function AnimatableDiv() {
  return (
    <motion.div
      className = "animatable"
      whileHover = {{
        scale: 1.2,
        transition: { duration: 0.3 }
      }}
      whileTap = {{ scale: 0.9 }}
    >
      <Button size = "large" className = "animatable">
        Button
      </Button>
    </motion.div>
  );
}

export default AnimatableDiv;

И это сработало!

Вы можете подумать, что если я использую motion. непосредственно в компоненте <Button>, вот так:

<motion.Button size = "large" className = "animatable">
  Button
</motion.Button>

Что ж, я думал об этом, и я также применил его, и все стили, которые Material UI применил к этой кнопке, были потеряны! Так что не следуйте этому подходу! повторяю не надо!

Вот по ссылке можно глянуть: https://codesandbox.io/s/brave-sutherland-5bki9


Я тоже был в такой же ситуации, поэтому после небольшого исследования, проб и ошибок я написал небольшую статью об этом, надеюсь, вам, ребята, это поможет, и если какие-либо предложения не стесняйтесь уточнять в разделе комментариев.

https://aishmn.medium.com/how-to-use-material-ui-and-framer-motion-together-6026fed96a4c


Решено

Material-UI имеет component опцию поддержки для такого рода требований и должен работать лучше и элегантнее, чем подход с оберткой. Затем вы можете передать любые реквизиты, предоставленные пакетом framer-motion, вашему компоненту Material-UI, если они не конфликтуют (я не уверен, что они есть).

 <Button
  color = "inherit"
  variant='contained'
  size = "large"
  component = {motion.div}
  whileHover = {{
    scale: 1.2,
    transition: { duration: 0.3 }
  }}
  whileTap = {{ scale: 0.9 }}
>
  Button
</Button>

У меня был тот же вопрос, поэтому я немного покопался в документе движения. и я нашел это: Любой компонент можно превратить в компонент движения, обернув его функцией motion(). Итак, я сделал это:

    import { TextField } from "@mui/material";
    import { motion } from "framer-motion";

    export default function YourComponent() {
    const TextFieldMotion = motion(TextField);
    return (
            <TextFieldMotion 
            animate = {{ x: [0,20] }} 
            transition = {{ ease: "easeInOut", duration: 3 }} 
            variant = "filled" 
            label = "first name" 
            />
    )
     };

для получения дополнительной информации: https://www.framer.com/docs/component/


Стратегия принятого ответа - самый простой способ реализовать это, но другая стратегия заключается в использовании переноса кадра-движения.

Это моя реализация с Typescript для тех, кто может искать эту проблему.

Box.tsx

import React from "react";
import { motion } from "framer-motion";

import MuiBox, { BoxProps } from "@mui/material/Box";

const BoxComponent = React.forwardRef((props: BoxProps, ref) => (
  <MuiBox {...props} ref = {ref} />
));

const Box = motion(BoxComponent);

export default Box;

Затем используйте его в своем компоненте

import Box from "./Box";

// The motion-wrapped Mui Box now also accepts framer-motion's props
<Box
  initial = {{ opacity: 0 }}
  animate = {{ x: 100, rotate: [null, 10, 20], opacity: 1 }}
  whileHover = {{ scale: [null, 1.5, 1.4] }}
  width = {100}
  height = {100}
  border = "1px solid red"
/>