diff --git a/js/eyecandy.js b/js/eyecandy.js index c827ac6..58ddea5 100644 --- a/js/eyecandy.js +++ b/js/eyecandy.js @@ -1,17 +1,16 @@ (function() { - var width, height, largeHeader, canvas, ctx, lines, target, size, animateHeader = true; + var width, height, largeHeader, canvas, ctx, points, target, animateHeader = true; // Main initHeader(); - addListeners(); initAnimation(); + addListeners(); function initHeader() { width = window.innerWidth; - height = window.innerHeight; - size = width > height ? height : width; - target = {x: 0, y: height}; + height = 500; + target = {x: width/2, y: height/2}; largeHeader = document.getElementById('large-header'); largeHeader.style.height = height+'px'; @@ -21,24 +20,77 @@ canvas.height = height; ctx = canvas.getContext('2d'); - // create particles - lines = []; - for(var i = 0; i < 90; i++) { - var l = new Line(Math.random()*360); - lines.push(l); + // create points + points = []; + for(var x = 0; x < width; x = x + width/20) { + for(var y = 0; y < height; y = y + height/20) { + var px = x + Math.random()*width/20; + var py = y + Math.random()*height/20; + var p = {x: px, originX: px, y: py, originY: py }; + points.push(p); + } } - } - function initAnimation() { - animate(); + // for each point find the 5 closest points + for(var i = 0; i < points.length; i++) { + var closest = []; + var p1 = points[i]; + for(var j = 0; j < points.length; j++) { + var p2 = points[j] + if(!(p1 == p2)) { + var placed = false; + for(var k = 0; k < 5; k++) { + if(!placed) { + if(closest[k] == undefined) { + closest[k] = p2; + placed = true; + } + } + } + + for(var k = 0; k < 5; k++) { + if(!placed) { + if(getDistance(p1, p2) < getDistance(p1, closest[k])) { + closest[k] = p2; + placed = true; + } + } + } + } + } + p1.closest = closest; + } + + // assign a circle to each point + for(var i in points) { + var c = new Circle(points[i], 2+Math.random()*2, 'rgba(255,255,255,0.3)'); + points[i].circle = c; + } } // Event handling function addListeners() { + if(!('ontouchstart' in window)) { + window.addEventListener('mousemove', mouseMove); + } window.addEventListener('scroll', scrollCheck); window.addEventListener('resize', resize); } + function mouseMove(e) { + var posx = posy = 0; + if (e.pageX || e.pageY) { + posx = e.pageX; + posy = e.pageY; + } + else if (e.clientX || e.clientY) { + posx = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; + posy = e.clientY + document.body.scrollTop + document.documentElement.scrollTop; + } + target.x = posx; + target.y = posy; + } + function scrollCheck() { if(document.body.scrollTop > height) animateHeader = false; else animateHeader = true; @@ -46,55 +98,88 @@ function resize() { width = window.innerWidth; - height = window.innerHeight; - size = width > height ? height : width; + height = 500; largeHeader.style.height = height+'px'; canvas.width = width; canvas.height = height; } + // animation + function initAnimation() { + animate(); + for(var i in points) { + shiftPoint(points[i]); + } + } + function animate() { if(animateHeader) { ctx.clearRect(0,0,width,height); - for(var i in lines) { - lines[i].draw(); + for(var i in points) { + // detect points in range + if(Math.abs(getDistance(target, points[i])) < 4000) { + points[i].active = 0.3; + points[i].circle.active = 0.6; + } else if(Math.abs(getDistance(target, points[i])) < 20000) { + points[i].active = 0.1; + points[i].circle.active = 0.3; + } else if(Math.abs(getDistance(target, points[i])) < 40000) { + points[i].active = 0.02; + points[i].circle.active = 0.1; + } else { + points[i].active = 0; + points[i].circle.active = 0; + } + + drawLines(points[i]); + points[i].circle.draw(); } } requestAnimationFrame(animate); } + function shiftPoint(p) { + TweenLite.to(p, 1+1*Math.random(), {x:p.originX-50+Math.random()*100, + y: p.originY-50+Math.random()*100, ease:Circ.easeInOut, + onComplete: function() { + shiftPoint(p); + }}); + } + // Canvas manipulation - function Line(angle) { + function drawLines(p) { + if(!p.active) return; + for(var i in p.closest) { + ctx.beginPath(); + ctx.moveTo(p.x, p.y); + ctx.lineTo(p.closest[i].x, p.closest[i].y); + ctx.strokeStyle = 'rgba(156,217,249,'+ p.active+')'; + ctx.stroke(); + } + } + + function Circle(pos,rad,color) { var _this = this; // constructor (function() { - _this.angle = angle; - + _this.pos = pos || null; + _this.radius = rad || null; + _this.color = color || null; })(); this.draw = function() { - - var r1 = Math.random()*(size < 400 ? 400 : size)*0.4; - var r2 = Math.random()*(size < 400 ? 400 : size)*0.4; - var x1 = r1*Math.cos(_this.angle*(Math.PI/180)) + width*0.5; - var y1 = r1*Math.sin(_this.angle*(Math.PI/180)) + height*0.48; - var x2 = r2*Math.cos(_this.angle*(Math.PI/180)) + width*0.5; - var y2 = r2*Math.sin(_this.angle*(Math.PI/180)) + height*0.48; + if(!_this.active) return; ctx.beginPath(); - ctx.moveTo(x1, y1); - ctx.lineTo(x2, y2); - ctx.strokeStyle = 'rgba(255,193,127,'+(0.5+Math.random()*0.5)+')'; - - ctx.stroke(); - - ctx.beginPath(); - ctx.arc(x1, y1, 2, 0, 2 * Math.PI, false); - ctx.fillStyle = 'rgba(255,165,70,'+(0.5+Math.random()*0.5)+')'; + ctx.arc(_this.pos.x, _this.pos.y, _this.radius, 0, 2 * Math.PI, false); + ctx.fillStyle = 'rgba(156,217,249,'+ _this.active+')'; ctx.fill(); - - _this.angle += Math.random(); }; } -})(); \ No newline at end of file + // Util + function getDistance(p1, p2) { + return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2); + } + +})();