【问题标题】:react framer-motion "AnimatePresence" animation on exiting, trying to get it working..noob framer-motion user在退出时对 framer-motion “AnimatePresence”动画做出反应,试图让它工作..noob framer-motion 用户
【发布时间】:2021-12-30 17:52:33
【问题描述】:

我的所有动画都运行良好,但当我单击某个项目时除外。没有动画出来。卡片项目有动画,但没有动画。我正在尝试实现 AnimatePresence,不得不承认我已经从周日开始重写了这个,然后又回来了,并试图在它上面跟着一些 tuts,但我似乎无法掌握它。我有我的路线动画进出使用 AnimateSharedLayout。 下面是跨三个页面的代码,试图在列出的项目与选定的项目之间设置过渡动画。

const containerVariants = {
    initial: {
        opacity: 0,
        y: '100vw',
        scale: 2,
    },
    in: {
        opacity: 1,
        y: 0,
        scale: 1,
    },
    out: {
        opacity: 0,
        y: '-100vw',
        scale: 0,
    },
};
const containerTransitions = {
    type: 'tween',
    ease: 'anticipate',
    duration: 2,
};
const containerVariants1 = {
    initial: {
        opacity: 0,
        x: '100vw',
        scale: 0,
    },
    in: {
        opacity: 1,
        x: 0,
        scale: 1,
    },
    out: {
        opacity: 0,
        x: '-100vw',
        scale: 0,
    },
};
const containerTransitions1 = {
    type: 'tween',
    ease: 'anticipate',
    duration: 3,
};

const LGallery = () => {
    return (
        <>
            <AnimatePresence key={Items._id}>
                <motion.div
                    initial='initial'
                    animate='in'
                    key={Items._id}
                    exit='out'
                    variants={containerVariants}
                    transition={containerTransitions}
                    className='container'
                >
                    <h1>filler title</h1>

                    <Row
                        as={motion.div}
                        key={Items._id}
                        initial='initial'
                        animate='in'
                        exit='out'
                        variants={containerVariants1}
                        transition={containerTransitions1}
                        className='card-list '
                    >
                        {Items.map((Items) => (
                            <Col key={Items._id}>
                                <WorkItems Items={Items} />
                            </Col>
                        ))}
                    </Row>
                </motion.div>
            </AnimatePresence>
        </>
    );
};

export default LGallery;

项目列表页面

const containerVariants = {
    initial: {
        opacity: 0,
        x: '-50vw',
        y: '10vw',
        scale: 0,
    },
    in: {
        opacity: 1,
        x: 0,
        y: 0,
        scale: 1,
    },
    out: {
        opacity: 0,
        x: '10vw',
        y: '-50vw',
        scale: 0,
    },
};
const containerTransitions = {
    type: 'tween',
    ease: 'anticipate',
    duration: 4,
};
const containerVariants1 = {
    initial: {
        opacity: 0,
        y: '60vw',
        scale: 0,
    },
    in: {
        opacity: 1,
        y: 0,
        scale: 1,
    },
    out: {
        opacity: 0,
        y: '-60vw',
        scale: 0,
    },
};
const containerTransitions1 = {
    type: 'tween',
    ease: 'anticipate',
    duration: 5,
};
const containerVariants2 = {
    initial: {
        opacity: 0,
        y: '-60vw',
        scale: 0,
    },
    in: {
        opacity: 1,
        y: 0,
        scale: 1,
    },
    out: {
        opacity: 0,
        y: '60vw',
        scale: 0,
    },
};
const containerTransitions2 = {
    type: 'tween',
    ease: 'anticipate',
    duration: 5,
};

const WorkItems = ({ Items }) => {
    return (
        <>
            <AnimatePresence key={Items._id}>
                <Link to={`/work/${Items._id}`}>
                    <Card
                        as={motion.div}
                        initial='initial'
                        animate='in'
                        exit='out'
                        variants={containerVariants}
                        transition={containerTransitions}
                        className='card-content-container'
                    >
                        <Link to={`/work/${Items._id}`}>
                            <Card.Img
                                className='card-image-container'
                                src={Items.image}
                                // variant='top'
                            />
                        </Link>

                        <Card.Body
                            as={motion.div}
                            key={Items._id}
                            initial='initial'
                            animate='in'
                            exit='out'
                            variants={containerVariants1}
                            transition={containerTransitions1}
                            className='card-content'
                        >
                            <Card.Title
                                as={motion.div}
                                key={Items._id}
                                initial='initial'
                                animate='in'
                                exit='out'
                                variants={containerVariants2}
                                transition={containerTransitions2}
                            >
                                <strong>{Items.title}</strong>
                            </Card.Title>

                            <Card.Text>
                                <motion.div
                                    key={Items._id}
                                    initial='initial'
                                    animate='in'
                                    exit='out'
                                    variants={containerVariants2}
                                    transition={containerTransitions2}
                                    className='card-content'
                                >
                                    {Items.description}
                                </motion.div>
                            </Card.Text>
                        </Card.Body>
                    </Card>
                </Link>
            </AnimatePresence>
        </>
    );
};

export default WorkItems;

单个项目页面

const containerVariants = {
    initial: {
        opacity: 0,
        y: '-80vw',
        scale: 0,
    },
    in: {
        opacity: 1,
        y: 0,
        scale: 1,
    },
    out: {
        opacity: 0,
        y: '80vw',
        scale: 0,
    },
};
const containerTransitions = {
    type: 'tween',
    ease: 'anticipate',
    duration: 2,
};

const unItems = ({ match }) => {
    const item = Items.find((p) => p._id === match.params.id);
    return (
        <>
            <AnimatePresence>
                <motion.div
                    initial='initial'
                    animate='in'
                    exit='out'
                    variants={containerVariants}
                    transition={containerTransitions}
                    className='portItem'
                >
                    <Image
                        className='image-container'
                        src={item.image}
                        alt={item.title}
                    />
                    <motion.div
                        initial='initial'
                        animate='in'
                        exit='out'
                        variants={containerVariants}
                        transition={containerTransitions}
                        className='portItem'
                    >
                        <ListGroup variant='flush'>
                            <ListGroup.Item>
                                <h3>{item.title}</h3>
                            </ListGroup.Item>
                            <ListGroup.Item>
                                <h3>{item.blurb}</h3>
                            </ListGroup.Item>
                            <ListGroup.Item>
                                <h3>{item.description}</h3>
                            </ListGroup.Item>
                        </ListGroup>
                    </motion.div>

                    <motion.div
                        initial='initial'
                        animate='in'
                        exit='out'
                        variants={containerVariants}
                        transition={containerTransitions}
                        className='portItem'
                    >
                        <ListGroup variant='flush'>
                            <ListGroup.Item>
                                <h3>{item.gitLink}</h3>
                            </ListGroup.Item>
                            <ListGroup.Item>
                                <h3>{item.hostLink}</h3>
                                <h3>{item.phoneQR}</h3>
                            </ListGroup.Item>
                        </ListGroup>
                    </motion.div>

                    <motion.div
                        initial='initial'
                        animate='in'
                        exit='out'
                        variants={containerVariants}
                        transition={containerTransitions}
                        className='portItem'
                    >
                        <ListGroup variant='flush'>
                            <ListGroup.Item>
                                <h3>{item.bIcon}</h3>
                            </ListGroup.Item>
                        </ListGroup>
                        <Link to='/work'>
                            <NButton>Go Back</NButton>
                        </Link>
                    </motion.div>
                </motion.div>
            </AnimatePresence>
        </>
    );
};

export default unItems;

【问题讨论】:

  • 谢谢,我想,更多的是寻找编码煽动然后是语法更正..

标签: reactjs animation framer-motion


【解决方案1】:

AnimatePresence 标签需要包装将从 DOM 中删除的元素。您不能将标签 inside 放在条件渲染的组件中,看起来就像您在此处所拥有的那样。在这种情况下,AnimatePresence 标签会从包含该组件的页面中移除,并且它永远没有机会运行退出动画。

所以你很可能只需将标签移动到父组件中。

此外,请确保您尝试使用 AnimatePresence 制作动画的所有组件都具有唯一的 key 属性。您似乎在其中一些示例中遗漏了这一点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-08
    • 2023-02-13
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 2020-12-28
    • 2022-11-21
    • 1970-01-01
    相关资源
    最近更新 更多