-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path3d.html
219 lines (187 loc) · 6.14 KB
/
3d.html
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
<canvas id="canvas"></canvas>
<style>
body {
margin: 0;
overflow: hidden;
}
canvas {
width:100%;
height:100%;
}
</style>
<script>
const DEGTORAD = Math.PI/180
class Camera {
constructor() {
this.x = 0
this.y = 0
this.z = 0
this.angle = 0
}
}
class Dot {
constructor() {
this.x = (Math.random() - 0.5) * width
this.y = 10
this.z = Math.random() * width
this.radius = Math.random() * 20 + 30;
this.xProjected = 0
this.yProjected = 0
this.scaleProjected = 0
}
transform() {
let theta = cam.angle*DEGTORAD
let s = Math.sin(theta)
let c = Math.cos(theta)
this.transformedX = this.x-cam.x // subtract rotation point (camera)
this.transformedZ = this.z-cam.z
this.tempX = this.transformedX*c - this.transformedZ*s // rotate
this.tempZ = this.transformedX*s + this.transformedZ*c
this.transformedX = this.tempX + cam.x // add back the rotation point (camera)
this.transformedZ = this.tempZ + cam.z
}
project() {
// The scaleProjected will store the scale of the element based on its distance from the 'camera'
this.transform()
this.scaleProjected = Math.max(PERSPECTIVE / (PERSPECTIVE + (this.transformedZ + cam.z)), 0)
this.xProjected = ((this.transformedX - cam.x) * this.scaleProjected) + PROJECTION_CENTRE_X
this.yProjected = ((this.y - cam.y) * this.scaleProjected) + PROJECTION_CENTRE_Y
}
draw() {
// We first calculate the projected values of our dot
this.project();
// We define the opacity of our element based on its distance
//ctx.globalAlpha = Math.abs(1 - (this.z - cam.z) / width);
// We draw a rectangle based on the projected coordinates and scale
if (this.z > cam.z) {
ctx.drawImage(treepng, this.xProjected - (this.radius *2* this.scaleProjected), this.yProjected - (this.radius *2* this.scaleProjected), this.radius * 2 * this.scaleProjected * (treepng.width/treepng.width), this.radius * 2 * this.scaleProjected * (treepng.width/treepng.width))
}
}
}
class Car {
constructor() {
this.x = 0
this.y = 0
this.z = -1000
this.direction = 0
this.throttle = 0
this.brakes = 0
this.steering = 0
this.leftSteer = 0
this.rightSteer = 0
this.accel = 0
}
}
let car = new Car()
document.addEventListener("keydown", function (event) {
if (event.defaultPrevented) {return;}
var handled = false;
if (event.key !== undefined) {
handled = true;
if (event.key == 'w' || event.key == 'W') { car.throttle = 1; }
if (event.key == 's' || event.key == 'S') { car.brakes = 1; }
if (event.key == 'a' || event.key == 'A') { car.leftSteer = 1; }
if (event.key == 'd' || event.key == 'D') { car.rightSteer = 1; }
controls()
}
if (handled) { event.preventDefault(); }
}, true);
document.addEventListener("keyup", function (event) {
if (event.defaultPrevented) {return;}
var handled = false;
if (event.key !== undefined) {
handled = true;
if (event.key == 'w' || event.key == 'W') { car.throttle = 0; }
if (event.key == 's' || event.key == 'S') { car.brakes = 0; }
if (event.key == 'a' || event.key == 'A') { car.leftSteer = 0; }
if (event.key == 'd' || event.key == 'D') { car.rightSteer = 0; }
controls()
}
if (handled) { event.preventDefault(); }
}, true);
function controls() {
if (car.leftSteer == 1 && car.rightSteer == 1){
car.steering = 0
} else if (car.leftSteer == 1) {
car.steering = -1
} else if (car.rightSteer == 1) {
car.steering = 1
} else { car.steering = 0 }
}
function moveCar() {
if (car.throttle == 1 && car.brakes == 1) {
} else if (car.throttle == 1) {
let theta = cam.angle*DEGTORAD
cam.z -= Math.cos(theta)
cam.x += Math.sin(theta)
console.log(cam.x, cam.z, cam.angle)
} else if (car.brakes == 1) {
let theta = cam.angle*DEGTORAD
cam.z += Math.cos(theta)
cam.x -= Math.sin(theta)
}
if (car.steering == -1) {
cam.angle -= 0.5
} else if (car.steering == 1) {
cam.angle += 0.5
}
}
function render() {
onResize()
moveCar()
// Clear the canvas
ctx.clearRect(0, 0, width, height)
ctx.fillStyle = 'lightblue'; // initialize canvas
ctx.fillRect(0, 0, canvas.width, canvas.height/2);
ctx.fillStyle = 'lightgreen'; // initialize canvas
ctx.fillRect(0, canvas.height/2, canvas.width, canvas.height/2);
// Loop through the dots array and draw every dot
for (var i = 0; i < dots.length; i++) {
dots[i].project()
}
dots.sort( (dot1, dot2) => {
return dot1.scaleProjected - dot2.scaleProjected
})
for (var i = 0; i < dots.length; i++) {
dots[i].draw()
}
window.requestAnimationFrame(render)
}
function onResize() {
// Lookup the size the browser is displaying the canvas in CSS pixels.
const displayWidth = canvas.clientWidth;
const displayHeight = canvas.clientHeight;
// Check if the canvas is not the same size.
let needResize = canvas.width !== displayWidth ||
canvas.height !== displayHeight;
if (needResize) {
// Make the canvas the same size
canvas.width = displayWidth;
canvas.height = displayHeight;
width = canvas.width
height = canvas.height
PERSPECTIVE = width * 0.8 // fov
PROJECTION_CENTRE_X = width / 2
PROJECTION_CENTRE_Y = height / 2
render()
}
}
const canvas = document.getElementById('canvas')
// get the canvas dimensions
let width = canvas.clientWidth
let height = canvas.clientHeight
const ctx = canvas.getContext('2d')
let treepng = new Image()
//treepng.src = "https://pics.clipartpng.com/Realistic_Green_Tree_PNG_Clip_Art-1102.png"
treepng.src = "tree.png"
let PERSPECTIVE = width * 0.8 // fov
let PROJECTION_CENTRE_X = width / 2
let PROJECTION_CENTRE_Y = height / 2
let dots = []
let cam = new Camera()
for (let i = 0; i < 50; i++) {
// Create a new dot and push it into the array
dots.push(new Dot())
}
render()
</script>