-
Notifications
You must be signed in to change notification settings - Fork 21
/
script.js
126 lines (113 loc) · 3.3 KB
/
script.js
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
import {
Scene,
PerspectiveCamera,
WebGLRenderer,
GridHelper,
ConeGeometry,
MeshPhongMaterial,
Mesh,
Matrix4,
Quaternion,
Vector3,
HemisphereLight,
} from 'three'
import { CameraRig, StoryPointsControls, ThreeDOFControls } from 'three-story-controls'
const canvasParent = document.querySelector('.canvas-parent')
const nextBtn = document.querySelector('.next')
const prevBtn = document.querySelector('.prev')
const caption = document.querySelector('.caption p')
const scene = new Scene()
const camera = new PerspectiveCamera(45, canvasParent.clientWidth / canvasParent.clientHeight, .1, 10000)
const renderer = new WebGLRenderer()
renderer.setSize(canvasParent.clientWidth, canvasParent.clientHeight)
canvasParent.appendChild(renderer.domElement)
const light = new HemisphereLight(0xffffbb, 0x080820, 1)
scene.add(light)
const grid = new GridHelper(100, 50)
grid.position.set(0, -5, 0)
scene.add(grid)
const storyPoints = [
{
meshPosition: new Vector3(0, 0, -30),
color: 0xff0000,
phi: Math.PI * 0.5,
theta: 0,
caption: 'This is a caption about the RED cone',
},
{
meshPosition: new Vector3(20, 0, -45),
color: 0xffff00,
phi: Math.PI * 0.4,
theta: Math.PI * 0.5,
caption: 'This is a caption about the YELLOW cone',
},
{
meshPosition: new Vector3(45, 0, 0),
color: 0xff00ff,
phi: Math.PI * 0.3,
theta: -Math.PI,
caption: 'This is a caption about the PINK cone',
},
{
meshPosition: new Vector3(30, 0, 20),
color: 0x00ffff,
phi: Math.PI * 0,
theta: Math.PI * 0.3,
caption: 'This is a caption about the TEAL cone',
},
{
meshPosition: new Vector3(-10, 0, 45),
color: 0x00ff00,
phi: Math.PI * 0.35,
theta: -Math.PI * 0.2,
caption: 'This is a caption about the GREEN cone',
},
{
meshPosition: new Vector3(-40, 0, 20),
color: 0x0000ff,
phi: Math.PI * 0.5,
theta: 0,
caption: 'This is a caption about the BLUE cone',
},
]
const cameraPositions = storyPoints.map((item) => {
const mesh = new Mesh(new ConeGeometry(3, 10, 4), new MeshPhongMaterial({ color: item.color }))
mesh.position.copy(item.meshPosition)
scene.add(mesh)
const position = new Vector3().setFromSphericalCoords(15, item.phi, item.theta).add(mesh.position)
const mat = new Matrix4().lookAt(position, mesh.position, new Vector3(0, 1, 0))
const quaternion = new Quaternion().setFromRotationMatrix(mat)
return {
position,
quaternion,
duration: 1,
useSlerp: true,
}
})
const rig = new CameraRig(camera, scene)
const controls = new StoryPointsControls(rig, cameraPositions, {
cycle: true,
})
controls.enable()
controls.goToPOI(0)
const controls3dof = new ThreeDOFControls(rig)
controls3dof.enable()
nextBtn.addEventListener('click', () => controls.nextPOI())
prevBtn.addEventListener('click', () => controls.prevPOI())
controls.addEventListener('update', (event) => {
if (event.progress > 0.8) {
caption.innerText = storyPoints[event.upcomingIndex].caption
}
})
function render(t) {
window.requestAnimationFrame(render)
controls.update(t)
controls3dof.update(t)
renderer.render(scene, camera)
}
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight
camera.updateProjectionMatrix()
renderer.setSize(window.innerWidth, window.innerHeight)
})
render()