var MOUSE_TIMEOUT = 1000; var mouseTimeout; $('body').mousemove(function() { hideAll(); if (mouseTimeout) clearTimeout(mouseTimeout); mouseTimeout = setTimeout(onMouseTimeout, MOUSE_TIMEOUT); }); function onMouseTimeout() { canSpawn(); } var MAX_BUGS = 5; var bugs = []; var SPAWN_INTERVAL = 2000; var spawnInterval; function canSpawn() { if (!spawnInterval) spawnInterval = setInterval(spawn, SPAWN_INTERVAL); } function spawn() { bugs = bugs.filter(function(bug) { return !bug.shouldHide; }); /*console.log("spawn", bugs.length, "/", MAX_BUGS);*/ if (bugs.length >= MAX_BUGS) return; bugs.push(new Bug()); } function hideAll() { if (spawnInterval) { clearInterval(spawnInterval); spawnInterval = null; hideAll(); } for(var i = 0; i < bugs.length; i++) { bugs[i].shouldHide = true; } bugs = []; } function Bug() { this.alpha = 0; this.rotation = 0; this.x = $('body').scrollLeft() + Math.floor(window.innerWidth * Math.random()); this.y = $('body').scrollTop() + Math.floor(window.innerHeight * Math.random()); this.selectTarget(); this.el = $(''); this.el.css({ position: 'absolute', width: "28px", height: "28px" }); $('body').append(this.el); /*console.log("new bug", this, this.x, this.y);*/ this.think(); } Bug.prototype = { update: function() { this.el.css({ left: Math.floor(this.x) + "px", top: Math.floor(this.y) + "px", opacity: this.alpha, transform: "rotate(" + this.rotation + "rad)", '-webkitTransform': "rotate(" + this.rotation + "rad)", '-mozTransform': "rotate(" + this.rotation + "rad)" }); }, selectTarget: function() { this.targetRotation = 2 * Math.PI * (Math.random() - 0.5); this.targetSteps = 5 + Math.ceil(10 * Math.random()); }, think: function() { if (this.shouldHide && this.alpha > 0) { /* fading out */ this.alpha -= 0.1; } else if (this.shouldHide) { this.el.remove(); /* destroy * HACK: Avoid nextTick() */ return; } else if (this.alpha < 1) { /* fading in */ this.alpha += 0.1; } var dr = this.targetRotation - this.rotation; if (Math.abs(dr) > 1) { this.rotation += Math.random() * dr / 10; } if (this.targetSteps > 0) { this.targetSteps--; this.x += Math.sin(this.rotation); this.y -= Math.cos(this.rotation); /* Emergency suicide: */ if (this.x < 16 || this.x > $('body').innerWidth() - 16 || this.y < 16 || this.y > $('body').innerHeight() - 16) { this.shouldHide = true; } } else { this.selectTarget(); } this.update(); nextTick(this.think.bind(this)); } }; var nextTick = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || window.oRequestAnimationFrame || function(f) { window.setTimeout(f, 40); };