Built Portfolio Page -4 (Scroll effect)

Steps:

  1. move project code to project component

useScroll Memo:

1
2
3
4
5
const ref = useRef<HTMLElement>(null);
const { scrollYProgress } = useScroll({
target: ref,
offset:["0 1", "1.33 1"]
});
  • 创建一个 ref,用于引用某个 DOM 元素(可能在JSX中通过 ref={ref} 绑定到一个元素上)。
  • 使用 useScroll 来监听这个被引用元素的滚动情况。
  • 设置滚动动画的触发范围:从元素开始进入视口底部(“0 1”)到元素完全离开视口底部 33% 的位置(“1.33 1”)。
  • 获取 scrollYProgress 值,这个值可能随着元素的滚动而变化,范围可能是 0 到 1。

Add project component

add src/components/Project.tsx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
"use client"

import React, { useRef } from 'react';
import Image from 'next/image';

import { projectsData } from '@/libs/data'
import { motion,useScroll, useTransform } from 'framer-motion';

type ProjectProps = (typeof projectsData)[number];

export default function Project({title,description,tags,imageUrl } :
ProjectProps) {
const ref = useRef<HTMLElement>(null);
const { scrollYProgress } = useScroll({
target: ref,
offset:["0 1", "1.33 1"]
});
const scaleProgress = useTransform(scrollYProgress, [0,1],[0.8,1]);
const opacityProgress = useTransform(scrollYProgress, [0,1],[0.6,1]);

return(
<motion.section
ref={ref}
style={{
scale: scaleProgress,
opacity: opacityProgress,
}}
className="group bg-gray-100 max-w-[42rem] border border-black/5 rounded-lg
overflow-hidden sm:pr-8 relative sm:h-[20rem] mb-3 sm:mb-8 last:mb-0 even:pl-8
hover:bg-gray-200 transition"
>
<div className='py-4 pb-7 px-5 sm:pl-10 sm:pr-2 sm:pt-10 sm:max-w-[50%]
flex flex-col h-full group-even:ml-[18rem]'>
<h3 className='text-2xl font-semibold'>{title}</h3>
<p className='mt-2 leading-relaxed text-gray-700'>{description}</p>
<ul className='flex flex-wrap mt-4 gap-2 sm:mt-auto'>
{tags.map((tag,index) => (
<li className='bg-black/[0.7] px-3 py-1 text-[0.7rem] upppercase
tracking-wider text-white rounded-full'
key={index}
>
{tag}
</li>
))}
</ul>
</div>
<Image
src={imageUrl} alt="Project I worked on" quality={95}
className='absolute top-8 -right-40 w-[28.25rem] rounded-t-lg shadow-2xl
transition
group-hover:scale-[1.05]
group-hover:-translate-x-3
group-hover:translate-y-3
group-hover:-rotate-2

group-even:group-hover:translate-x-3
group-even:group-hover:-translate-y-3
group-even:group-hover:rotate-2
group-even:right-[inital] group-even:-left-40'
/>
</motion.section>
)
}

Demo

Demo Page

请我喝杯咖啡吧~

支付宝
微信