html5jp_graphs 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitigore +2 -0
- data/README.rdoc +82 -0
- data/Rakefile +22 -0
- data/html5jp_graphs.gemspec +17 -0
- data/lib/examples/sample_graph_circle_1.html +54 -0
- data/lib/examples/sample_graph_circle_2.html +61 -0
- data/lib/examples/sample_graph_line_1.html +44 -0
- data/lib/examples/sample_graph_line_2.html +53 -0
- data/lib/examples/sample_graph_radar_1.html +47 -0
- data/lib/examples/sample_graph_radar_2.html +52 -0
- data/lib/examples/sample_graph_vbar_1.html +51 -0
- data/lib/examples/sample_graph_vbar_2.html +52 -0
- data/lib/examples/sample_graph_vbar_3.html +52 -0
- data/lib/examples/sample_graph_vbar_4.html +52 -0
- data/lib/generators/html5jp_graphs/USAGE +8 -0
- data/lib/generators/html5jp_graphs/html5jp_graphs_generator.rb +12 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/AUTHORS +10 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/COPYING +202 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/README +22 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/examples/example1.html +93 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/examples/example2.html +513 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/examples/example3.html +284 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/examples/ff.jpg +0 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/excanvas-compressed.js +19 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/excanvas.js +785 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/testcases/arc.html +49 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/testcases/linewidth.html +47 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/testcases/overflow.html +37 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/testcases/quadraticcurve.html +74 -0
- data/lib/generators/html5jp_graphs/templates/excanvas/testcases/resizing.html +65 -0
- data/lib/generators/html5jp_graphs/templates/graph/circle.js +407 -0
- data/lib/generators/html5jp_graphs/templates/graph/line.js +577 -0
- data/lib/generators/html5jp_graphs/templates/graph/radar.js +545 -0
- data/lib/generators/html5jp_graphs/templates/graph/vbar.js +1156 -0
- data/lib/html5jp_graphs.rb +1 -0
- data/lib/html5jp_graphs/version.rb +3 -0
- data/lib/html5jp_graphs_helper.rb +255 -0
- data/tasks/html5jp_graphs_tasks.rake +4 -0
- data/test/html5jp_graphs_test.rb +8 -0
- metadata +88 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
ExplorerCanvas
|
2
|
+
Copyright 2006 Google Inc.
|
3
|
+
|
4
|
+
-------------------------------------------------------------------------------
|
5
|
+
DESCRIPTION
|
6
|
+
|
7
|
+
Firefox, Safari and Opera 9 support the canvas tag to allow 2D command-based
|
8
|
+
drawing operations. ExplorerCanvas brings the same functionality to Internet
|
9
|
+
Explorer; web developers only need to include a single script tag in their
|
10
|
+
existing canvas webpages to enable this support.
|
11
|
+
|
12
|
+
|
13
|
+
-------------------------------------------------------------------------------
|
14
|
+
INSTALLATION
|
15
|
+
|
16
|
+
Include the ExplorerCanvas tag in the same directory as your HTML files, and
|
17
|
+
add the following code to your page, preferably in the <head> tag.
|
18
|
+
|
19
|
+
<!--[if IE]><script type="text/javascript" src="excanvas.js"></script><![endif]-->
|
20
|
+
|
21
|
+
If you run into trouble, please look at the included example code to see how
|
22
|
+
to best implement this
|
@@ -0,0 +1,93 @@
|
|
1
|
+
<!--
|
2
|
+
Copyright 2006 Google Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
-->
|
16
|
+
<html>
|
17
|
+
<head>
|
18
|
+
<title>ExplorerCanvas Example 1</title>
|
19
|
+
<!--[if IE]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
|
20
|
+
<script type="text/javascript">
|
21
|
+
var canvas, ctx;
|
22
|
+
var particles = [];
|
23
|
+
var NUM_PARTICLES = 20;
|
24
|
+
|
25
|
+
function Particle() {
|
26
|
+
this.x = Math.random() * canvas.width;
|
27
|
+
this.y = Math.random() * canvas.height;
|
28
|
+
|
29
|
+
this.xvel = Math.random() * 5 - 2.5;
|
30
|
+
this.yvel = Math.random() * 5 - 2.5;
|
31
|
+
}
|
32
|
+
|
33
|
+
Particle.prototype.update = function() {
|
34
|
+
this.x += this.xvel;
|
35
|
+
this.y += this.yvel;
|
36
|
+
|
37
|
+
this.yvel += 0.1;
|
38
|
+
|
39
|
+
if (this.x > canvas.width || this.x < 0) {
|
40
|
+
this.xvel = -this.xvel;
|
41
|
+
}
|
42
|
+
|
43
|
+
if (this.y > canvas.height || this.y < 0) {
|
44
|
+
this.yvel = -this.yvel;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
function loop() {
|
49
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
50
|
+
|
51
|
+
for(var i = 0; i < NUM_PARTICLES; i++) {
|
52
|
+
particles[i].update();
|
53
|
+
|
54
|
+
ctx.beginPath();
|
55
|
+
ctx.moveTo(particles[i].x, particles[i].y);
|
56
|
+
ctx.lineTo(particles[i].x - particles[i].xvel,
|
57
|
+
particles[i].y - particles[i].yvel);
|
58
|
+
ctx.stroke();
|
59
|
+
ctx.closePath();
|
60
|
+
}
|
61
|
+
|
62
|
+
setTimeout(loop, 10);
|
63
|
+
}
|
64
|
+
|
65
|
+
function load() {
|
66
|
+
canvas = document.getElementById("cv");
|
67
|
+
ctx = canvas.getContext("2d");
|
68
|
+
|
69
|
+
for(var i = 0; i < NUM_PARTICLES; i++) {
|
70
|
+
particles[i] = new Particle();
|
71
|
+
}
|
72
|
+
|
73
|
+
ctx.lineWidth = "2";
|
74
|
+
ctx.strokeStyle = "rgb(255, 255, 255)";
|
75
|
+
loop();
|
76
|
+
}
|
77
|
+
</script>
|
78
|
+
<style>
|
79
|
+
body {
|
80
|
+
background-color:black;
|
81
|
+
margin:50px;
|
82
|
+
text-align:center;
|
83
|
+
}
|
84
|
+
|
85
|
+
canvas {
|
86
|
+
border:1px solid #444;
|
87
|
+
}
|
88
|
+
</style>
|
89
|
+
</head>
|
90
|
+
<body onload="load();">
|
91
|
+
<canvas id="cv" width="400" height="300"></canvas>
|
92
|
+
</body>
|
93
|
+
</html>
|
@@ -0,0 +1,513 @@
|
|
1
|
+
<!--
|
2
|
+
Copyright 2006 Google Inc.
|
3
|
+
|
4
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
you may not use this file except in compliance with the License.
|
6
|
+
You may obtain a copy of the License at
|
7
|
+
|
8
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
|
10
|
+
Unless required by applicable law or agreed to in writing, software
|
11
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
See the License for the specific language governing permissions and
|
14
|
+
limitations under the License.
|
15
|
+
-->
|
16
|
+
<html>
|
17
|
+
<head>
|
18
|
+
<title>ExplorerCanvas Example 1</title>
|
19
|
+
<!--[if IE]><script type="text/javascript" src="../excanvas.js"></script><![endif]-->
|
20
|
+
<script type="text/javascript">
|
21
|
+
/* -------------------------------------------------------------------- */
|
22
|
+
|
23
|
+
var canvas, ctx;
|
24
|
+
var canvasWidth, halfCanvasWidth;
|
25
|
+
var canvasHeight, halfCanvasHeight;
|
26
|
+
|
27
|
+
var space; // 3D Engine
|
28
|
+
var scene; // 3D Scene
|
29
|
+
|
30
|
+
/* -------------------------------------------------------------------- */
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Space is a simple 3D system.
|
34
|
+
*
|
35
|
+
* Y+ = up
|
36
|
+
* Z+ = into screen
|
37
|
+
* X+ = right
|
38
|
+
*/
|
39
|
+
function Space() {
|
40
|
+
this.m = this.createMatrixIdentity();
|
41
|
+
this.mStack = [];
|
42
|
+
}
|
43
|
+
|
44
|
+
Space.prototype.createMatrixIdentity = function() {
|
45
|
+
return [
|
46
|
+
[1, 0, 0, 0],
|
47
|
+
[0, 1, 0, 0],
|
48
|
+
[0, 0, 1, 0],
|
49
|
+
[0, 0, 0, 1]
|
50
|
+
];
|
51
|
+
}
|
52
|
+
|
53
|
+
/**
|
54
|
+
* Multiplies two 4x4 matricies together.
|
55
|
+
*/
|
56
|
+
Space.prototype.matrixMultiply = function(m1, m2) {
|
57
|
+
var result = this.createMatrixIdentity();
|
58
|
+
|
59
|
+
var width = m1[0].length;
|
60
|
+
var height = m1.length;
|
61
|
+
|
62
|
+
if (width != m2.length) {
|
63
|
+
// error
|
64
|
+
}
|
65
|
+
|
66
|
+
for (var x = 0; x < width; x++) {
|
67
|
+
for (var y = 0; y < height; y++) {
|
68
|
+
var sum = 0;
|
69
|
+
|
70
|
+
for (var z = 0; z < width; z++) {
|
71
|
+
sum += m1[y][z] * m2[z][x];
|
72
|
+
}
|
73
|
+
|
74
|
+
result[y][x] = sum;
|
75
|
+
}
|
76
|
+
}
|
77
|
+
|
78
|
+
return result;
|
79
|
+
}
|
80
|
+
|
81
|
+
/**
|
82
|
+
* Transforms a coordinate using the current transformation
|
83
|
+
* matrix, then flattens it using the projection matrix.
|
84
|
+
*/
|
85
|
+
Space.prototype.flatten = function(point) {
|
86
|
+
var p = [[point.x, point.y, point.z, 1]];
|
87
|
+
var pm = this.matrixMultiply(p, this.m);
|
88
|
+
|
89
|
+
point.tx = pm[0][0];
|
90
|
+
point.ty = pm[0][1];
|
91
|
+
point.tz = pm[0][2];
|
92
|
+
|
93
|
+
// lazy projection
|
94
|
+
point.fx = halfCanvasWidth + (canvasWidth * point.tx / point.tz);
|
95
|
+
point.fy = halfCanvasHeight -(canvasWidth * point.ty / point.tz);
|
96
|
+
}
|
97
|
+
|
98
|
+
/**
|
99
|
+
* Translate (move) the current transformation matrix
|
100
|
+
*/
|
101
|
+
Space.prototype.translate = function(x, y, z) {
|
102
|
+
var m = [
|
103
|
+
[1, 0, 0, 0],
|
104
|
+
[0, 1, 0, 0],
|
105
|
+
[0, 0, 1, 0],
|
106
|
+
[x, y, z, 1]
|
107
|
+
];
|
108
|
+
|
109
|
+
this.m = this.matrixMultiply(m, this.m);
|
110
|
+
}
|
111
|
+
|
112
|
+
/**
|
113
|
+
* Rotate the current transformation matrix. Rotations are
|
114
|
+
* world-oriented, and occur in y,x,z order.
|
115
|
+
*/
|
116
|
+
Space.prototype.rotate = function(x, y, z) {
|
117
|
+
if (y) {
|
118
|
+
var cosY = Math.cos(y);
|
119
|
+
var sinY = Math.sin(y);
|
120
|
+
var rotY = [
|
121
|
+
[cosY, 0, sinY, 0],
|
122
|
+
[0, 1, 0, 0],
|
123
|
+
[-sinY, 0, cosY, 0],
|
124
|
+
[0, 0, 0, 1]
|
125
|
+
];
|
126
|
+
|
127
|
+
this.m = this.matrixMultiply(this.m, rotY);
|
128
|
+
}
|
129
|
+
|
130
|
+
if (x) {
|
131
|
+
var cosX = Math.cos(x);
|
132
|
+
var sinX = Math.sin(x);
|
133
|
+
var rotX = [
|
134
|
+
[1, 0, 0, 0],
|
135
|
+
[0, cosX, -sinX, 0],
|
136
|
+
[0, sinX, cosX,0],
|
137
|
+
[0, 0, 0, 1]
|
138
|
+
];
|
139
|
+
this.m = this.matrixMultiply(this.m, rotX);
|
140
|
+
}
|
141
|
+
|
142
|
+
if (z) {
|
143
|
+
var cosZ = Math.cos(z);
|
144
|
+
var sinZ = Math.sin(z);
|
145
|
+
var rotZ = [
|
146
|
+
[cosZ, -sinZ, 0, 0],
|
147
|
+
[sinZ, cosZ, 0, 0],
|
148
|
+
[0, 0, 1, 0],
|
149
|
+
[0, 0, 0, 1]
|
150
|
+
];
|
151
|
+
|
152
|
+
this.m = this.matrixMultiply(this.m, rotZ);
|
153
|
+
}
|
154
|
+
}
|
155
|
+
|
156
|
+
/**
|
157
|
+
* Pushes the current transformation onto the stack
|
158
|
+
*/
|
159
|
+
Space.prototype.push = function() {
|
160
|
+
this.mStack.push(this.m);
|
161
|
+
this.m = [
|
162
|
+
[this.m[0][0], this.m[0][1], this.m[0][2], this.m[0][3]],
|
163
|
+
[this.m[1][0], this.m[1][1], this.m[1][2], this.m[1][3]],
|
164
|
+
[this.m[2][0], this.m[2][1], this.m[2][2], this.m[2][3]],
|
165
|
+
[this.m[3][0], this.m[3][1], this.m[3][2], this.m[3][3]]
|
166
|
+
];
|
167
|
+
}
|
168
|
+
|
169
|
+
/**
|
170
|
+
* Pops the end off the transformation stack
|
171
|
+
*/
|
172
|
+
Space.prototype.pop = function() {
|
173
|
+
this.m = this.mStack.pop();
|
174
|
+
}
|
175
|
+
|
176
|
+
/* -------------------------------------------------------------------- */
|
177
|
+
|
178
|
+
/**
|
179
|
+
* A 3d coordinate
|
180
|
+
*/
|
181
|
+
function Point(x, y, z) {
|
182
|
+
this.x = x;
|
183
|
+
this.y = y;
|
184
|
+
this.z = z;
|
185
|
+
|
186
|
+
// Relative to camera coordinates
|
187
|
+
this.tx;
|
188
|
+
this.ty;
|
189
|
+
this.tz;
|
190
|
+
|
191
|
+
// Flattened coordinates
|
192
|
+
this.fx;
|
193
|
+
this.fy;
|
194
|
+
}
|
195
|
+
|
196
|
+
/**
|
197
|
+
* A Shape is made up of polygons
|
198
|
+
*/
|
199
|
+
function Shape() {
|
200
|
+
this.points = [];
|
201
|
+
this.polygons = [];
|
202
|
+
}
|
203
|
+
|
204
|
+
/**
|
205
|
+
* Draws the shape
|
206
|
+
*/
|
207
|
+
Shape.prototype.draw = function(drawlist) {
|
208
|
+
for (var i = 0; i< this.points.length; i++) {
|
209
|
+
space.flatten(this.points[i]);
|
210
|
+
}
|
211
|
+
|
212
|
+
for (var i = 0; i< this.polygons.length; i++) {
|
213
|
+
var poly = this.polygons[i]; // convenience
|
214
|
+
|
215
|
+
space.flatten(poly.origin);
|
216
|
+
|
217
|
+
// lazy backface culling
|
218
|
+
if (poly.normal && this.backface) {
|
219
|
+
space.flatten(poly.normal);
|
220
|
+
|
221
|
+
var originDist = Math.pow(poly.origin.tx, 2)
|
222
|
+
+ Math.pow(poly.origin.ty, 2)
|
223
|
+
+ Math.pow(poly.origin.tz, 2);
|
224
|
+
|
225
|
+
var normalDist = Math.pow(poly.normal.tx, 2)
|
226
|
+
+ Math.pow(poly.normal.ty, 2)
|
227
|
+
+ Math.pow(poly.normal.tz, 2);
|
228
|
+
|
229
|
+
if(originDist > normalDist) {
|
230
|
+
drawlist.push(poly);
|
231
|
+
}
|
232
|
+
} else {
|
233
|
+
drawlist.push(poly);
|
234
|
+
}
|
235
|
+
}
|
236
|
+
}
|
237
|
+
|
238
|
+
/**
|
239
|
+
* A polygon is a connection of points in the shape object. You
|
240
|
+
* should probably try to make them coplanar.
|
241
|
+
*/
|
242
|
+
function Polygon(points, normal, backface, type, color) {
|
243
|
+
this.points = points;
|
244
|
+
|
245
|
+
this.origin = new Point(0, 0, 0);
|
246
|
+
for(var i = 0; i < this.points.length; i++) {
|
247
|
+
this.origin.x += this.points[i].x;
|
248
|
+
this.origin.y += this.points[i].y;
|
249
|
+
this.origin.z += this.points[i].z;
|
250
|
+
}
|
251
|
+
|
252
|
+
this.origin.x /= this.points.length;
|
253
|
+
this.origin.y /= this.points.length;
|
254
|
+
this.origin.z /= this.points.length;
|
255
|
+
|
256
|
+
if (normal) {
|
257
|
+
this.normal = new Point(this.origin.x + normal.x,
|
258
|
+
this.origin.y + normal.y,
|
259
|
+
this.origin.z + normal.z);
|
260
|
+
} else {
|
261
|
+
this.normal = null;
|
262
|
+
}
|
263
|
+
|
264
|
+
this.backface = backface;
|
265
|
+
this.type = type;
|
266
|
+
this.color = color;
|
267
|
+
}
|
268
|
+
|
269
|
+
Polygon.SOLID = 0;
|
270
|
+
Polygon.WIRE = 1;
|
271
|
+
|
272
|
+
/**
|
273
|
+
* Draws the polygon. Assumes that the points have already been
|
274
|
+
* flattened.
|
275
|
+
*/
|
276
|
+
Polygon.prototype.draw = function() {
|
277
|
+
ctx.beginPath();
|
278
|
+
ctx.moveTo(this.points[0].fx, this.points[0].fy);
|
279
|
+
|
280
|
+
for(var i = 0; i < this.points.length; i++) {
|
281
|
+
ctx.lineTo(this.points[i].fx, this.points[i].fy);
|
282
|
+
}
|
283
|
+
|
284
|
+
ctx.closePath();
|
285
|
+
|
286
|
+
var color = this.color;
|
287
|
+
|
288
|
+
/*
|
289
|
+
// Do lighting here
|
290
|
+
lightvector = Math.abs(this.normal.x + this.normal.y);
|
291
|
+
if(lightvector > 1) {
|
292
|
+
lightvector = 1;
|
293
|
+
}
|
294
|
+
|
295
|
+
color[0] = (color[0] * lightvector).toString();
|
296
|
+
color[1] = (color[1] * lightvector).toString();
|
297
|
+
color[2] = (color[2] * lightvector).toString();
|
298
|
+
*/
|
299
|
+
|
300
|
+
if (color.length > 3) {
|
301
|
+
var style = ["rgba(",
|
302
|
+
color[0], ",",
|
303
|
+
color[1], ",",
|
304
|
+
color[2], ",",
|
305
|
+
color[3], ")"].join("");
|
306
|
+
} else {
|
307
|
+
var style = ["rgb(",
|
308
|
+
color[0], ",",
|
309
|
+
color[1], ",",
|
310
|
+
color[2], ")"].join("");
|
311
|
+
}
|
312
|
+
|
313
|
+
if (this.type == Polygon.SOLID) {
|
314
|
+
ctx.fillStyle = style;
|
315
|
+
ctx.fill();
|
316
|
+
} else if (this.type == Polygon.WIRE) {
|
317
|
+
ctx.strokeStyle = style;
|
318
|
+
ctx.stroke();
|
319
|
+
}
|
320
|
+
}
|
321
|
+
|
322
|
+
/* -------------------------------------------------------------------- */
|
323
|
+
|
324
|
+
/**
|
325
|
+
* Scene describes the 3D environment
|
326
|
+
*/
|
327
|
+
function Scene() {
|
328
|
+
this.shapes = {};
|
329
|
+
this.camera = new Point(0, 0, 0);
|
330
|
+
this.cameraTarget = new Point(0, 0, 0);
|
331
|
+
this.cameraRotation = 0;
|
332
|
+
|
333
|
+
this.drawlist = [];
|
334
|
+
}
|
335
|
+
|
336
|
+
/**
|
337
|
+
* Draw the world
|
338
|
+
*/
|
339
|
+
Scene.prototype.draw = function() {
|
340
|
+
space.push();
|
341
|
+
|
342
|
+
// Camera transformation
|
343
|
+
space.translate(
|
344
|
+
-this.camera.x,
|
345
|
+
-this.camera.y,
|
346
|
+
-this.camera.z
|
347
|
+
);
|
348
|
+
|
349
|
+
// Camera rotation
|
350
|
+
var xdiff = this.cameraTarget.x - this.camera.x;
|
351
|
+
var ydiff = this.cameraTarget.y - this.camera.y;
|
352
|
+
var zdiff = this.cameraTarget.z - this.camera.z;
|
353
|
+
|
354
|
+
var xzdist = Math.sqrt(Math.pow(xdiff, 2) + Math.pow(zdiff, 2));
|
355
|
+
|
356
|
+
var xrot = -Math.atan2(ydiff, xzdist); // up/down rotation
|
357
|
+
var yrot = Math.atan2(xdiff, zdiff); // left/right rotation
|
358
|
+
|
359
|
+
space.rotate(xrot, yrot, this.cameraRotation);
|
360
|
+
|
361
|
+
// Drawing
|
362
|
+
this.drawlist = [];
|
363
|
+
|
364
|
+
for(var i in this.shapes) {
|
365
|
+
this.shapes[i].draw(this.drawlist);
|
366
|
+
}
|
367
|
+
|
368
|
+
// Depth sorting (warning: this is only enough to drive this demo - feel
|
369
|
+
// free to contribute a better system).
|
370
|
+
this.drawlist.sort(function (poly1, poly2) {
|
371
|
+
return poly2.origin.tz - poly1.origin.tz;
|
372
|
+
});
|
373
|
+
|
374
|
+
for (var i = 0; i < this.drawlist.length; i++) {
|
375
|
+
this.drawlist[i].draw();
|
376
|
+
}
|
377
|
+
|
378
|
+
space.pop();
|
379
|
+
}
|
380
|
+
|
381
|
+
/* -------------------------------------------------------------------- */
|
382
|
+
|
383
|
+
var count = 0;
|
384
|
+
|
385
|
+
function loop() {
|
386
|
+
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
|
387
|
+
|
388
|
+
scene.camera.x = 70*Math.sin(count);
|
389
|
+
scene.camera.y = 70;
|
390
|
+
scene.camera.z = 70*Math.cos(count);
|
391
|
+
scene.cameraRotation = count / 10;
|
392
|
+
|
393
|
+
count += 0.01;
|
394
|
+
scene.draw();
|
395
|
+
}
|
396
|
+
|
397
|
+
function load() {
|
398
|
+
// Init drawing system
|
399
|
+
canvas = document.getElementById("cv");
|
400
|
+
ctx = canvas.getContext("2d");
|
401
|
+
|
402
|
+
canvasWidth = canvas.width;
|
403
|
+
canvasHeight = canvas.height;
|
404
|
+
halfCanvasWidth = canvasWidth * 0.5;
|
405
|
+
halfCanvasHeight = canvasHeight * 0.5;
|
406
|
+
|
407
|
+
// Init 3D components
|
408
|
+
space = new Space();
|
409
|
+
scene = new Scene();
|
410
|
+
|
411
|
+
// Create a box shape and add it to the scene
|
412
|
+
scene.shapes['box'] = new Shape();
|
413
|
+
var p = scene.shapes['box'].points; // for convenience
|
414
|
+
|
415
|
+
p[0] = new Point(-10, -10, -10); // left bottom front
|
416
|
+
p[1] = new Point(10, -10, -10); // right bottom front
|
417
|
+
p[2] = new Point(10, 10, -10); // right top front
|
418
|
+
p[3] = new Point(-10, 10, -10); // left top front
|
419
|
+
|
420
|
+
p[4] = new Point(-10, -10, 10); // left bottom back
|
421
|
+
p[5] = new Point(10, -10, 10); // right bottom back
|
422
|
+
p[6] = new Point(10, 10, 10); // right top back
|
423
|
+
p[7] = new Point(-10, 10, 10); // left top back
|
424
|
+
|
425
|
+
// Back
|
426
|
+
scene.shapes['box'].polygons.push(new Polygon(
|
427
|
+
[ p[0], p[1], p[2], p[3] ],
|
428
|
+
new Point(0, 0, -1),
|
429
|
+
true /* double-sided */,
|
430
|
+
Polygon.SOLID,
|
431
|
+
[255, 0, 0]
|
432
|
+
));
|
433
|
+
|
434
|
+
// Front
|
435
|
+
scene.shapes['box'].polygons.push(new Polygon(
|
436
|
+
[ p[4], p[5], p[6], p[7] ],
|
437
|
+
new Point(0, 0, 1),
|
438
|
+
true /* double-sided */,
|
439
|
+
Polygon.SOLID,
|
440
|
+
[0, 0, 255]
|
441
|
+
));
|
442
|
+
|
443
|
+
// Top
|
444
|
+
scene.shapes['box'].polygons.push(new Polygon(
|
445
|
+
[ p[2], p[3], p[7], p[6] ],
|
446
|
+
new Point(0, 1, 0),
|
447
|
+
false /* single-sided */,
|
448
|
+
Polygon.WIRE,
|
449
|
+
[0, 255, 0]
|
450
|
+
));
|
451
|
+
|
452
|
+
// Transparent Top
|
453
|
+
scene.shapes['box'].polygons.push(new Polygon(
|
454
|
+
[ p[2], p[3], p[7], p[6] ],
|
455
|
+
new Point(0, 1, 0),
|
456
|
+
false /* single-sided */,
|
457
|
+
Polygon.SOLID,
|
458
|
+
[0, 255, 0, 0.4]
|
459
|
+
));
|
460
|
+
|
461
|
+
// Left
|
462
|
+
scene.shapes['box'].polygons.push(new Polygon(
|
463
|
+
[ p[0], p[4], p[7], p[3] ],
|
464
|
+
new Point(-1, 0, 0),
|
465
|
+
true /* double-sided */,
|
466
|
+
Polygon.SOLID,
|
467
|
+
[255, 255, 0]
|
468
|
+
));
|
469
|
+
|
470
|
+
// Right
|
471
|
+
scene.shapes['box'].polygons.push(new Polygon(
|
472
|
+
[ p[1], p[5], p[6], p[2] ],
|
473
|
+
new Point(1, 0, 0),
|
474
|
+
true /* double-sided */,
|
475
|
+
Polygon.SOLID,
|
476
|
+
[0, 255, 255]
|
477
|
+
));
|
478
|
+
|
479
|
+
// Create a floor shape and add it to the scene
|
480
|
+
scene.shapes['floor'] = new Shape();
|
481
|
+
var p = scene.shapes['floor'].points; // for convenience
|
482
|
+
|
483
|
+
p[0] = new Point(-40, -10, -40);
|
484
|
+
p[1] = new Point(-40, -10, 40);
|
485
|
+
p[2] = new Point( 40, -10, 40);
|
486
|
+
p[3] = new Point( 40, -10, -40);
|
487
|
+
|
488
|
+
// Floor
|
489
|
+
scene.shapes['floor'].polygons.push(new Polygon(
|
490
|
+
[ p[0], p[1], p[2], p[3] ],
|
491
|
+
new Point(0, 1, 0),
|
492
|
+
false /* single-sided */,
|
493
|
+
Polygon.SOLID,
|
494
|
+
[45, 45, 45]
|
495
|
+
));
|
496
|
+
|
497
|
+
setInterval('loop()', 20);
|
498
|
+
}
|
499
|
+
|
500
|
+
/* -------------------------------------------------------------------- */
|
501
|
+
</script>
|
502
|
+
<style>
|
503
|
+
body {
|
504
|
+
background-color:black;
|
505
|
+
margin:50px;
|
506
|
+
text-align:center;
|
507
|
+
}
|
508
|
+
</style>
|
509
|
+
</head>
|
510
|
+
<body onload="load();">
|
511
|
+
<canvas id="cv" width="400" height="300"></canvas>
|
512
|
+
</body>
|
513
|
+
</html>
|