要实现所需的动画行为,可以使用以下组合
useInView
和
useScroll
Framer Motion的挂钩。以下是修改代码的方法:
import { motion, useInView, useScroll, useTransform } from "framer-motion";
import { useRef } from "react";
import { SectionHeading } from "../UI/Headings";
import { Section } from "../UI/Section";
export default function About() {
const inViewRef = useRef();
const isInView = useInView(inViewRef, { margin: "-180px 0px", once: true });
const scrollRef = useRef(null);
const { scrollYProgress } = useScroll({ target: scrollRef });
const x = useTransform(scrollYProgress, [0, 1], ["0%", "120%"]);
return (
<Section ref={inViewRef} id="who-i-am" className="bg-black h-[150svh]">
<motion.div
className="bg-purple-500 sticky top-0"
initial={{ y: 300, visibility: "hidden" }}
animate={isInView ? { y: 50, visibility: "visible" } : {}}
transition={{ duration: 1.6, ease: "easeIn", type: "spring" }}
>
<motion.div ref={scrollRef} style={{ x }} className="h-[150svh]">
<SectionHeading>SECTION HEADING</SectionHeading>
<p>
Lorem ipsum dolor, sit amet consectetur adipisicing elit. Temporibus
aliquam veniam non quod veritatis sed ex ipsam doloribus. Ratione
est quae quo architecto. Labore, quisquam. Ipsam vitae libero veniam
eius, pariatur magni perferendis, molestiae numquam, iure dolorum
voluptatum nemo? Illum laudantium quae voluptatem reiciendis hic at
aut quam ea error.
</p>
<p>
Lorem ipsum dolor sit amet, consectetur adipisicing elit. Vitae
recusandae atque quibusdam ipsa ab fugit minus, veritatis earum
molestias repellat.
</p>
</motion.div>
</motion.div>
</Section>
);
}
以下是我的更改:
-
我移动了
motion.div
外面的紫色背景
动作.div
这有
scrollRef
这样,输入动画将独立于水平滚动动画而发生。
-
我用了
animate
紫色道具
动作.div
基于
isInView
价值。当元素在视图中时,它将设置动画
y: 50
和
visibility: "visible"
否则,它将保持其初始状态。
-
我移动了
h-[150svh]
类到内部
动作.div
这有
scrollRef
这确保了水平滚动动画发生在该部分的高度内。
有了这些更改,动画的行为应该如下:
-
当该部分进入视口时,紫色背景元素将从垂直方向移动
y: 300
到
y: 50
根据指定的转换。
-
当有人向下滚动页面时,紫色背景元素将从
0%
到
120%
通过调整其宽度,有效地将其移出视口到右侧。
-
该部分的高度设置为
150svh
,这应该防止紫色背景元素在到达其最终位置时超过该部分的末端。
这是我能想到的所有修改,如果它仍然不起作用,我无能为力