html--烟花3

// Options var options = { /* Which hue should be used for the first batch of rockets? */ startingHue: 120, /* How many ticks the script should wait before a new firework gets spawned, if the user is holding down his mouse button. */ clickLimiter: 5, /* How fast the rockets should automatically spawn, based on ticks */ timerInterval: 40, /* Show pulsing circles marking the targets? */ showTargets: true, /* Rocket movement options, should be self-explanatory */ rocketSpeed: 2, rocketAcceleration: 1.03, /* Particle movement options, should be self-explanatory */ particleFriction: 0.95, particleGravity: 1, /* Minimum and maximum amount of particle spawns per rocket */ particleMinCount: 25, particleMaxCount: 40, /* Minimum and maximum radius of a particle */ particleMinRadius: 3, particleMaxRadius: 5 }; // Local variables var fireworks = []; var particles = []; var mouse = {down: false, x: 0, y: 0}; var currentHue = options.startingHue; var clickLimiterTick = 0; var timerTick = 0; var cntRocketsLaunched = 0; // Helper function for canvas animations window.requestAnimFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(cb) { window.setTimeout(callback, 1000 / 60); } })(); // Helper function to return random numbers within a specified range function random(min, max) { return Math.random() * (max - min) + min; } // Helper function to calculate the distance between 2 points function calculateDistance(p1x, p1y, p2x, p2y) { var xDistance = p1x - p2x; var yDistance = p1y - p2y; return Math.sqrt(Math.pow(xDistance, 2) + Math.pow(yDistance, 2)); } // Setup some basic variables var canvas = document.getElementById('canvas'); var canvasCtx = canvas.getContext('2d'); var canvasWidth = window.innerWidth; var canvasHeight = window.innerHeight; // Resize canvas canvas.width = canvasWidth; canvas.height = canvasHeight; // Firework class function Firework(sx, sy, tx, ty) { // Set coordinates (x/y = actual, sx/sy = starting, tx/ty = target) this.x = this.sx = sx; this.y = this.sy = sy; this.tx = tx; this.ty = ty; // Calculate distance between starting and target point this.distanceToTarget = calculateDistance(sx, sy, tx, ty); this.distanceTraveled = 0; // To simulate a trail effect, the last few coordinates will be stored this.coordinates = []; this.coordinateCount = 3; // Populate coordinate array with initial data while(this.coordinateCount--) { this.coordinates.push([this.x, this.y]); } // Some settings, you can adjust them if you'd like to do so. this.angle = Math.atan2(ty - sy, tx - sx); this.speed = options.rocketSpeed; this.acceleration = options.rocketAcceleration; this.brightness = random(50, 80); this.hue = currentHue; this.targetRadius = 1; this.targetDirection = false; // false = Radius is getting bigger, true = Radius is getting smaller // Increase the rockets launched counter cntRocketsLaunched++; }; // This method should be called each frame to update the firework Firework.prototype.update = function(index) { // Update the coordinates array this.coordinates.pop(); this.coordinates.unshift([this.x, this.y]); // Cycle the target radius (used for the pulsing target circle) if(!this.targetDirection) { if(this.targetRadius < 8) this.targetRadius += 0.15; else this.targetDirection = true; } else { if(this.targetRadius > 1) this.targetRadius -= 0.15; else this.targetDirection = false; } // Speed up the firework (could possibly travel faster than the speed of light) this.speed *= this.acceleration; // Calculate the distance the firework has travelled so far (based on velocities) var vx = Math.cos(this.angle) * this.speed; var vy = Math.sin(this.angle) * this.speed; this.distanceTraveled = calculateDistance(this.sx, this.sy, this.x + vx, this.y + vy); // If the distance traveled (including velocities) is greater than the initial distance // to the target, then the target has been reached. If that's not the case, keep traveling. if(this.distanceTraveled >= this.distanceToTarget) { createParticles(this.tx, this.ty); fireworks.splice(index, 1); } else { this.x += vx; this.y += vy; } }; // Draws the firework Firework.prototype.draw = function() { var lastCoordinate = this.coordinates[this.coordinates.length - 1]; // Draw the rocket canvasCtx.beginPath(); canvasCtx.moveTo(lastCoordinate[0], lastCoordinate[1]); canvasCtx.lineTo(this.x, this.y); canvasCtx.strokeStyle = 'hsl(' + this.hue + ',100%,' + this.brightness + '%)'; canvasCtx.stroke(); // Draw the target (pulsing circle) if(options.showTargets) { canvasCtx.beginPath(); canvasCtx.arc(this.tx, this.ty, this.targetRadius, 0, Math.PI * 2); canvasCtx.stroke(); } }; // Particle class function Particle(x, y) { // Set the starting point this.x = x; this.y = y; // To simulate a trail effect, the last few coordinates will be stored this.coordinates = []; this.coordinateCount = 5; // Populate coordinate array with initial data while(this.coordinateCount--) { this.coordinates.push([this.x, this.y]); } // Set a random angle in all possible directions (radians) this.angle = random(0, Math.PI * 2); this.speed = random(1, 10); // Add some friction and gravity to the particle this.friction = options.particleFriction; this.gravity = options.particleGravity; // Change the hue to a random number this.hue = random(currentHue - 20, currentHue + 20); this.brightness = random(50, 80); this.alpha = 1; // Set how fast the particles decay this.decay = random(0.01, 0.03); } // Updates the particle, should be called each frame Particle.prototype.update = function(index) { // Update the coordinates array this.coordinates.pop(); this.coordinates.unshift([this.x, this.y]); // Slow it down (based on friction) this.speed *= this.friction; // Apply velocity to the particle this.x += Math.cos(this.angle) * this.speed; this.y += Math.sin(this.angle) * this.speed + this.gravity; // Fade out the particle, and remove it if alpha is low enough this.alpha -= this.decay; if(this.alpha <= this.decay) { particles.splice(index, 1); } } // Draws the particle Particle.prototype.draw = function() { var lastCoordinate = this.coordinates[this.coordinates.length - 1]; var radius = Math.round(random(options.particleMinRadius, options.particleMaxRadius)); // Create a new shiny gradient var gradient = canvasCtx.createRadialGradient(this.x, this.y, 0, this.x, this.y, radius); gradient.addColorStop(0.0, 'white'); gradient.addColorStop(0.1, 'white'); gradient.addColorStop(0.1, 'hsla(' + this.hue + ',100%,' + this.brightness + '%,' + this.alpha + ')'); gradient.addColorStop(1.0, 'black'); // Draw the gradient canvasCtx.beginPath(); canvasCtx.fillStyle = gradient; canvasCtx.arc(this.x, this.y, radius, Math.PI * 2, false); canvasCtx.fill(); } // Create a bunch of particles at the given position function createParticles(x, y) { var particleCount = Math.round(random(options.particleMinCount, options.particleMaxCount)); while(particleCount--) { particles.push(new Particle(x, y)); } } // Add an event listener to the window so we're able to react to size changes window.addEventListener('resize', function(e) { canvas.width = canvasWidth = window.innerWidth; canvas.height = canvasHeight = window.innerHeight; }); // Add event listeners to the canvas to handle mouse interactions canvas.addEventListener('mousemove', function(e) { e.preventDefault(); mouse.x = e.pageX - canvas.offsetLeft; mouse.y = e.pageY - canvas.offsetTop; }); canvas.addEventListener('mousedown', function(e) { e.preventDefault(); mouse.down = true; }); canvas.addEventListener('mouseup', function(e) { e.preventDefault(); mouse.down = false; }); // Main application / script, called when the window is loaded function gameLoop() { // This function will rund endlessly by using requestAnimationFrame (or fallback to setInterval) requestAnimFrame(gameLoop); // Increase the hue to get different colored fireworks over time currentHue += 0.5; // 'Clear' the canvas at a specific opacity, by using 'destination-out'. This will create a trailing effect. canvasCtx.globalCompositeOperation = 'destination-out'; canvasCtx.fillStyle = 'rgba(0, 0, 0, 0.5)'; canvasCtx.fillRect(0, 0, canvasWidth, canvasHeight); canvasCtx.globalCompositeOperation = 'lighter'; // Loop over all existing fireworks (they should be updated & drawn) var i = fireworks.length; while(i--) { fireworks[i].draw(); fireworks[i].update(i); } // Loop over all existing particles (they should be updated & drawn) var i = particles.length; while(i--) { particles[i].draw(); particles[i].update(i); } // Draw some text canvasCtx.fillStyle = 'white'; canvasCtx.font = '14px Arial'; canvasCtx.fillText('Rockets launched: ' + cntRocketsLaunched, 10, 24); // Launch fireworks automatically to random coordinates, if the user does not interact with the scene if(timerTick >= options.timerInterval) { if(!mouse.down) { fireworks.push(new Firework(canvasWidth / 2, canvasHeight, random(0, canvasWidth), random(0, canvasHeight / 2))); timerTick = 0; } } else { timerTick++; } // Limit the rate at which fireworks can be spawned by mouse if(clickLimiterTick >= options.clickLimiter) { if(mouse.down) { fireworks.push(new Firework(canvasWidth / 2, canvasHeight, mouse.x, mouse.y)); clickLimiterTick = 0; } } else { clickLimiterTick++; } } window.onload = gameLoop();
上一篇:Hive SchemaTool 命令详解


下一篇:RabbitMQ3.13.x之六_RabbitMQ使用场景