-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblob.tsx
74 lines (59 loc) · 1.63 KB
/
blob.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
64
65
66
67
68
69
70
71
72
73
74
import { useEffect, useState } from 'react'
import { motion } from 'framer-motion'
const Blob = ({ width, height, color }: any) => {
const getRandom = (min: number, max: number) => Math.random() * (max - min) + min
const getPosition = () => {
const PADDING = 10
const x = getRandom(PADDING, (width ?? 600) - PADDING)
const y = getRandom(PADDING, (height ?? 500) - PADDING)
return { x, y }
}
const updateBlob = () => {
setBlobData((prev: any) => {
const data = { initial: prev.animate, animate: {} }
const pos = getPosition()
const opacity = getRandom(.3, 1)
const scale = getRandom(5, 20)
data.animate = {
...pos,
width: `${scale}em`,
opacity,
}
return data
})
}
const initialize = () => {
const data = { animate: {}, initial: {} }
const initPos = getPosition()
const initOpacity = getRandom(.3, 1)
const initScale = getRandom(5, 20)
data.initial = {
...initPos,
width: `${initScale}em`,
initOpacity,
}
const pos = getPosition()
const opacity = getRandom(.5, 1)
const scale = getRandom(5, 20)
data.animate = {
...pos,
width: `${scale}em`,
opacity,
}
return data
}
const [blobData, setBlobData] = useState<any>({})
useEffect(() => {
setBlobData(initialize())
}, [])
return (
<motion.div
initial={blobData.initial}
animate={blobData.animate}
transition={{ duration: 20 }}
onAnimationComplete={() => updateBlob()}
className={`absolute aspect-square ${color ? color : 'bg-primary'} z-[0]`}
/>
)
}
export default Blob