HTMLcopy
1
<div id="container"></div>
CSScopy
8
1
html,
2
body,
3
#container {
4
width: 100%;
5
height: 100%;
6
margin: 0;
7
padding: 0;
8
}
JavaScriptcopy
x
1
var starsPath;
2
var flag = 0;
3
4
/**
5
* Array of points.
6
* @type {Array.<Point3D>}
7
*/
8
var stars = [];
9
10
/**
11
* Focus length.
12
* @type {number}
13
*/
14
var FOCUS_LENGTH = 50;
15
16
/**
17
* FAV multiplier.
18
* @type {number}
19
*/
20
var FAV = 500;
21
22
var xAxisLength = 0;
23
var yAxisLength = 0;
24
var zAxisLength = 0;
25
26
var xAxisPath;
27
var yAxisPath;
28
var zAxisPath;
29
30
var xAxis;
31
var yAxis;
32
var zAxis;
33
34
var DEPTH = 2000;
35
36
var STARS_STEP = 1;
37
38
var axisOpacity = 0.8;
39
40
var xRotation = 0.1;
41
var yRotation = 0.2;
42
43
var prevX = NaN;
44
var prevY = NaN;
45
46
//--------------------------------------------------------------------------------------------------------------
47
//
48
// Point class.
49
//
50
//--------------------------------------------------------------------------------------------------------------
51
/**
52
* Point class.
53
* @param x
54
* @param y
55
* @param z
56
* @constructor
57
*/
58
var Point3D = function (x, y, z) {
59
this.x = x;
60
this.y = y;
61
this.z = z;
62
};
63
64
/**
65
* Rotates point in 3D by X.
66
* @param {number} angle - Degrees.
67
*/
68
Point3D.prototype.rotateX3D = function (angle) {
69
angle = degToRads(angle);
70
var sin = Math.sin(angle);
71
var cos = Math.cos(angle);
72
var y = this.y;
73
var z = this.z;
74
this.y = y * cos - z * sin;
75
this.z = z * cos + y * sin;
76
};
77
78
/**
79
* Rotates point in 3D by Y.
80
* @param {number} angle - Degrees.
81
*/
82
Point3D.prototype.rotateY3D = function (angle) {
83
angle = degToRads(angle);
84
var sin = Math.sin(angle);
85
var cos = Math.cos(angle);
86
var x = this.x;
87
var z = this.z;
88
this.x = x * cos - z * sin;
89
this.z = z * cos + x * sin;
90
};
91
92
/**
93
* Rotates point in 3D by Z.
94
* @param {number} angle - Degrees.
95
*/
96
Point3D.prototype.rotateZ3D = function (angle) {
97
angle = degToRads(angle);
98
var sin = Math.sin(angle);
99
var cos = Math.cos(angle);
100
var x = this.x;
101
var y = this.y;
102
this.x = x * cos - y * sin;
103
this.y = y * cos + x * sin;
104
};
105
106
/**
107
* Turns point to screen coordinate.
108
* @returns {anychart.graphics.math.Coordinate}
109
*/
110
Point3D.prototype.get2DPoint = function () {
111
var x = getScreenCoordinate(this.x, this.z);
112
var y = getScreenCoordinate(this.y, this.z);
113
return acgraph.math.coordinate(x, y);
114
};
115
116
//--------------------------------------------------------------------------------------------------------------
117
//
118
// Utils.
119
//
120
//--------------------------------------------------------------------------------------------------------------
121
/**
122
* Gets screen coordinate.
123
* @param {number} coordinate - Dimension coordinate.
124
* @param {number} z - Depth coordinate.
125
* @return {number}
126
*/
127
var getScreenCoordinate = function (coordinate, z) {
128
return (coordinate * FAV) / (z + FOCUS_LENGTH + DEPTH);
129
};
130
131
/**
132
* Turns degrees to radians.
133
* @param degrees
134
* @return {number}
135
*/
136
var degToRads = function (degrees) {
137
return degrees * (Math.PI / 180);
138
};
139
140
/**
141
* Generates random number in range.
142
* @param val
143
* @return {number}
144
*/
145
function plusMinusRandom(val) {
146
return val - 2 * val * Math.random();
147
}
148
149
/**
150
* Generates stars data.
151
*/
152
function generateStars() {
153
var w = 150;
154
var h = 100;
155
var d = w;
156
157
var xDelta = 0.7 * w;
158
var yDelta = 0.7 * h;
159
var zDelta = 0.7 * d;
160
161
var maxXRad = Math.PI * 2;
162
163
var radStep = degToRads(STARS_STEP);
164
var ang = 0.0001;
165
166
var numberOfPointOnStep = 7;
167
168
while (ang <= maxXRad) {
169
var progress = Math.max(0.2, 1 - ang / maxXRad);
170
171
var x1 = w * ang * Math.cos(ang);
172
var y1 = h * ang * Math.sin(ang);
173
var x2 = -x1;
174
var y2 = -y1;
175
176
var z1 = plusMinusRandom(d);
177
var z2 = plusMinusRandom(d);
178
179
for (var i = 0; i < numberOfPointOnStep; i++) {
180
var x1Rand = x1 + plusMinusRandom(xDelta);
181
var y1Rand = y1 + plusMinusRandom(yDelta);
182
var z1Rand = z1 + plusMinusRandom(zDelta);
183
184
var x2Rand = x2 + plusMinusRandom(xDelta);
185
var y2Rand = y2 + plusMinusRandom(yDelta);
186
var z2Rand = z2 + plusMinusRandom(zDelta);
187
188
stars.push(new Point3D(x1Rand, y1Rand, z1Rand * progress));
189
stars.push(new Point3D(x2Rand, y2Rand, z2Rand * progress));
190
}
191
192
ang += radStep;
193
radStep *= 1.02;
194
}
195
}
196
197
/**
198
* Draws axes.
199
*/
200
function drawAxes() {
201
stage.suspend();
202
var bounds = stage.getBounds();
203
var centerX = Math.round(bounds.width / 2);
204
var centerY = Math.round(bounds.height / 2);
205
var addX = centerX;
206
var addY = centerY;
207
208
var xAxisFromCoord = xAxis.fromPoint.get2DPoint();
209
var xAxisToCoord = xAxis.toPoint.get2DPoint();
210
xAxisPath
211
.clear()
212
.moveTo(xAxisFromCoord.x + addX, xAxisFromCoord.y + addY)
213
.lineTo(xAxisToCoord.x + addX, xAxisToCoord.y + addY);
214
215
var yAxisFromCoord = yAxis.fromPoint.get2DPoint();
216
var yAxisToCoord = yAxis.toPoint.get2DPoint();
217
yAxisPath
218
.clear()
219
.moveTo(yAxisFromCoord.x + addX, yAxisFromCoord.y + addY)
220
.lineTo(yAxisToCoord.x + addX, yAxisToCoord.y + addY);
221
222
var zAxisFromCoord = zAxis.fromPoint.get2DPoint();
223
var zAxisToCoord = zAxis.toPoint.get2DPoint();
224
zAxisPath
225
.clear()
226
.moveTo(zAxisFromCoord.x + addX, zAxisFromCoord.y + addY)
227
.lineTo(zAxisToCoord.x + addX, zAxisToCoord.y + addY);
228
229
starsPath.clear();
230
for (var i = 0; i < stars.length; i++) {
231
var star = stars[i];
232
var startScreenCoords = star.get2DPoint();
233
starsPath
234
.moveTo(startScreenCoords.x + addX, startScreenCoords.y + addY)
235
.lineTo(
236
startScreenCoords.x + addX + 1,
237
startScreenCoords.y + addY + 1
238
);
239
}
240
241
stage.resume();
242
}
243
244
/**
245
* Calculates rotation of stars.
246
* @param xAngle
247
* @param yAngle
248
* @param zAngle
249
*/
250
function rotateStars(xAngle, yAngle, zAngle) {
251
xAngle = xAngle || 0;
252
yAngle = yAngle || 0;
253
zAngle = zAngle || 0;
254
255
for (var i = 0; i < stars.length; i++) {
256
var star = stars[i];
257
star.rotateX3D(xAngle);
258
star.rotateY3D(yAngle);
259
star.rotateZ3D(zAngle);
260
}
261
}
262
263
/**
264
* Axis class.
265
* @param fromX
266
* @param toX
267
* @param fromY
268
* @param toY
269
* @param fromZ
270
* @param toZ
271
* @constructor
272
*/
273
var Axis = function (fromX, toX, fromY, toY, fromZ, toZ) {
274
this.fromPoint = new Point3D(fromX, fromY, fromZ);
275
this.toPoint = new Point3D(toX, toY, toZ);
276
};
277
278
/**
279
* Rotates axes in 3D by X.
280
* @param angle
281
*/
282
Axis.prototype.rotateX3D = function (angle) {
283
this.fromPoint.rotateX3D(angle);
284
this.toPoint.rotateX3D(angle);
285
};
286
287
/**
288
* Rotates axes in 3D by Y.
289
* @param angle
290
*/
291
Axis.prototype.rotateY3D = function (angle) {
292
this.fromPoint.rotateY3D(angle);
293
this.toPoint.rotateY3D(angle);
294
};
295
296
/**
297
* Rotates axes in 3D by Z.
298
* @param angle
299
*/
300
Axis.prototype.rotateZ3D = function (angle) {
301
this.fromPoint.rotateZ3D(angle);
302
this.toPoint.rotateZ3D(angle);
303
};
304
305
var cont = document.getElementById('container');
306
cont.style.backgroundColor = '#000';
307
var stage = acgraph.create('container');
308
309
generateStars();
310
311
// x - green
312
xAxisPath = stage.path().stroke([
313
{ color: '#afa', opacity: 0 },
314
{
315
color: '#afa',
316
opacity: axisOpacity
317
},
318
{ color: '#afa', opacity: 0 }
319
]);
320
// y - red
321
yAxisPath = stage.path().stroke([
322
{ color: '#faa', opacity: 0 },
323
{
324
color: '#faa',
325
opacity: axisOpacity
326
},
327
{ color: '#faa', opacity: 0 }
328
]);
329
// z - blue
330
zAxisPath = stage.path().stroke([
331
{ color: '#aaf', opacity: 0 },
332
{
333
color: '#aaf',
334
opacity: axisOpacity
335
},
336
{ color: '#aaf', opacity: 0 }
337
]);
338
339
starsPath = stage.path().stroke({ color: '#fff', opacity: 0.7 });
340
341
var bounds = stage.getBounds();
342
343
xAxisLength = Math.round(bounds.width);
344
zAxisLength = xAxisLength;
345
yAxisLength = Math.round(bounds.height);
346
347
xAxis = new Axis();
348
xAxis.fromPoint.x = Math.round(xAxisLength / 2);
349
xAxis.toPoint.x = -xAxis.fromPoint.x;
350
xAxis.fromPoint.y = 0;
351
xAxis.toPoint.y = 0;
352
xAxis.fromPoint.z = 0;
353
xAxis.toPoint.z = 0;
354
355
yAxis = new Axis();
356
yAxis.fromPoint.x = 0;
357
yAxis.toPoint.x = 0;
358
yAxis.fromPoint.y = Math.round(yAxisLength / 2);
359
yAxis.toPoint.y = -yAxis.fromPoint.y;
360
yAxis.fromPoint.z = 0;
361
yAxis.toPoint.z = 0;
362
363
zAxis = new Axis();
364
zAxis.fromPoint.x = 0;
365
zAxis.toPoint.x = 0;
366
zAxis.fromPoint.y = 0;
367
zAxis.toPoint.y = 0;
368
zAxis.fromPoint.z = Math.round(zAxisLength / 2);
369
zAxis.toPoint.z = -zAxis.fromPoint.z;
370
371
window.requestAnimationFrame =
372
window.requestAnimationFrame ||
373
window.webkitRequestAnimationFrame ||
374
window.mozRequestAnimationFrame ||
375
window.oRequestAnimationFrame ||
376
window.msRequestAnimationFrame ||
377
function (callback) {
378
setTimeout(callback, 1000 / 60);
379
};
380
381
cont.addEventListener('mousedown', function () {
382
flag = 1;
383
});
384
cont.addEventListener('mousemove', function () {
385
if (flag === 1) {
386
cont.addEventListener('mousemove', galaxyMove);
387
}
388
});
389
cont.addEventListener('mouseup', function () {
390
flag = 0;
391
cont.removeEventListener('mousemove', galaxyMove);
392
});
393
394
function galaxyMove(e) {
395
prevX = isNaN(prevX) ? e.clientX : prevX;
396
prevY = isNaN(prevY) ? e.clientY : prevY;
397
398
yRotation = e.clientX - prevX;
399
xRotation = e.clientY - prevY;
400
401
prevX = e.clientX;
402
prevY = e.clientY;
403
}
404
405
drawAxes();
406
draw();
407
408
/**
409
* Draws.
410
*/
411
function draw() {
412
window.requestAnimationFrame(draw);
413
414
xAxis.rotateX3D(xRotation);
415
xAxis.rotateY3D(yRotation);
416
// xAxis.rotateZ3D(zRot);
417
418
yAxis.rotateX3D(xRotation);
419
yAxis.rotateY3D(yRotation);
420
// yAxis.rotateZ3D(zRot);
421
422
zAxis.rotateX3D(xRotation);
423
zAxis.rotateY3D(yRotation);
424
// zAxis.rotateZ3D(zRot);
425
426
rotateStars(xRotation, yRotation, 0);
427
428
drawAxes();
429
}