Path: blob/main/public/games/files/garbage-collector/js/zoo.js
1036 views
(function( window, document, undefined ) {1'use strict';23var PI2 = 2 * Math.PI;45var running = false;67var el = document.querySelector( '.container' );89var tickFns = [];1011function createCanvas( size ) {12var canvas = document.createElement( 'canvas' ),13ctx = canvas.getContext( '2d' );1415var width = size,16height = size;1718canvas.width = width;19canvas.height = height;2021el.appendChild( canvas );2223return {24canvas: canvas,25ctx: ctx,26width: width,27height: height28};29}3031/**32* TODO:33* - Wires,34* - Teleporter?35* - Emitter.36* - Trash?37*/3839tickFns.push((function drawHero() {40var element = createCanvas( 128 );4142var canvas = element.canvas,43ctx = element.ctx,44width = element.width,45height = element.height;4647canvas.style.backgroundColor = 'black';4849var t = 0;5051function draw() {52ctx.clearRect( 0, 0, ctx.canvas.width, ctx.canvas.height );5354ctx.save();55ctx.translate( 0.5 * width, 0.5 * height );5657// Draw casing.58ctx.lineWidth = 0.05 * width;5960// Top left.61ctx.beginPath();62ctx.arc( 0, 0, 0.22 * width, -Math.PI, -0.5 * Math.PI );63ctx.strokeStyle = '#fef';64ctx.stroke();6566// Top right.67ctx.beginPath();68ctx.arc( 0, 0, 0.22 * width, -0.5 * Math.PI, 0 );69ctx.strokeStyle = '#cbe';70ctx.stroke();7172// Bottom right.73ctx.beginPath();74ctx.arc( 0, 0, 0.22 * width, 0, 0.5 * Math.PI );75ctx.strokeStyle = '#98b';76ctx.stroke();7778// Bottom left.79ctx.beginPath();80ctx.arc( 0, 0, 0.22 * width, 0.5 * Math.PI, Math.PI );81ctx.strokeStyle = '#658';82ctx.stroke();8384// Draw main body.85ctx.beginPath();86ctx.arc( 0, 0, 0.2 * width, 0, PI2 );87ctx.fillStyle = '#ecf';88ctx.fill();8990// Strokes.91ctx.lineWidth = 0.02 * width;92ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)';93ctx.stroke();9495ctx.beginPath();96ctx.arc( 0, 0, 0.18 * width, 0, PI2 );97ctx.strokeStyle = '#fff';98ctx.stroke();99100// Draw eyes.101if ( t % 240 < 160 ) {102// Draw left eye.103ctx.beginPath();104ctx.rect( -0.1 * width, -0.06 * height, 0.04 * width, 0.08 * width );105ctx.fillStyle = '#448';106ctx.fill();107108// Draw right eye.109ctx.beginPath();110ctx.rect( 0.06 * width, -0.06 * height, 0.04 * width, 0.08 * width );111ctx.fillStyle = '#448';112ctx.fill();113} else {114// Draw X.115ctx.beginPath();116ctx.moveTo( -0.1 * width, -0.06 * height );117ctx.lineTo( 0.1 * width, 0.02 * height );118ctx.moveTo( -0.1 * width, 0.02 * height );119ctx.lineTo( 0.1 * width, -0.06 * height );120ctx.lineWidth = 0.03 * width;121ctx.strokeStyle = '#448';122ctx.stroke();123}124125// Draw mouth.126if ( t % 240 < 80 ) {127// Draw smile.128ctx.beginPath();129ctx.arc( 0, 0.02 * height, 0.1 * width, 0.25 * Math.PI, 0.75 * Math.PI );130131ctx.lineWidth = 0.03 * width;132ctx.strokeStyle = '#448';133ctx.stroke();134} else if ( t % 240 < 160 ) {135// Draw line.136ctx.beginPath();137ctx.rect( -0.06 * width, 0.08 * height, 0.12 * width, 0.02 * width );138ctx.fillStyle = '#448';139ctx.fill();140} else {141// Draw square.142ctx.beginPath();143ctx.rect( -0.03 * width, 0.06 * height, 0.06 * width, 0.06 * width );144ctx.fillStyle = '#448';145ctx.fill();146}147148// Draw ring.149ctx.beginPath();150ctx.arc( 0, 0, 0.35 * width, 0, PI2 );151152ctx.shadowColor = '#fff';153ctx.shadowBlur = 0.05 * width + Math.random() * 0.05 * width;154155ctx.lineWidth = 0.07 * width;156ctx.strokeStyle = '#fff';157ctx.stroke();158159ctx.shadowBlur = 0;160161ctx.restore();162}163164return function() {165t++;166draw();167};168}) ());169170tickFns.push((function drawEmitter() {171var element = createCanvas( 128 );172173var canvas = element.canvas,174ctx = element.ctx,175width = element.width,176height = element.height;177178canvas.style.backgroundColor = '#333';179180var beamWidth = 0.4 * width,181beamHeight = 0.3 * height;182183var baseWidth = 0.1 * beamWidth,184baseHeight = beamHeight;185186function yRandom() {187return Math.random() - 0.5;188}189190var t = 0;191192var particles = [];193var particleCount = 10;194var radius;195while ( particleCount-- ) {196radius = ( 0.02 + Math.random() * 0.01 ) * width;197particles.push({198x: Math.random() * beamWidth,199y: yRandom() * ( beamHeight - radius ),200radius: radius,201vx: 2 * beamHeight,202vy: 0203});204}205206var redPrefix = 'rgba(255, 128, 128, ',207bluePrefix = 'rgba(128, 128, 255, ';208209var colorPrefix = redPrefix;210211function draw() {212if ( t % 120 < 60 ) {213colorPrefix = redPrefix;214} else {215colorPrefix = bluePrefix;216}217218ctx.clearRect( 0, 0, width, height );219220ctx.save();221ctx.translate( 0.5 * width, 0.5 * height );222223// Draw beam.224ctx.beginPath();225ctx.rect( 0, -0.5 * beamHeight, beamWidth, beamHeight );226var grad = ctx.createLinearGradient( 0, 0, beamWidth, 0 );227grad.addColorStop( 0, colorPrefix + '0.8)' );228grad.addColorStop( 1, colorPrefix + '0.0)' );229ctx.fillStyle = grad;230ctx.fill();231232// Draw particles.233particles.forEach(function( particle ) {234var alpha = 1 - particle.x / beamWidth;235236ctx.beginPath();237ctx.arc( particle.x, particle.y, particle.radius, 0, PI2 );238ctx.fillStyle = 'rgba(255, 255, 255, ' + alpha + ')';239ctx.fill();240});241242// Draw base.243ctx.shadowBlur = 0.02 * width;244ctx.shadowColor = colorPrefix + '1.0)';245246ctx.beginPath();247ctx.moveTo( 0, -0.5 * baseHeight );248ctx.lineTo( 0, 0.5 * baseHeight );249250ctx.lineCap = 'round';251ctx.lineWidth = baseWidth;252ctx.strokeStyle = '#fff';253ctx.stroke();254255ctx.lineCap = 'butt';256ctx.shadowBlur = 0;257258ctx.restore();259}260261return function( dt ) {262t++;263264particles.forEach(function( particle ) {265particle.x += particle.vx * dt;266particle.y += particle.vy * dt;267268if ( particle.x - particle.radius > beamWidth ) {269particle.x = particle.radius;270particle.y = yRandom() * ( beamHeight - radius );271}272});273274draw();275};276}) ());277278tickFns.push((function drawTrash() {279var element = createCanvas( 128 );280281var canvas = element.canvas,282ctx = element.ctx,283width = element.width,284height = element.height;285286canvas.style.backgroundColor = '#222';287288var t = 0;289290var angle = 0;291var va = 60 * Math.PI / 180;292293var hue = 240;294295function draw() {296ctx.clearRect( 0, 0, width, height );297298if ( t % 240 < 120 ) {299hue = 240;300} else {301hue = 0;302}303304ctx.save();305ctx.translate( 0.5 * width, 0.5 * height );306ctx.rotate( -angle );307308ctx.beginPath();309ctx.rect( -0.32 * width, -0.2 * height, 0.64 * width, 0.4 * height );310ctx.fillStyle = 'hsl(' + hue + ', 30%, 60%)';311ctx.fill();312313// Draw outline.314ctx.shadowBlur = 0.1 * width;315ctx.shadowColor = 'hsl(' + hue + ', 70%, 70%)';316317ctx.lineJoin = 'round';318ctx.lineWidth = 0.03 * width;319ctx.strokeStyle = '#fff';320ctx.stroke();321322ctx.shadowBlur = 0;323ctx.lineJoin = 'butt';324325ctx.restore();326}327328return function( dt ) {329t++;330331angle += va * dt;332if ( angle > PI2 ) {333angle -= PI2;334}335336draw();337};338}) ());339340// Based off of https://github.com/soulwire/sketch.js/blob/master/examples/particles.html341tickFns.push((function drawExplosion() {342var element = createCanvas( 128 );343344var canvas = element.canvas,345ctx = element.ctx,346width = element.width,347height = element.height;348349canvas.style.backgroundColor = '#555';350351var particles = [];352353var shrink = 0.95;354var t = 0;355356function generateParticles() {357var particleCount = 10;358var angle, force;359360while ( particleCount-- ) {361angle = Math.random() * PI2;362force = Math.random() * 50 + 100;363364particles.push({365x: 0.5 * width,366y: 0.5 * height,367radius: ( Math.random() * 0.1 + 0.05 ) * width,368angle: angle,369vx: Math.cos( angle ) * force,370vy: Math.sin( angle ) * force,371drag: Math.random() * 0.05 + 0.9,372deviation: Math.random() * 1.5 + 0.5373});374}375}376377generateParticles();378379function draw() {380ctx.clearRect( 0, 0, width, height );381382if ( t % 240 < 120 ) {383ctx.fillStyle = 'rgba(64, 32, 32, 1)';384} else {385ctx.fillStyle = 'rgba(32, 32, 64, 1)';386}387388ctx.globalCompositeOperation = 'lighter';389390particles.forEach(function( particle ) {391ctx.beginPath();392ctx.arc( particle.x, particle.y, particle.radius, 0, PI2 );393ctx.fill();394});395396ctx.globalCompositeOperation = 'source-over';397}398399return function( dt ) {400t++;401402var removed = [];403particles.forEach(function( particle, index ) {404particle.x += particle.vx * dt;405particle.y += particle.vy * dt;406407particle.vx *= particle.drag;408particle.vy *= particle.drag;409410particle.angle += ( Math.random() - 0.5 ) * particle.deviation;411412particle.vx += Math.cos( particle.angle ) * 0.1;413particle.vy += Math.sin( particle.angle ) * 0.1;414415particle.radius *= shrink;416if ( particle.radius < 0.5 ) {417removed.push( index );418}419});420421var index = removed.length;422while ( index-- ) {423particles.splice( removed[ index ], 1 );424}425426if ( !particles.length ) {427generateParticles();428}429430draw();431};432}) ());433434tickFns.push((function drawBackground() {435var element = createCanvas( 512 );436437var canvas = element.canvas,438ctx = element.ctx,439width = element.width,440height = element.height;441442var hue = 240;443var hueSpread = 20;444445var t = 0;446447var rects = [];448449function generateRects() {450rects = [];451452var rectCount = 100;453while ( rectCount-- ) {454rects.push({455x: Math.random() * width,456y: Math.random() * height,457width: ( Math.random() * 0.25 + 0.05 ) * width,458height: ( Math.random() * 0.25 + 0.05 ) * height,459saturation: Math.round( Math.random() * 30 + 25 ) + '%',460lightness: Math.round( Math.random() * 50 + 25 ) + '%'461});462}463}464465function draw() {466if ( t % 240 < 120 ) {467hue = 240;468} else {469hue = 0;470}471472canvas.style.backgroundColor = 'hsla(' + hue + ', 30%, 50%, 1.0)';473474ctx.clearRect( 0, 0, width, height );475476generateRects();477rects.forEach(function( rect ) {478ctx.save();479ctx.translate( rect.x, rect.y );480ctx.beginPath();481ctx.rect( -0.5 * rect.width, -0.5 * rect.height, rect.width, rect.height );482ctx.fillStyle = 'hsla(' +483( hue + Math.round( hueSpread * ( Math.random() - 0.5 ) ) ) + ', ' +484rect.saturation + ', ' +485rect.lightness + ', ' +486Math.random() +487')';488ctx.fill();489490ctx.restore();491});492}493494var isDrawn = false;495496return function() {497t++;498if ( t % 120 === 0 ) {499isDrawn = false;500}501502if ( !isDrawn ) {503draw();504isDrawn = true;505}506};507}) ());508509var prevTime = Date.now(),510currTime;511512function tick() {513currTime = Date.now();514var dt = currTime - prevTime;515prevTime = currTime;516517if ( dt > 1e2 ) {518dt = 1e2;519}520521dt *= 1e-3;522523tickFns.forEach(function( tickFn ) {524tickFn( dt );525});526527if ( !running ) {528return;529}530531window.requestAnimationFrame( tick );532}533534tick();535536var runCheckbox = document.getElementById( 'run-checkbox' );537538function play() {539if ( !running ) {540running = true;541tick();542runCheckbox.checked = true;543}544}545546function pause() {547running = false;548runCheckbox.checked = false;549}550551function toggleContinuousRendering() {552if ( !runCheckbox.checked ) {553play();554} else {555pause();556}557}558559runCheckbox.addEventListener( 'click', function() {560runCheckbox.checked = !runCheckbox.checked;561toggleContinuousRendering();562});563564document.addEventListener( 'keydown', function( event ) {565// ESC.566if ( event.which === 27 ) {567pause();568}569570// Space.571if ( event.which === 32 ) {572event.preventDefault();573toggleContinuousRendering();574}575});576577window.addEventListener( 'blur', function() {578pause();579});580}) ( window, document );581582583