Skip to content

Commit 9d3ea1f

Browse files
author
Eli
committed
Moving to Next.js
1 parent 1645a75 commit 9d3ea1f

12 files changed

+2656
-1965
lines changed

.gitignore

+30-5
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
1-
node_modules/
2-
dist/
3-
inspiration
4-
*.log
5-
stats.json
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.js
7+
8+
# testing
9+
/coverage
10+
11+
# next.js
12+
/.next/
13+
/out/
14+
15+
# production
16+
/build
17+
18+
# misc
19+
.DS_Store
20+
21+
# debug
22+
npm-debug.log*
23+
yarn-debug.log*
24+
yarn-error.log*
25+
26+
# local env files
27+
.env.local
28+
.env.development.local
29+
.env.test.local
30+
.env.production.local

next.config.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const path = require('path');
2+
const merge = require('deepmerge');
3+
4+
module.exports = {
5+
webpack: (config) => {
6+
const customAlias = merge(config.resolve.alias, {
7+
'@three': path.resolve('node_modules/three/build/three.module.js'),
8+
'@three-controls': path.resolve(
9+
'node_modules/three/examples/jsm/controls'
10+
),
11+
'@three-libs': path.resolve('node_modules/three/examples/jsm/libs'),
12+
'@three-gui': path.resolve(
13+
'node_modules/three/examples/jsm/libs/dat.gui.module.js'
14+
),
15+
'@three-modules': path.resolve('node_modules/three/examples/jsm'),
16+
17+
'@textures': path.resolve(__dirname, 'src/assets/textures/'),
18+
'@styles': path.resolve(__dirname, 'src/assets/styles/'),
19+
'@helpers': path.resolve(__dirname, 'src/helpers/'),
20+
'@factories': path.resolve(__dirname, 'src/helpers/factories/'),
21+
});
22+
23+
config.resolve.alias = customAlias;
24+
25+
return config;
26+
},
27+
};

package.json

+18-28
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,24 @@
11
{
2-
"dependencies": {
3-
"react": "^16.13.1",
4-
"react-dom": "^16.13.1",
5-
"react-three-fiber": "^4.0.25",
6-
"three": "^0.115.0"
7-
},
8-
"scripts": {
9-
"start": "webpack-dev-server -d --hot",
10-
"build": "webpack --mode production",
11-
"stats": "webpack --json --mode production > stats.json"
12-
},
13-
"devDependencies": {
14-
"@babel/core": "^7.9.0",
15-
"@babel/plugin-proposal-class-properties": "^7.8.3",
16-
"@babel/preset-env": "^7.9.0",
17-
"@babel/preset-react": "^7.9.4",
18-
"babel-loader": "^8.1.0",
19-
"clean-webpack-plugin": "^3.0.0",
20-
"css-loader": "^3.5.3",
21-
"file-loader": "^6.0.0",
22-
"style-loader": "^1.2.1",
23-
"webpack": "^4.42.1",
24-
"webpack-cli": "^3.3.11",
25-
"webpack-dev-server": "^3.10.3"
26-
},
272
"name": "threejs-exploration",
28-
"version": "1.0.0",
29-
"description": "Exploring three.js with react-three-fiber",
3+
"version": "0.1.0",
4+
"description": "Exploring three.js",
305
"repository": "https://github.com/epleaner/threejs-react.git",
316
"author": "Eli <[email protected]>",
327
"license": "MIT",
33-
"private": true
8+
"private": true,
9+
"scripts": {
10+
"dev": "next dev",
11+
"build": "next build",
12+
"start": "next start"
13+
},
14+
"dependencies": {
15+
"next": "9.2.1",
16+
"react": "16.12.0",
17+
"react-dom": "16.12.0",
18+
"react-three-fiber": "4.0.12",
19+
"three": "0.112.1"
20+
},
21+
"devDependencies": {
22+
"deepmerge": "^4.2.2"
23+
}
3424
}

pages/_app.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import React from 'react'
2+
import './index.css'
3+
4+
function MyApp({ Component, pageProps }) {
5+
return <Component {...pageProps} />
6+
}
7+
8+
export default MyApp

pages/birds.js

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import React, { useRef, useState, useEffect, Suspense } from 'react'
2+
import * as THREE from 'three'
3+
import { Canvas, useFrame, useLoader } from 'react-three-fiber'
4+
5+
let GLTFLoader
6+
7+
const Bird = ({ speed, factor, url, ...props }) => {
8+
const gltf = useLoader(GLTFLoader, url)
9+
const group = useRef()
10+
const [mixer] = useState(() => new THREE.AnimationMixer())
11+
useEffect(
12+
() => void mixer.clipAction(gltf.animations[0], group.current).play(),
13+
[gltf.animations, mixer]
14+
)
15+
useFrame((state, delta) => {
16+
group.current.rotation.y +=
17+
Math.sin((delta * factor) / 2) * Math.cos((delta * factor) / 2) * 1.5
18+
mixer.update(delta * speed)
19+
})
20+
return (
21+
<group ref={group}>
22+
<scene name="Scene" {...props}>
23+
<mesh
24+
name="Object_0"
25+
morphTargetDictionary={gltf.__$[1].morphTargetDictionary}
26+
morphTargetInfluences={gltf.__$[1].morphTargetInfluences}
27+
rotation={[1.5707964611537577, 0, 0]}
28+
>
29+
<bufferGeometry attach="geometry" {...gltf.__$[1].geometry} />
30+
<meshStandardMaterial
31+
attach="material"
32+
{...gltf.__$[1].material}
33+
name="Material_0_COLOR_0"
34+
/>
35+
</mesh>
36+
</scene>
37+
</group>
38+
)
39+
}
40+
41+
const Birds = () => {
42+
return new Array(5).fill().map((_, i) => {
43+
const x = (15 + Math.random() * 30) * (Math.round(Math.random()) ? -1 : 1)
44+
const y = -10 + Math.random() * 20
45+
const z = -5 + Math.random() * 10
46+
const bird = ['stork', 'parrot', 'flamingo'][Math.round(Math.random() * 2)]
47+
let speed = bird === 'stork' ? 0.5 : bird === 'flamingo' ? 2 : 5
48+
let factor =
49+
bird === 'stork'
50+
? 0.5 + Math.random()
51+
: bird === 'flamingo'
52+
? 0.25 + Math.random()
53+
: 1 + Math.random() - 0.5
54+
return (
55+
<Bird
56+
key={i}
57+
position={[x, y, z]}
58+
rotation={[0, x > 0 ? Math.PI : 0, 0]}
59+
speed={speed}
60+
factor={factor}
61+
url={`/glb/${bird}.glb`}
62+
/>
63+
)
64+
})
65+
}
66+
67+
const BirdsPage = props => {
68+
useEffect(() => {
69+
GLTFLoader = require('three/examples/jsm/loaders/GLTFLoader').GLTFLoader
70+
}, [])
71+
return (
72+
<>
73+
<Canvas camera={{ position: [0, 0, 35] }}>
74+
<ambientLight intensity={2} />
75+
<pointLight position={[40, 40, 40]} />
76+
<Suspense fallback={null}>
77+
<Birds />
78+
</Suspense>
79+
</Canvas>
80+
</>
81+
)
82+
}
83+
84+
export default BirdsPage

pages/boxes.js

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React, { useRef, useState, Suspense } from 'react'
2+
import { Canvas, useFrame } from 'react-three-fiber'
3+
4+
const Box = props => {
5+
const mesh = useRef()
6+
7+
const [hovered, setHover] = useState(false)
8+
const [active, setActive] = useState(false)
9+
10+
useFrame(() => (mesh.current.rotation.x = mesh.current.rotation.y += 0.01))
11+
12+
return (
13+
<mesh
14+
{...props}
15+
ref={mesh}
16+
scale={active ? [6, 6, 6] : [5, 5, 5]}
17+
onClick={e => setActive(!active)}
18+
onPointerOver={e => setHover(true)}
19+
onPointerOut={e => setHover(false)}
20+
>
21+
<boxBufferGeometry attach="geometry" args={[1, 1, 1]} />
22+
<meshStandardMaterial
23+
attach="material"
24+
color={hovered ? '#2b6c76' : '#720b23'}
25+
/>
26+
</mesh>
27+
)
28+
}
29+
30+
const BirdsPage = () => {
31+
return [
32+
<h1>Click on me - Hover me :)</h1>,
33+
<Canvas camera={{ position: [0, 0, 35] }}>
34+
<ambientLight intensity={2} />
35+
<pointLight position={[40, 40, 40]} />
36+
<Suspense fallback={null}>
37+
<Box position={[10, 0, 0]} />
38+
<Box position={[-10, 0, 0]} />
39+
<Box position={[0, 10, 0]} />
40+
<Box position={[0, -10, 0]} />
41+
</Suspense>
42+
</Canvas>,
43+
]
44+
}
45+
46+
export default BirdsPage

pages/index.css

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
body {
2+
margin: 0;
3+
padding: 0;
4+
width: 100%;
5+
height: 100vh;
6+
background: lavender;
7+
}
8+
9+
canvas {
10+
width: 100%;
11+
height: 100vh;
12+
}
13+
14+
h1 {
15+
display: flex;
16+
justify-content: center;
17+
align-content: center;
18+
color: hotpink;
19+
}
20+
21+
.main {
22+
background: hotpink;
23+
padding: 50px;
24+
border-radius: 4px;
25+
display: flex;
26+
margin: 200px;
27+
flex-direction: column;
28+
justify-content: center;
29+
align-items: center;
30+
color: white;
31+
}
32+
33+
a {
34+
color: white;
35+
display: block;
36+
text-decoration: unset;
37+
font-size: 20px;
38+
margin: 5px 0;
39+
}
40+
41+
a:hover {
42+
color: #3f51b5;
43+
}

pages/index.js

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from 'react'
2+
import Link from 'next/link'
3+
4+
const Index = () => {
5+
return (
6+
<div className="main">
7+
<Link href="/birds">
8+
<a>Birds Example</a>
9+
</Link>
10+
<Link href="/boxes">
11+
<a>Boxes Example</a>
12+
</Link>
13+
</div>
14+
)
15+
}
16+
17+
export default Index

public/glb/flamingo.glb

322 KB
Binary file not shown.

public/glb/parrot.glb

325 KB
Binary file not shown.

public/glb/stork.glb

302 KB
Binary file not shown.

0 commit comments

Comments
 (0)