Я просто хочу знать, есть ли способ использовать framer-motion с Material-Ui. Я пытался, но я не понимаю.
🤔 А знаете ли вы, что...
React - это библиотека JavaScript, разработанная компанией Facebook.
Ваш вопрос меня заинтересовал. Я никогда не пробовал фреймер-движение, но недавно планировал научиться этому.
Так что я попробовал, создал песочницу, добавил в нее 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"
/>