Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 7fdf9b1

Browse files
author
takuma-hmng8
committed
v1.1.35
1 parent 15a01fe commit 7fdf9b1

40 files changed

+1838
-1545
lines changed

‎app/stickers/Background.tsx‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
"use client";
2+
3+
import * as THREE from "three";
4+
import { memo } from "react";
5+
import { Environment } from "@react-three/drei";
6+
7+
export const Background = memo(
8+
({
9+
stickerMap,
10+
scene,
11+
}: {
12+
stickerMap: THREE.Texture;
13+
scene: THREE.Scene;
14+
}) => {
15+
return (
16+
<>
17+
<Environment
18+
frames={1}
19+
files={"/env/empty_warehouse_01_1k.hdr"}
20+
environmentIntensity={0.8}
21+
scene={scene}
22+
/>
23+
<mesh scale={100}>
24+
<sphereGeometry args={[3, 32, 32]} />
25+
<meshBasicMaterial
26+
color={new THREE.Color(0x666666)}
27+
map={stickerMap}
28+
side={THREE.BackSide}
29+
/>
30+
</mesh>
31+
</>
32+
);
33+
}
34+
);
35+
Background.displayName = "Background";

‎app/stickers/CanvasState.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as THREE from "three";
22
import { CLICKED_WOBBLE_STRENGTH } from "./StickerBall";
3-
import { STICKER_TEXTURES_LENGTH } from "./useStickers";
3+
import { STICKER_TEXTURES_LENGTH } from "./StickerBall/useStickers";
44

55
export class CanvasState {
66
private static instance: CanvasState;
@@ -18,7 +18,7 @@ export class CanvasState {
1818
};
1919

2020
public CAMERA_Z = {
21-
zoom: 3.5,
21+
zoom: 3.2,
2222
default: 4,
2323
};
2424

‎app/stickers/Playground.tsx‎

Lines changed: 94 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,81 @@
11
"use client";
22

33
import * as THREE from "three";
4-
import { memo } from "react";
5-
import { Environment,OrbitControls } from "@react-three/drei";
6-
import { useFrame } from "@react-three/fiber";
7-
import { useStickers } from "./useStickers";
4+
import { useMemo,useRef } from "react";
5+
import { OrbitControls } from "@react-three/drei";
6+
import { useFrame,createPortal,extend,useThree } from "@react-three/fiber";
7+
import { useStickers } from "./StickerBall/useStickers";
88
import { CanvasState } from "./CanvasState";
99
import { StickerBall } from "./StickerBall";
10-
import { Easing, Utils } from "@/packages/use-shader-fx/src";
10+
import {
11+
Easing,
12+
Utils,
13+
useResizeBoundary,
14+
useSingleFBO,
15+
} from "@/packages/use-shader-fx/src";
16+
import { Background } from "./Background";
17+
import { FxMaterial, FxMaterialProps } from "./romanticism/FxMaterial";
18+
import { useRomanticism } from "./romanticism/useRomanticism";
1119

12-
const Background = memo(({ stickerMap }: { stickerMap: THREE.Texture }) => {
13-
return (
14-
<>
15-
<Environment preset="warehouse" environmentIntensity={0.5} />
16-
<mesh scale={100}>
17-
<sphereGeometry args={[3, 32, 32]} />
18-
<meshBasicMaterial
19-
color={new THREE.Color(0x444444)}
20-
map={stickerMap}
21-
side={THREE.BackSide}
22-
/>
23-
</mesh>
24-
</>
25-
);
26-
});
27-
Background.displayName = "Background";
20+
extend({ FxMaterial });
2821

2922
export const Playground = () => {
30-
const { stickerMap, normalMap, isReady, silhouette } = useStickers();
23+
const { camera, size, viewport, gl } = useThree();
3124

3225
const canvasState = CanvasState.getInstance();
3326

34-
useFrame(({ camera, clock }, delta) => {
27+
// 1000以上リサイズした場合のみリサイズする
28+
const resizeBoundary = useResizeBoundary({
29+
gl,
30+
size,
31+
boundFor: "larger",
32+
threshold: 1000,
33+
});
34+
35+
// stickers
36+
const { stickerMap, normalMap, isReady, silhouette } =
37+
useStickers(resizeBoundary);
38+
39+
// offscreen to stickers
40+
const offscreenScene = useMemo(() => new THREE.Scene(), []);
41+
const [portalStickers, updatePortalStickers] = useSingleFBO({
42+
scene: offscreenScene,
43+
camera,
44+
size,
45+
dpr: viewport.dpr,
46+
depthBuffer: true,
47+
isSizeUpdate: resizeBoundary.isUpdate,
48+
});
49+
50+
// romanticism
51+
const romanticism = useRomanticism(portalStickers.texture);
52+
const materialRef = useRef<FxMaterialProps>(null);
53+
54+
useFrame(({ camera, clock, pointer, gl }) => {
3555
if (!isReady) {
3656
return;
3757
}
3858

39-
// control camera state
40-
if (canvasState.cameraState.point.z < canvasState.CAMERA_Z.default) {
41-
canvasState.cameraState.point.z += delta;
59+
// update portalized stickers
60+
updatePortalStickers(gl);
61+
62+
// update romanticism
63+
if (materialRef.current) {
64+
materialRef.current.u_time = clock.getElapsedTime();
4265
}
43-
camera.position.lerp(canvasState.cameraState.point, 0.16);
66+
67+
// control camera state
68+
const _pointer = pointer.clone().multiplyScalar(0.32);
69+
canvasState.cameraState.point.lerp(
70+
{
71+
..._pointer, // uncomment this line to enable camera movement
72+
// x: 0,
73+
// y: 0,
74+
z: canvasState.CAMERA_Z.default,
75+
},
76+
0.12
77+
);
78+
camera.position.lerp(canvasState.cameraState.point, 0.14);
4479
camera.lookAt(0, 0, 0);
4580

4681
// control clock state
@@ -61,23 +96,37 @@ export const Playground = () => {
6196
}
6297
});
6398
return (
64-
<mesh visible={isReady}>
65-
<StickerBall
66-
stickerMap={stickerMap}
67-
normalMap={normalMap}
68-
silhouetteMap={silhouette}
69-
/>
70-
<Background stickerMap={stickerMap} />
71-
<OrbitControls
72-
enabled={true}
73-
enableZoom={false}
74-
enablePan={false}
75-
rotateSpeed={0.12}
76-
minAzimuthAngle={-0.785} // -45
77-
maxAzimuthAngle={0.785} // 45
78-
minPolarAngle={1.134} // 65
79-
maxPolarAngle={1.919} // 110
80-
/>
81-
</mesh>
99+
<>
100+
{createPortal(
101+
<mesh visible={isReady}>
102+
<StickerBall
103+
stickerMap={stickerMap}
104+
normalMap={normalMap}
105+
silhouetteMap={silhouette}
106+
/>
107+
<Background stickerMap={stickerMap} scene={offscreenScene} />
108+
<OrbitControls
109+
enabled={true}
110+
enableZoom={false}
111+
enablePan={false}
112+
rotateSpeed={0.12}
113+
minAzimuthAngle={-0.785} // -45
114+
maxAzimuthAngle={0.785} // 45
115+
minPolarAngle={1.134} // 65
116+
maxPolarAngle={1.919} // 110
117+
/>
118+
</mesh>,
119+
offscreenScene
120+
)}
121+
<mesh visible={isReady}>
122+
<planeGeometry args={[2, 2]} />
123+
<fxMaterial
124+
ref={materialRef}
125+
u_romance={romanticism}
126+
u_original={portalStickers.texture}
127+
key={FxMaterial.key}
128+
/>
129+
</mesh>
130+
</>
82131
);
83132
};

‎app/stickers/useStickers.ts‎ renamed to ‎app/stickers/StickerBall/useStickers.ts‎

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,8 @@
11
import * as THREE from "three";
2-
import {
3-
useMemo,
4-
useCallback,
5-
useReducer,
6-
useRef,
7-
useState,
8-
useEffect,
9-
} from "react";
10-
import { useFrame, useThree, useLoader } from "@react-three/fiber";
11-
import { useBlank, useBrush } from "@/packages/use-shader-fx/src";
12-
import { CanvasState } from "./CanvasState";
2+
import { useMemo, useCallback, useRef, useState } from "react";
3+
import { useFrame, useThree, useLoader, Size } from "@react-three/fiber";
4+
import { ResizeBoundary, Utils, useBlank } from "@/packages/use-shader-fx/src";
5+
import { CanvasState } from "../CanvasState";
136

147
const STICKER_TEXCOORD = `
158
vec2 stamp = uStampPoint;
@@ -61,7 +54,7 @@ const STICKER_TEXTURES = [
6154

6255
export const STICKER_TEXTURES_LENGTH = STICKER_TEXTURES.length;
6356

64-
export const useStickers = () => {
57+
export const useStickers = (resizeBoundary: ResizeBoundary) => {
6558
const canvasState = CanvasState.getInstance();
6659

6760
const textures = useLoader(THREE.TextureLoader, [
@@ -82,7 +75,8 @@ export const useStickers = () => {
8275

8376
const [updateSticker, _, { output: stickerMap }] = useBlank({
8477
size,
85-
dpr: 6,
78+
dpr: Math.min(resizeBoundary.maxDpr, 6),
79+
isSizeUpdate: resizeBoundary.isUpdate,
8680
onBeforeInit: useCallback(
8781
(parameters: any) => {
8882
Object.assign(parameters.uniforms, {
@@ -120,6 +114,11 @@ export const useStickers = () => {
120114
usf_FragColor = finalColor;
121115
`
122116
);
117+
118+
parameters.fragmentShader = parameters.fragmentShader.replace(
119+
"precision highp float;",
120+
"precision lowp float;"
121+
);
123122
},
124123
// eslint-disable-next-line react-hooks/exhaustive-deps
125124
[]
@@ -128,7 +127,8 @@ export const useStickers = () => {
128127

129128
const [updateNormal, __, { output: normalMap }] = useBlank({
130129
size,
131-
dpr: 4,
130+
dpr: Math.min(resizeBoundary.maxDpr, 4),
131+
isSizeUpdate: resizeBoundary.isUpdate,
132132
onBeforeInit: useCallback(
133133
(shader: any) => {
134134
Object.assign(shader.uniforms, {
@@ -201,6 +201,11 @@ export const useStickers = () => {
201201
usf_FragColor = finalColor;
202202
`
203203
);
204+
205+
shader.fragmentShader = shader.fragmentShader.replace(
206+
"precision highp float;",
207+
"precision lowp float;"
208+
);
204209
},
205210
// eslint-disable-next-line react-hooks/exhaustive-deps
206211
[]
@@ -209,6 +214,13 @@ export const useStickers = () => {
209214

210215
const tickCount = useRef(-2);
211216

217+
if (
218+
resizeBoundary.isUpdate &&
219+
tickCount.current === canvasState.stickerState.count
220+
) {
221+
tickCount.current -= 2;
222+
}
223+
212224
const [isReady, setIsReady] = useState(false);
213225

214226
useFrame((state) => {
@@ -218,7 +230,7 @@ export const useStickers = () => {
218230

219231
tickCount.current++;
220232

221-
if (tickCount.current === 0) {
233+
if (tickCount.current === 0&&!isReady) {
222234
setIsReady(true);
223235
}
224236

‎app/stickers/UI/Cursor/GifPreloader.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { memo } from "react";
22
import Image from "next/image";
3-
import { STICKER_TEXTURES_LENGTH } from "../../useStickers";
3+
import { STICKER_TEXTURES_LENGTH } from "../../StickerBall/useStickers";
44

55
const GIF_IMAGES = [...Array(STICKER_TEXTURES_LENGTH)].map(
66
(_, i) => `/stickers/gif/gif${i}.gif`

‎app/stickers/UI/Cursor/index.tsx‎

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@ import { useCallback, useEffect, useRef, useState } from "react";
77
import gsap from "gsap";
88
import { GifPreloader } from "./GifPreloader";
99
import { Confetti } from "./Confetti";
10-
import { useIsTouchDevice } from "@funtech-inc/spice";
10+
import { useIsTouchDevice,useFrame } from "@funtech-inc/spice";
1111
import s from "./index.module.scss";
1212

1313
const updateTargetPoint = (target: HTMLDivElement, point: THREE.Vector2) => {
14-
const targetRect = target.getBoundingClientRect();
15-
target.style.left = `${point.x - targetRect.width / 2}px`;
16-
target.style.top = `${point.y - targetRect.height / 2}px`;
14+
const width = target.clientWidth;
15+
const height = target.clientHeight;
16+
target.style.left = `${point.x - width / 2}px`;
17+
target.style.top = `${point.y - height / 2}px`;
1718
};
1819

1920
const CURSOR_LERP = 0.8;
@@ -58,7 +59,6 @@ export const CursorUI = () => {
5859
canvasState.stickerState.nextStickerIndex
5960
);
6061

61-
const rafID = useRef<number>(0);
6262
const cursorRef = useRef<HTMLDivElement>(null);
6363
const imageRef = useRef<HTMLImageElement>(null);
6464
const confettiRef = useRef<HTMLDivElement>(null);
@@ -170,7 +170,7 @@ export const CursorUI = () => {
170170
[canvasState]
171171
);
172172

173-
consthandleFrame=useCallback(() => {
173+
useFrame(() => {
174174
const isOver = canvasState.cursorState.isOver;
175175

176176
// update sticker index
@@ -194,21 +194,7 @@ export const CursorUI = () => {
194194
updateCursorPoint(false);
195195
}
196196
prevIsOver.current = isOver;
197-
rafID.current = requestAnimationFrame(handleFrame);
198-
}, [
199-
canvasState.stickerState,
200-
stickerIndex,
201-
canvasState.cursorState,
202-
onStickerChange,
203-
onOver,
204-
onOut,
205-
updateCursorPoint,
206-
]);
207-
208-
useEffect(() => {
209-
rafID.current = requestAnimationFrame(handleFrame);
210-
return () => cancelAnimationFrame(rafID.current);
211-
}, [handleFrame]);
197+
});
212198

213199
return (
214200
<div className={s.container}>

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /