Skip to content

Commit

Permalink
feat: scroll animation
Browse files Browse the repository at this point in the history
  • Loading branch information
wkylin committed Nov 1, 2024
1 parent aa9c7be commit c459220
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 7 deletions.
25 changes: 25 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@
"echarts": "^5.5.1",
"echarts-for-react": "^3.0.2",
"fetch-intercept": "^2.4.0",
"framer-motion": "^11.11.11",
"helmet": "^8.0.0",
"html-to-image": "^1.11.11",
"html2canvas": "^1.4.1",
Expand Down
74 changes: 74 additions & 0 deletions src/components/stateless/AnimateOnScreen/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useState, useEffect, useRef } from 'react'

const useElementOnScreen = (ref, rootMargin = '0px') => {
const [isIntersecting, setIsIntersecting] = useState(true)
useEffect(() => {
const observer = new IntersectionObserver(
([entry]) => {
setIsIntersecting(entry.isIntersecting)
},
{ rootMargin }
)
if (ref.current) {
observer.observe(ref.current)
}
return () => {
if (ref.current) {
observer.unobserve(ref.current)
}
}
}, [])
return isIntersecting
}

const AnimateIn = ({ from, to, children }) => {
const ref = useRef(null)
const onScreen = useElementOnScreen(ref)
const defaultStyles = {
transition: '1000ms ease-in-out',
}
return (
<div
ref={ref}
style={
onScreen
? {
...defaultStyles,
...to,
}
: {
...defaultStyles,
...from,
}
}
>
{children}
</div>
)
}

const FadeIn = ({ children }) => (
<AnimateIn from={{ opacity: 0 }} to={{ opacity: 1 }}>
{children}
</AnimateIn>
)

const FadeUp = ({ children }) => (
<AnimateIn from={{ opacity: 0, translate: '0 2rem' }} to={{ opacity: 1, translate: 'none' }}>
{children}
</AnimateIn>
)

const ScaleIn = ({ children }) => (
<AnimateIn from={{ scale: '0' }} to={{ scale: '1' }}>
{children}
</AnimateIn>
)

const AnimateOnScreen = {
FadeIn,
FadeUp,
ScaleIn,
}

export default AnimateOnScreen
21 changes: 21 additions & 0 deletions src/components/stateless/ScrollAnimation/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import { motion } from 'framer-motion'

const ScrollAnimation = ({ children }) => {
return (
<motion.div
initial={{ opacity: 0, y: 50 }}
whileInView={{ opacity: 1, y: 0 }}
// viewport={{once:true}}
transition={{
ease: 'linear',
duration: 1,
y: { duration: 0.5 },
}}
>
{children}
</motion.div>
)
}

export default ScrollAnimation
33 changes: 27 additions & 6 deletions src/pages/home/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import LineBordered from '@stateless/LineBordered'
import GradientTracking from '@stateless/GradientTracking'
import ShiftingCard from '@stateless/ShiftingCard'
import BreatheText from '@stateless/BreatheText'
import ScrollAnimation from '@stateless/ScrollAnimation'
import AnimateOnScreen from '@stateless/AnimateOnScreen'

import { oneApiChat, prettyObject } from '@utils/aidFn'

Expand Down Expand Up @@ -162,12 +164,9 @@ const Home = () => {
<section>
I love coding in <AlternatingText alternateText={['javascript', 'typescript', 'rect', 'vue']} />.
</section>
<section>
<section style={{ marginBottom: 40 }}>
<AutoLink text="foo bar baz http://example.org bar https://github.com/wkylin/pro-react-admin" />
</section>
<section>
<LazyLoadImage src="https://picsum.photos/seed/picsum/300/160" alt="Strawberries" />
</section>
<section>
<AvatarCard avatar="https://picsum.photos/seed/picsum/300/160" text="Hi, I'm a developer." />
</section>
Expand All @@ -176,22 +175,44 @@ const Home = () => {
</section>
<StarRating value={2} />
<LineBordered text="A line bordered text." />
<section style={{ display: 'flex', alignItems: 'center', marginTop: 10 }}>
<section style={{ display: 'flex', alignItems: 'center', marginTop: 10, marginBottom: 40 }}>
<Atom /> <Merge /> <GitMerge /> <GitPullRequestArrow />
</section>
<section style={{ marginBottom: 40 }}>
<ScrollAnimation>
<LazyLoadImage src="https://picsum.photos/seed/picsum/300/160" alt="Strawberries" />
</ScrollAnimation>
</section>
<section>
<GradientTracking />
</section>

<section style={{ margin: 40 }}>
<BreatheText />
</section>

<section style={{ marginBottom: 40 }}>
<ShiftingCard />
</section>
<section>
<section style={{ marginBottom: 40 }}>
<PinInput onChange={(value, index, values) => setPinValues(values)} values={pinValues} />
</section>
<section style={{ marginBottom: 40 }}>
<AnimateOnScreen.FadeIn>
<AvatarCard avatar="https://picsum.photos/seed/picsum/300/160" text="Hi, I'm a developer." />
</AnimateOnScreen.FadeIn>
</section>
<section style={{ marginBottom: 40 }}>
<AnimateOnScreen.FadeUp>
<img src="https://picsum.photos/360/200.jpg" alt="" />
</AnimateOnScreen.FadeUp>
</section>
<section style={{ marginBottom: 40, width: 360, height: 200 }}>
<AnimateOnScreen.ScaleIn>
<img src="https://picsum.photos/360/200/?blur=2" alt="" />
</AnimateOnScreen.ScaleIn>
</section>

<section style={{ width: 600, margin: '30px 0' }}>
<Input defaultValue={apiKey} placeholder="api key" onChange={changeApiKey} style={{ marginBottom: 20 }} />
<Flex align="center">
Expand Down
2 changes: 1 addition & 1 deletion src/utils/publicFn/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ export const groupBy = (arr, groupFn) =>
export const areEqual = (arr1, arr2) => JSON.stringify(arr1.sort()) === JSON.stringify(arr2.sort())
export const areEqual2 = (arr1, arr2) => arr1.sort().join(',') === arr2.sort().join(',')

export const jsonToMap = (json = new Map(Object.entries(JSON.parse(json))))
export const jsonToMap = (json) => new Map(Object.entries(JSON.parse(json)))

// 蛇形转换为驼峰
export const snakeToCamelCase = (snake) => snake.toLowerCase().replace(/(_\w)/g, (word) => word.toUpperCase().substr(1))
Expand Down

0 comments on commit c459220

Please sign in to comment.