/
index.tsx
126 lines (122 loc) · 3.85 KB
/
index.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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
'use client'
import useNextjsNavigate from 'src/app/hooks/useNextjsNavigate'
import Logo from 'src/components/Logo'
import stars from './assets/Stars-full.webp'
import { Texture, TextStyle } from 'pixi.js'
import { Spring } from 'react-spring'
import { Sprite } from '@pixi/react-animated'
import logo from 'src/components/Logo/etherion-logo.png'
import { OPTIONS } from 'src/components/PixiStage'
import { useCallback, useContext, useMemo, useState } from 'react'
import {
ParallaxCameraContext,
ParallaxCameraProvider,
ParallaxLayer,
useParallaxCameraRef,
} from 'pixi-react-parallax'
import { Text } from '@pixi/react'
import Button from '../Experiment2/Button'
import Overlay from '../Experiment2/Overlay'
import DebugIndicator from 'src/components/DebugIndicator'
const set = (): AnimatedLogoProps => ({
x: Math.random() * OPTIONS.width,
y: Math.random() * OPTIONS.height,
rotation: Math.random() * 10,
// scale: Math.max(1, Math.random() * 4),
})
const getRandomPosition = () => {
return {
x: Math.random() * OPTIONS.width,
y: Math.random() * OPTIONS.height,
}
}
export default function Experiment1() {
const navigate = useNextjsNavigate()
const [transform, setTransform] = useState<AnimatedLogoProps>(set)
const click = useCallback(() => {
setTransform(set)
}, [])
const logo1 = useMemo(getRandomPosition, [])
const logo2 = useMemo(getRandomPosition, [])
const logo3 = useMemo(getRandomPosition, [])
const logo4 = useMemo(getRandomPosition, [])
return (
<>
<ParallaxCameraProvider>
<ParallaxLayer zIndex={-18000}>
<Sprite texture={Texture.from(stars.src)} x={0} y={0} anchor={0.5} scale={65} />
</ParallaxLayer>
<ParallaxLayer zIndex={-850}>
{/* Very far away from the camera */}
<Logo {...logo1} />
</ParallaxLayer>
<ParallaxLayer zIndex={-400}>
{/* A bit closer */}
<Logo {...logo2} />
</ParallaxLayer>
<ParallaxLayer zIndex={-200}>
{/* Closer still */}
<Logo {...logo3} />
</ParallaxLayer>
<ParallaxLayer zIndex={0}>
{/* Normal distance. No auto-scaling applied. */}
<AnimatedLogo {...transform} />
</ParallaxLayer>
<ParallaxLayer zIndex={100}>
{/* Don't exceed the focal length (default 300) or it'll pass behind the camera. Technically, it gets mirrored, and looks weird. */}
{/* Very close! */}
<Logo {...logo4} />
</ParallaxLayer>
<DebugIndicator />
</ParallaxCameraProvider>
<Text
text="pixi-react-parallax"
x={OPTIONS.width - 700}
y={50}
scale={2}
style={new TextStyle({ fill: '0xffffff', fontSize: '38px' })}
/>
<Text
text={`Click/tap anywhere to move the camera target.\nClick/tap on the camera target to also cause the camera to shake!`}
x={100}
y={200}
scale={2}
style={new TextStyle({ fill: '0xcccccc', fontSize: '22px' })}
/>
<Overlay onPress={click} />
<Button text="≡ Menu" x={100} y={50} width={300} height={100} onPress={navigate('/')} />
</>
)
}
interface AnimatedLogoProps {
x: number
y: number
rotation: number
// scale: number
}
function AnimatedLogo(props: AnimatedLogoProps) {
const [, setCameraTargetRef] = useParallaxCameraRef()
const camera = useContext(ParallaxCameraContext)
const click = useCallback(() => {
camera?.shake(40, 0.2)
}, [camera])
return (
<Spring
to={props}
config={{ mass: 10, tension: 1000, friction: 100 /*, duration: 4000 */ }}
loop
>
{(props) => (
<Sprite
anchor={0.5}
texture={Texture.from(logo.src)}
{...props}
onpointerup={click}
cursor="pointer"
eventMode="dynamic"
ref={setCameraTargetRef}
/>
)}
</Spring>
)
}