2014-07-25 08:37:41 +02:00
|
|
|
(function(
|
|
|
|
Base,
|
|
|
|
Vector,
|
|
|
|
Logo,
|
2014-07-25 09:04:54 +02:00
|
|
|
Shapes,
|
2014-07-25 12:09:17 +02:00
|
|
|
Grid,
|
2014-07-25 08:37:41 +02:00
|
|
|
Chainable
|
|
|
|
){
|
2014-07-24 05:35:57 +02:00
|
|
|
|
|
|
|
var sqrt, pow, Engine;
|
|
|
|
|
|
|
|
if (!window.requestAnimationFrame) {
|
|
|
|
window.requestAnimationFrame = (function(){
|
|
|
|
return window.requestAnimationFrame ||
|
|
|
|
window.webkitRequestAnimationFrame ||
|
|
|
|
window.mozRequestAnimationFrame ||
|
|
|
|
function( callback ){
|
|
|
|
window.setTimeout(callback, 1000 / 60);
|
|
|
|
};
|
|
|
|
})();
|
|
|
|
}
|
|
|
|
|
|
|
|
sqrt = Math.sqrt;
|
|
|
|
pow = Math.pow;
|
|
|
|
|
|
|
|
Engine = Base.extend({
|
|
|
|
|
|
|
|
scale: window.devicePixelRatio || 1,
|
|
|
|
// scale:1,
|
|
|
|
|
2014-07-26 08:09:04 +02:00
|
|
|
shapes : [],
|
|
|
|
particles : [],
|
|
|
|
particlesA : [],
|
|
|
|
particlesB : [],
|
2014-07-24 05:35:57 +02:00
|
|
|
|
2014-07-24 09:46:14 +02:00
|
|
|
_deferredParticles: [],
|
2014-07-26 08:09:04 +02:00
|
|
|
|
|
|
|
ticks: [],
|
2014-07-24 05:35:57 +02:00
|
|
|
|
2014-07-25 12:09:17 +02:00
|
|
|
starGeneratorRate: 600,
|
|
|
|
|
|
|
|
mouse: {
|
|
|
|
x: -9999,
|
|
|
|
y: -9999
|
|
|
|
},
|
|
|
|
|
2014-07-25 08:37:41 +02:00
|
|
|
constructor: function(canvas, image){
|
2014-07-24 05:35:57 +02:00
|
|
|
if (typeof canvas === 'string') {
|
|
|
|
this.canvas = document.getElementById(canvas);
|
|
|
|
} else {
|
|
|
|
this.canvas = canvas;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!this.canvas.getContext) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.context = this.canvas.getContext('2d');
|
|
|
|
|
|
|
|
this.resize = this.resize.bind(this);
|
|
|
|
this.resize();
|
|
|
|
window.addEventListener('resize', this.resize, false);
|
|
|
|
|
2014-07-26 09:11:43 +02:00
|
|
|
this._handleScroll = this._handleScroll.bind(this);
|
|
|
|
this._handleScroll();
|
|
|
|
window.addEventListener('scroll', this._handleScroll, false);
|
|
|
|
|
2014-07-25 08:37:41 +02:00
|
|
|
this.setupStarfield();
|
2014-07-24 05:35:57 +02:00
|
|
|
this.setupTessellation();
|
|
|
|
|
|
|
|
this.last = Date.now() / 1000;
|
|
|
|
|
|
|
|
this.start = this.last;
|
|
|
|
|
2014-07-25 12:09:17 +02:00
|
|
|
this._handleMouseCoords = this._handleMouseCoords.bind(this);
|
|
|
|
window.addEventListener('mousemove', this._handleMouseCoords, false);
|
|
|
|
|
2014-07-24 05:35:57 +02:00
|
|
|
this.render = this.render.bind(this);
|
|
|
|
this.render();
|
|
|
|
|
|
|
|
this.canvas.style.opacity = 1;
|
2014-07-24 05:52:27 +02:00
|
|
|
|
2014-07-25 08:37:41 +02:00
|
|
|
this.cssAnimations(
|
|
|
|
document.getElementById(image)
|
|
|
|
);
|
|
|
|
},
|
|
|
|
|
|
|
|
cssAnimations: function(image){
|
|
|
|
var parent = this.canvas.parentNode;
|
|
|
|
|
2014-07-24 05:35:57 +02:00
|
|
|
image.style.webkitTransform = 'translate3d(0,0,0) scale(1)';
|
|
|
|
image.style.opacity = 1;
|
2014-07-24 05:52:27 +02:00
|
|
|
|
2014-07-25 08:37:41 +02:00
|
|
|
new Chainable()
|
2014-07-26 05:28:47 +02:00
|
|
|
.wait(1000)
|
2014-07-25 12:09:17 +02:00
|
|
|
.then(function(){
|
2014-07-25 12:18:49 +02:00
|
|
|
this.starGeneratorRate = 200;
|
2014-07-25 12:09:17 +02:00
|
|
|
}, this)
|
2014-07-26 05:28:47 +02:00
|
|
|
.wait(1000)
|
2014-07-25 12:09:17 +02:00
|
|
|
.then(function(){
|
|
|
|
this.showGrid = true;
|
|
|
|
}, this)
|
|
|
|
.wait(2000)
|
2014-07-25 08:37:41 +02:00
|
|
|
.then(function(){
|
|
|
|
parent.className += ' state-one';
|
|
|
|
})
|
|
|
|
.wait(150)
|
|
|
|
.then(function(){
|
|
|
|
parent.className += ' state-two';
|
|
|
|
})
|
|
|
|
.wait(150)
|
|
|
|
.then(function(){
|
|
|
|
parent.className += ' state-three';
|
|
|
|
})
|
|
|
|
.wait(500)
|
|
|
|
.then(function(){
|
|
|
|
parent.className += ' state-four';
|
|
|
|
})
|
|
|
|
.wait(100)
|
|
|
|
.then(function(){
|
|
|
|
this.showShapes = true;
|
2014-07-25 12:09:17 +02:00
|
|
|
}, this)
|
|
|
|
.wait(1000)
|
|
|
|
.then(function(){
|
2014-07-25 08:37:41 +02:00
|
|
|
}, this);
|
2014-07-24 05:35:57 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
setupStarfield: function(){
|
|
|
|
this.particles = [];
|
2014-07-25 12:09:17 +02:00
|
|
|
// this.generateParticles(50, true);
|
2014-07-26 05:28:47 +02:00
|
|
|
this.generateParticles(400);
|
2014-07-24 05:35:57 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
setupTessellation: function(canvas){
|
2014-07-24 09:37:27 +02:00
|
|
|
this.shapes = [];
|
|
|
|
this.logo = new Engine.Shape(
|
2014-07-25 07:50:14 +02:00
|
|
|
-(180),
|
|
|
|
-(180),
|
2014-07-24 09:37:27 +02:00
|
|
|
360,
|
|
|
|
360,
|
2014-07-24 09:46:14 +02:00
|
|
|
Logo.Points,
|
|
|
|
Logo.Polygons
|
2014-07-24 09:37:27 +02:00
|
|
|
);
|
2014-07-25 12:09:17 +02:00
|
|
|
|
2014-07-26 06:04:52 +02:00
|
|
|
this.grid = new Engine.Shape.Puller(this.width, this.height, Grid);
|
2014-07-24 05:35:57 +02:00
|
|
|
},
|
|
|
|
|
2014-07-26 08:09:04 +02:00
|
|
|
|
|
|
|
getAverageTickTime: function(){
|
|
|
|
var sum = 0, s;
|
|
|
|
|
|
|
|
for (s = 0; s < this.ticks.length; s++) {
|
|
|
|
sum += this.ticks[s];
|
|
|
|
}
|
|
|
|
|
2014-07-26 09:11:43 +02:00
|
|
|
window.console.log('Average Tick Time:', sum / this.ticks.length);
|
2014-07-26 08:09:04 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
getLongestTick: function(){
|
|
|
|
var max = 0, index, s;
|
|
|
|
|
|
|
|
for (s = 0; s < this.ticks.length; s++) {
|
|
|
|
if (this.ticks[s] > max) {
|
|
|
|
max = this.ticks[s];
|
|
|
|
index = s;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-26 09:11:43 +02:00
|
|
|
window.console.log('Max tick was:', max, 'at index:', index);
|
2014-07-26 08:09:04 +02:00
|
|
|
},
|
|
|
|
|
2014-07-24 05:35:57 +02:00
|
|
|
render: function(){
|
2014-07-26 09:11:43 +02:00
|
|
|
var scale = this.scale;
|
2014-07-24 05:35:57 +02:00
|
|
|
|
2014-07-26 09:11:43 +02:00
|
|
|
if (this.scrollY > 700) {
|
2014-07-24 07:28:16 +02:00
|
|
|
window.requestAnimationFrame(this.render);
|
|
|
|
return;
|
|
|
|
}
|
2014-07-24 05:35:57 +02:00
|
|
|
|
2014-07-25 07:50:14 +02:00
|
|
|
this.context.clearRect(
|
|
|
|
-(this.width / 2) * scale,
|
|
|
|
-(this.height / 2) * scale,
|
2014-07-26 08:09:04 +02:00
|
|
|
this.width * scale,
|
2014-07-25 07:50:14 +02:00
|
|
|
this.height * scale
|
|
|
|
);
|
2014-07-24 07:28:16 +02:00
|
|
|
|
|
|
|
this.now = Date.now() / 1000;
|
2014-07-24 05:35:57 +02:00
|
|
|
|
2014-07-25 08:37:41 +02:00
|
|
|
this.tick = Math.min(this.now - this.last, 0.017);
|
2014-07-24 05:35:57 +02:00
|
|
|
|
|
|
|
this.renderStarfield(this.now);
|
|
|
|
|
2014-07-25 12:09:17 +02:00
|
|
|
if (this.showGrid) {
|
2014-07-26 05:28:47 +02:00
|
|
|
this.grid
|
|
|
|
.update(this)
|
2014-07-26 06:16:16 +02:00
|
|
|
.draw(this.context, scale, this);
|
2014-07-25 12:09:17 +02:00
|
|
|
}
|
|
|
|
|
2014-07-25 08:37:41 +02:00
|
|
|
if (this.showShapes) {
|
2014-07-26 08:09:04 +02:00
|
|
|
// this.renderTessellation(this.now);
|
|
|
|
this.logo
|
|
|
|
.update(this)
|
|
|
|
.draw(this.context, scale, this);
|
2014-07-24 05:35:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
this.last = this.now;
|
|
|
|
|
|
|
|
window.requestAnimationFrame(this.render);
|
|
|
|
},
|
|
|
|
|
|
|
|
renderTessellation: function(){
|
2014-07-25 09:22:27 +02:00
|
|
|
var scale = this.scale, p, index;
|
2014-07-24 05:35:57 +02:00
|
|
|
|
2014-07-24 09:37:27 +02:00
|
|
|
for (p = 0; p < this.shapes.length; p++) {
|
2014-07-26 05:28:47 +02:00
|
|
|
this.shapes[p]
|
|
|
|
.update(this)
|
2014-07-26 06:16:16 +02:00
|
|
|
.draw(this.context, scale, this);
|
2014-07-24 05:35:57 +02:00
|
|
|
}
|
|
|
|
|
2014-07-26 05:28:47 +02:00
|
|
|
this.logo
|
|
|
|
.update(this)
|
2014-07-26 06:16:16 +02:00
|
|
|
.draw(this.context, scale, this);
|
2014-07-24 09:46:14 +02:00
|
|
|
|
|
|
|
// Remove destroyed shapes
|
|
|
|
for (p = 0; p < this._deferredShapes.length; p++) {
|
|
|
|
index = this.shapes.indexOf(this._deferredShapes.pop());
|
|
|
|
if (index >= 0) {
|
|
|
|
this.shapes.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
2014-07-25 09:04:54 +02:00
|
|
|
|
|
|
|
// 1 Per second? Maybe?
|
2014-07-25 09:24:34 +02:00
|
|
|
// if (Engine.getRandomFloat(0,100) < 1.6666) {
|
|
|
|
// this.generateRandomShape();
|
|
|
|
// }
|
2014-07-24 05:35:57 +02:00
|
|
|
},
|
|
|
|
|
2014-07-25 09:22:27 +02:00
|
|
|
generateRandomShape: function(){
|
2014-07-26 09:11:43 +02:00
|
|
|
var halfWidth, halfHeight, iter,
|
2014-07-25 09:22:27 +02:00
|
|
|
shape, shapeTemplate, columns, rows, modWidth, row, column,
|
|
|
|
xOffset, yOffset;
|
|
|
|
|
|
|
|
iter = 140;
|
|
|
|
|
|
|
|
rows = this.height / iter - 1;
|
|
|
|
modWidth = this.width % iter;
|
|
|
|
columns = (this.width - modWidth) / iter - 1;
|
|
|
|
|
|
|
|
row = Engine.getRandomInt(0, rows);
|
|
|
|
column = Engine.getRandomInt(0, columns);
|
|
|
|
|
|
|
|
halfWidth = this.width / 2;
|
|
|
|
halfHeight = this.height / 2;
|
|
|
|
shapeTemplate = Shapes[Engine.getRandomInt(0, Shapes.length - 1)];
|
|
|
|
|
|
|
|
xOffset = Engine.getRandomInt(-50, 50);
|
|
|
|
yOffset = Engine.getRandomInt(-50, 50);
|
|
|
|
|
|
|
|
shape = new Engine.Shape(
|
|
|
|
(iter / 2) + (column * iter) - (modWidth / 2) - halfWidth + xOffset - 25,
|
|
|
|
(iter / 2) + (row * iter) - halfHeight + yOffset - 25,
|
|
|
|
50,
|
|
|
|
50,
|
|
|
|
shapeTemplate.points,
|
|
|
|
shapeTemplate.polygons,
|
|
|
|
true
|
|
|
|
);
|
|
|
|
shape.selfDestruct(10);
|
|
|
|
this.shapes.push(shape);
|
|
|
|
},
|
|
|
|
|
2014-07-24 05:35:57 +02:00
|
|
|
generateParticles: function(num, fixed){
|
|
|
|
var p;
|
|
|
|
|
|
|
|
for (p = 0; p < num; p++) {
|
|
|
|
if (fixed) {
|
|
|
|
this.particles.push(new Engine.Particle.Fixed(this.width, this.height));
|
|
|
|
} else {
|
|
|
|
this.particles.push(new Engine.Particle(this.width, this.height));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
resize: function(){
|
2014-07-25 07:50:14 +02:00
|
|
|
var scale = this.scale;
|
|
|
|
|
2014-07-24 05:35:57 +02:00
|
|
|
this.width = window.innerWidth;
|
|
|
|
this.height = 700;
|
|
|
|
|
2014-07-25 07:50:14 +02:00
|
|
|
this.canvas.width = this.width * scale;
|
|
|
|
this.canvas.height = this.height * scale;
|
|
|
|
|
|
|
|
this.context.translate(
|
|
|
|
this.width / 2 * scale >> 0,
|
|
|
|
this.height / 2 * scale >> 0
|
|
|
|
);
|
2014-07-26 05:28:47 +02:00
|
|
|
|
|
|
|
if (this.grid) {
|
|
|
|
this.grid.resize(this.width, this.height);
|
|
|
|
}
|
2014-07-24 05:35:57 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
renderStarfield: function(){
|
2014-07-26 08:09:04 +02:00
|
|
|
var scale = this.scale, p, index, particle;
|
2014-07-24 05:35:57 +02:00
|
|
|
|
|
|
|
// Update all particles... may need to be optimized
|
|
|
|
for (p = 0; p < this.particles.length; p++) {
|
2014-07-26 08:09:04 +02:00
|
|
|
this.particles[p].update(this);
|
2014-07-24 05:35:57 +02:00
|
|
|
}
|
|
|
|
|
2014-07-26 08:09:04 +02:00
|
|
|
// Batch render particles based on color
|
|
|
|
// to prevent unneeded context state change
|
|
|
|
this.context.fillStyle = '#8750c2';
|
|
|
|
for (p = 0; p < this.particlesA.length; p++) {
|
|
|
|
particle = this.particlesA[p];
|
|
|
|
|
|
|
|
if (particle.radius < 0.25) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
this.context.fillRect(
|
|
|
|
particle.pos.x * scale >> 0,
|
|
|
|
particle.pos.y * scale >> 0,
|
|
|
|
particle.radius * scale,
|
|
|
|
particle.radius * scale
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.context.fillStyle = '#b976ff';
|
|
|
|
for (p = 0; p < this.particlesB.length; p++) {
|
|
|
|
particle = this.particlesB[p];
|
|
|
|
|
|
|
|
if (particle.radius < 0.25) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
this.context.fillRect(
|
|
|
|
particle.pos.x * scale >> 0,
|
|
|
|
particle.pos.y * scale >> 0,
|
|
|
|
particle.radius * scale,
|
|
|
|
particle.radius * scale
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.particlesA.length = 0;
|
|
|
|
this.particlesB.length = 0;
|
|
|
|
|
2014-07-24 09:46:14 +02:00
|
|
|
// Remove destroyed particles
|
|
|
|
for (p = 0; p < this._deferredParticles.length; p++) {
|
|
|
|
index = this.particles.indexOf(this._deferredParticles.pop());
|
2014-07-24 05:35:57 +02:00
|
|
|
if (index >= 0) {
|
|
|
|
this.particles.splice(index, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-07-25 12:09:17 +02:00
|
|
|
this.generateParticles(this.starGeneratorRate * this.tick >> 0);
|
|
|
|
},
|
|
|
|
|
|
|
|
_handleMouseCoords: function(event){
|
|
|
|
this.mouse.x = event.pageX;
|
|
|
|
this.mouse.y = event.pageY;
|
2014-07-26 09:11:43 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
_handleScroll: function(){
|
|
|
|
this.scrollY = window.scrollY;
|
2014-07-24 05:35:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
Engine.map = function(val, istart, istop, ostart, ostop) {
|
|
|
|
return ostart + (ostop - ostart) * ((val - istart) / (istop - istart));
|
|
|
|
};
|
|
|
|
|
|
|
|
Engine.getRandomFloat = function(min, max) {
|
|
|
|
return Math.random() * (max - min) + min;
|
|
|
|
};
|
|
|
|
|
|
|
|
Engine.getRandomInt = function(min, max) {
|
|
|
|
return Math.floor(Math.random() * (max - min + 1) + min);
|
|
|
|
};
|
|
|
|
|
2014-07-24 09:37:27 +02:00
|
|
|
Engine.clone = function(ref) {
|
|
|
|
var clone = {}, key;
|
|
|
|
for (key in ref) {
|
|
|
|
clone[key] = ref[key];
|
|
|
|
}
|
|
|
|
return clone;
|
|
|
|
};
|
|
|
|
|
2014-07-24 05:35:57 +02:00
|
|
|
window.Engine = Engine;
|
|
|
|
|
2014-07-25 08:37:41 +02:00
|
|
|
})(
|
|
|
|
window.Base,
|
|
|
|
window.Vector,
|
|
|
|
window.Logo,
|
2014-07-25 09:04:54 +02:00
|
|
|
window.Shapes,
|
2014-07-25 12:09:17 +02:00
|
|
|
window.Grid,
|
2014-07-25 08:37:41 +02:00
|
|
|
window.Chainable
|
|
|
|
);
|