このファイル: /home/web6047/www/cgi-bin/prj/20190923-indexJS/b.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
app = {
16
uid : Date.now(),
17
18
19
onload : function( e ) {
20
console.log( this.uid, "onload" );
21
22
23
this.timerID = null;
24
this.timerMS = 100;
25
var canvasElement = document.createElement( "canvas" );
26
canvasElement.id = "canvas" + this.uid;
27
this.p = document.getElementById( "whiteareaID" );
28
this.p.appendChild( canvasElement );
29
this.cc = document.getElementById( canvasElement.id ).getContext( "2d" );
30
31
32
33
34
35
36
this.vars = {
37
stars : new Array(),
38
maxStars : 1000,
39
colors : [ "blue", "red", "magenta", "lightgreen", "cyan", "yellow", "white" ],
40
41
cam : {
42
s : 100,
43
rotationX : 0,
44
rotationY : 0,
45
rotationZ : 0,
46
},
47
counter : 0,
48
times : 0,
49
step : 100,
50
info : false,
51
message : "テスト",
52
}
53
54
55
var app = this;
56
this.cc.canvas.onclick = function() {
57
app.vars.info = !app.vars.info;
58
}
59
60
this.pixel = 1;
61
if( 1 ) {
62
this.cc.canvas.style.imageRendering = "pixelated";
63
this.cc.canvas.style.imageRendering = "optimizeSpeed";
64
}
65
66
this.onresize();
67
68
69
for( var i = 0; i < this.vars.maxStars; i++ ) {
70
var star = new Star( this );
71
star.x = Math.random() * this.vars.lenX + this.vars.minX;
72
star.y = Math.random() * this.vars.lenY + this.vars.minY;
73
star.z = Math.random() * this.vars.lenZ + this.vars.minZ;
74
this.vars.stars.push( star );
75
}
76
77
addEventListener( "resize", app.onresize.bind( app ), false );
78
addEventListener( "scroll", app.onscroll.bind( app ), false );
79
80
81
82
83
84
},
85
86
87
onresize : function( e ) {
88
var canvasElement = this.cc.canvas;
89
var h2;
90
91
for( var i = 0; i < this.p.children.length; i++ ) {
92
var child = this.p.children[ i ];
93
if( child.tagName == "H2" ) {
94
h2 = child;
95
break;
96
}
97
}
98
99
100
var pr = this.p.getBoundingClientRect();
101
var w = pr.width;
102
var h = h2.offsetTop;
103
with( canvasElement.style ) {
104
position = "absolute";
105
left = "0px";
106
top = "0px";
107
width = w + "px";
108
height = h + "px";
109
zIndex = -2;
110
backgroundColor = "black";
111
}
112
113
114
this.cc.canvas.width = w / this.pixel;
115
this.cc.canvas.height = h / this.pixel;
116
117
118
this.vars.maxH = this.cc.canvas.width / 2;
119
this.vars.minH = -this.cc.canvas.width / 2;
120
this.vars.maxV = this.cc.canvas.height / 2;
121
this.vars.minV = -this.cc.canvas.height / 2;
122
123
124
this.vars.len = 4000;
125
this.vars.lenX = this.vars.len;
126
this.vars.lenY = this.vars.len;
127
this.vars.lenZ = this.vars.len;
128
this.vars.maxX = this.vars.len / 2;
129
this.vars.minX = -this.vars.len / 2;
130
this.vars.maxY = this.vars.len / 2;
131
this.vars.minY = -this.vars.len / 2;
132
this.vars.maxZ = this.vars.len / 2;
133
this.vars.minZ = -this.vars.len / 2;
134
135
136
this.draw( this.cc );
137
this.onscroll();
138
139
},
140
141
142
143
draw : function( cc ) {
144
cc.clearRect( 0, 0, cc.canvas.width, cc.canvas.height );
145
cc.save();
146
cc.translate( cc.canvas.width / 2, cc.canvas.height /2 );
147
148
for( var i = 0; i < this.vars.stars.length; i++ ) {
149
var star = this.vars.stars[ i ];
150
151
var isOver = star.cz <= 0
152
|| star.h < this.vars.minH
153
|| star.h > this.vars.maxH
154
|| star.v < this.vars.minV
155
|| star.v > this.vars.maxV;
156
if( isOver ) continue;
157
158
star.draw( cc );
159
}
160
cc.restore();
161
162
163
cc.font = "32px ''";
164
cc.fillStyle = "white";
165
var x = ( cc.canvas.width - cc.measureText( this.vars.message ).width ) / 2;
166
cc.fillText( this.vars.message, x, cc.canvas.height - 8 );
167
168
169
if( this.vars.info ) {
170
var fs = 12;
171
var ly = 1;
172
var lx = 0;
173
var tab = 130;
174
cc.font = fs + "px ''";
175
cc.fillStyle = "cyan";
176
cc.fillText( "num of stars: " + this.vars.stars.length, lx * tab, ly++ * fs );
177
cc.fillText( "time: " + this.vars.times / 1000, lx * tab, ly++ * fs );
178
cc.fillText( "anm seek: " + this.anmseek, lx * tab, ly++ * fs );
179
lx ++; ly = 1;
180
cc.fillText( "rotationX: " + Math.round( this.vars.cam.rotationX * 1000 ) / 1000, lx * tab, ly++ * fs );
181
cc.fillText( "rotationY: " + Math.round( this.vars.cam.rotationY * 1000 ) / 1000, lx * tab, ly++ * fs );
182
cc.fillText( "rotationZ: " + Math.round( this.vars.cam.rotationZ * 1000 ) / 1000, lx * tab, ly++ * fs );
183
lx ++; ly = 1;
184
cc.fillText( "speed: " + this.vars.step, lx * tab, ly++ * fs );
185
}
186
},
187
188
189
190
onscroll : function( e ) {
191
192
193
var rect = this.cc.canvas.getBoundingClientRect();
194
var canvasTop = rect.top;
195
var canvasBottom = rect.top + rect.height;
196
var windowBottom = window.innerHeight;
197
var overTheTop = canvasBottom - 200 < 0;
198
var overTheBottom = canvasTop + 200 > windowBottom;
199
var isVisible = !overTheTop && !overTheBottom;
200
if( this.timerID && !isVisible ) this.stop();
201
else if( !this.timerID && isVisible ) this.start();
202
},
203
204
205
start : function() {
206
console.log( this.uid, "start" );
207
this.timerID = setInterval( this.frame.bind( this ), this.timerMS );
208
209
},
210
211
212
stop : function() {
213
console.log( this.uid, "stop" );
214
clearInterval( this.timerID );
215
this.timerID = 0;
216
},
217
218
219
220
221
222
223
anmseek : 0,
224
anms : [
225
{
226
227
times : 0,
228
frame : function( app ) {
229
app.vars.message = "イースみたいな星空";
230
if( ( this.times += app.timerMS ) >= 5000 ) {
231
this.times = 0;
232
app.anmseek++;
233
}
234
},
235
},
236
{
237
238
frame : function( app ) {
239
app.vars.step --;
240
if( app.vars.step < 50 ) {
241
app.vars.message = "でも、止まっ… ";
242
}
243
if( app.vars.step == 0 ) {
244
app.vars.message = "でも、止まっ…た";
245
app.anmseek++;
246
}
247
248
}
249
},
250
{
251
252
times : 0,
253
frame : function( app ) {
254
if( ( this.times += app.timerMS ) >= 2000 ) {
255
this.times = 0;
256
app.anmseek++;
257
}
258
},
259
},
260
{
261
262
endValue : 0,
263
frame : function( app ) {
264
app.vars.message = "ぐるっと回転しまして…";
265
266
if( this.endValue == 0 ) {
267
this.endValue = app.vars.cam.rotationY + Math.PI;
268
}
269
value = 0.05;
270
app.vars.cam.rotationY += value;
271
272
if( app.vars.cam.rotationY >= this.endValue ) {
273
app.vars.cam.rotationY = this.endValue;
274
app.anmseek++;
275
this.endValue = 0;
276
}
277
},
278
},
279
{
280
281
times : 0,
282
frame : function( app ) {
283
if( ( this.times += app.timerMS ) >= 2000 ) {
284
this.times = 0;
285
app.anmseek++;
286
}
287
},
288
},
289
{
290
291
frame : function( app ) {
292
app.vars.message = "リバース";
293
app.vars.step ++;
294
if( app.vars.step == 100 ) {
295
app.anmseek++;
296
}
297
298
}
299
},
300
{
301
302
endValue : 0,
303
frame : function( app ) {
304
app.vars.message = "そのまま、ぐるっと回転しまして…";
305
306
if( this.endValue == 0 ) {
307
this.endValue = app.vars.cam.rotationY + Math.PI / 2;
308
}
309
value = 0.05;
310
app.vars.cam.rotationY += value;
311
312
if( app.vars.cam.rotationY >= this.endValue ) {
313
app.vars.cam.rotationY = this.endValue;
314
app.anmseek++;
315
this.endValue = 0;
316
}
317
},
318
},
319
{
320
321
times : 0,
322
frame : function( app ) {
323
app.vars.message = "横に流れています…";
324
if( ( this.times += app.timerMS ) >= 2000 ) {
325
this.times = 0;
326
app.anmseek++;
327
}
328
},
329
},
330
{
331
332
frame : function( app ) {
333
app.vars.step --;
334
if( app.vars.step == 0 ) {
335
app.anmseek++;
336
}
337
338
}
339
},
340
{
341
342
times : 0,
343
frame : function( app ) {
344
app.vars.message = "";
345
if( ( this.times += app.timerMS ) >= 2000 ) {
346
this.times = 0;
347
app.anmseek++;
348
}
349
},
350
},
351
{
352
353
endValue : 0,
354
frame : function( app ) {
355
app.vars.message = "ぐるぐるぐる";
356
357
if( this.endValue == 0 ) {
358
this.endValue = app.vars.cam.rotationZ + Math.PI * 2;
359
}
360
value = 0.05;
361
app.vars.cam.rotationZ += value;
362
363
if( app.vars.cam.rotationZ >= this.endValue ) {
364
app.vars.cam.rotationZ = 0;
365
app.anmseek++;
366
this.endValue = 0;
367
}
368
},
369
},
370
{
371
372
times : 0,
373
frame : function( app ) {
374
app.vars.message = "";
375
if( ( this.times += app.timerMS ) >= 2000 ) {
376
this.times = 0;
377
app.anmseek++;
378
}
379
},
380
},
381
{
382
383
endValue : 0,
384
frame : function( app ) {
385
app.vars.message = "ぐるっと回転しまして…";
386
387
if( this.endValue == 0 ) {
388
this.endValue = app.vars.cam.rotationY + Math.PI / 2;
389
}
390
value = 0.05;
391
app.vars.cam.rotationY += value;
392
393
if( app.vars.cam.rotationY >= this.endValue ) {
394
app.vars.cam.rotationY = 0;
395
app.anmseek++;
396
this.endValue = 0;
397
}
398
},
399
},
400
{
401
402
times : 0,
403
frame : function( app ) {
404
if( ( this.times += app.timerMS ) >= 2000 ) {
405
this.times = 0;
406
app.anmseek++;
407
}
408
},
409
},
410
{
411
412
frame : function( app ) {
413
app.vars.message = "くりかえし";
414
app.vars.step ++;
415
if( app.vars.step > 50 ) {
416
app.vars.message = "(ちなみに上のほうクリックでデータ表示)";
417
}
418
if( app.vars.step == 100 ) {
419
app.anmseek++;
420
}
421
422
}
423
},
424
425
],
426
427
428
frame : function() {
429
430
this.vars.times = this.timerMS * this.vars.counter;
431
var times = this.vars.times;
432
this.anms[ this.anmseek ].frame( this );
433
434
if( this.anmseek == this.anms.length ) {
435
this.anmseek = 0;
436
this.vars.counter = 0;
437
this.vars.times = 0;
438
}
439
440
441
for( var i = this.vars.stars.length; i < this.vars.maxStars; i++ ) {
442
var star = new Star( this );
443
star.x = Math.random() * this.vars.lenX + this.vars.minX;
444
star.y = Math.random() * this.vars.lenY + this.vars.minY;
445
star.z = this.vars.maxZ;
446
this.vars.stars.push( star );
447
}
448
449
450
for( var i = 0; i < this.vars.stars.length; i++ ) {
451
var star = this.vars.stars[ i ];
452
star.frame();
453
454
if( star.z < this.vars.minZ ) {
455
this.vars.stars.splice( i, 1 );
456
i--;
457
continue;
458
}
459
460
461
star.cx = star.x;
462
star.cy = star.y;
463
star.cz = star.z;
464
465
466
var k = kaiten( star.cx, star.cz, this.vars.cam.rotationY );
467
star.cx = k.X;
468
star.cz = k.Y;
469
470
471
var k = kaiten( star.cx, star.cy, this.vars.cam.rotationZ );
472
star.cx = k.X;
473
star.cy = k.Y;
474
475
476
star.h = star.cx * ( this.vars.cam.s / star.cz );
477
star.v = star.cy * ( this.vars.cam.s / star.cz );
478
479
480
star.h *= 5.25;
481
star.v *= 5.25;
482
483
}
484
485
this.draw( this.cc );
486
487
this.vars.counter ++;
488
},
489
490
};
491
492
function kaiten( x, y, theta2 ) {
493
494
var hankei = Math.sqrt( x * x + y * y );
495
var theta1 = Math.atan2( y, x );
496
var kaitenX = Math.cos( theta1 + theta2 ) * hankei;
497
var kaitenY = Math.sin( theta1 + theta2 ) * hankei;
498
return {
499
X : kaitenX,
500
Y : kaitenY,
501
};
502
}
503
504
function Star( app ) {
505
506
this.app = app;
507
this.x = 0;
508
this.y = 0;
509
this.z = 0;
510
this.cx = 0;
511
this.cy = 0;
512
this.cz = 0;
513
this.color = this.app.vars.colors[ Math.floor( Math.random() * this.app.vars.colors.length ) ];
514
}
515
Star.prototype.frame = function() {
516
517
var len = this.app.vars.step;
518
this.z -= len;
519
}
520
Star.prototype.draw = function( cc ) {
521
522
cc.fillStyle = this.color;
523
cc.fillRect( this.h, this.v, 2, 2 );
524
}
525
526
527
addEventListener( "load", app.onload.bind( app ), false );
528
529