Skip to content

Commit 209ffdb

Browse files
committed
feat: add three.js, typescript, eslint and standard
1 parent ae5e2d8 commit 209ffdb

File tree

7 files changed

+1564
-1248
lines changed

7 files changed

+1564
-1248
lines changed

.eslintrc

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"extends": ["standard-jsx", "standard-with-typescript"],
3+
"parserOptions": {
4+
"project": "./tsconfig.json"
5+
}
6+
}

components/game.tsx

+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { useState, useEffect, useRef } from 'react'
2+
import * as THREE from 'three'
3+
4+
function Game (): JSX.Element {
5+
const canvas = useRef<HTMLCanvasElement>(null)
6+
const renderRef = useRef<null | number>(null)
7+
8+
const [renderer, setRenderer] = useState<THREE.WebGLRenderer>()
9+
const [rendering, setRendering] = useState(false)
10+
11+
const [scene, setScene] = useState<THREE.Scene>()
12+
const [camera, setCamera] = useState<THREE.PerspectiveCamera>()
13+
const [testCube, setTestCube] = useState<THREE.Mesh>()
14+
15+
useEffect(() => {
16+
if (canvas.current == null) return
17+
console.log('useEffect renderer')
18+
19+
const glRenderer = new THREE.WebGLRenderer({
20+
canvas: canvas.current
21+
})
22+
23+
setRenderer(glRenderer)
24+
25+
const fov = 75
26+
const aspect = 2 // the canvas default
27+
const near = 0.1
28+
const far = 5
29+
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far)
30+
31+
camera.position.z = 2
32+
33+
setCamera(camera)
34+
35+
const scene = new THREE.Scene()
36+
setScene(scene)
37+
38+
const boxWidth = 1
39+
const boxHeight = 1
40+
const boxDepth = 1
41+
const geometry = new THREE.BoxGeometry(boxWidth, boxHeight, boxDepth)
42+
43+
const material = new THREE.MeshBasicMaterial({ color: 0x44aa88 })
44+
45+
const cube = new THREE.Mesh(geometry, material)
46+
47+
scene.add(cube)
48+
49+
setTestCube(cube)
50+
setRendering(true)
51+
}, [canvas])
52+
53+
useEffect(() => {
54+
console.log('useEffect anim frame', renderer, rendering)
55+
56+
function render (time): void {
57+
time *= 0.001 // convert time to seconds
58+
59+
// @ts-expect-error
60+
testCube.rotation.x = time
61+
// @ts-expect-error
62+
testCube.rotation.y = time
63+
64+
// @ts-expect-error
65+
renderer.render(scene, camera)
66+
67+
renderRef.current = requestAnimationFrame(render)
68+
}
69+
70+
if (renderer instanceof THREE.WebGLRenderer && rendering) {
71+
renderRef.current = requestAnimationFrame(render)
72+
}
73+
74+
return () => {
75+
if (typeof renderRef.current === 'number') {
76+
cancelAnimationFrame(renderRef.current)
77+
}
78+
}
79+
}, [renderer, rendering, testCube])
80+
81+
return (
82+
<div>
83+
<canvas id="game" ref={canvas} />
84+
<br />
85+
<button onClick={() => {
86+
setRendering(!rendering)
87+
}}>Toggle rendering, current: {JSON.stringify(rendering)}</button>
88+
</div>
89+
)
90+
}
91+
92+
export default Game

next-env.d.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/types/global" />
3+
/// <reference types="next/image-types/global" />
4+
5+
// NOTE: This file should not be edited
6+
// see https://nextjs.org/docs/basic-features/typescript for more information.

0 commit comments

Comments
 (0)