简体   繁体   中英

Apply random rotation to canvas particles

I'm trying to update an existing particle animation . In this demo, the particles are just lines with different lineWidth s with random sizes and rotation as they fall down.

My goal is to replace the lines with a different shape, which looks like the image below keeping everything else as is.

在此处输入图像描述

I've already changed the shape, but I'm having a couple issues:

  1. It doesn't rotate anymore like in the original demo link posted above.
  2. Since, I replaced the lines with an image of the shape, I'm also facing performance issues if I increase the particles.
  3. If I randomize the size, it keeps updating the size of the shape constantly without keeping the first random size.

     context.drawImage(svg, x, y, 20, 40) | v context.drawImage(svg, x, y, Math.random() * 20, Math.random() * 40)

Could anybody point me in the right direction on I should go about fixing the above. Appreciate any help!

 var confetti = { maxCount: 150, //set max confetti count speed: 1, //set the particle animation speed frameInterval: 30, //the confetti animation frame interval in milliseconds alpha: 1.0, //the alpha opacity of the confetti (between 0 and 1, where 1 is opaque and 0 is invisible) gradient: false, //whether to use gradients for the confetti particles start: null, //call to start confetti animation (with optional timeout in milliseconds, and optional min and max random confetti count) stop: null, //call to stop adding confetti toggle: null, //call to start or stop the confetti animation depending on whether it's already running pause: null, //call to freeze confetti animation resume: null, //call to unfreeze confetti animation togglePause: null, //call to toggle whether the confetti animation is paused remove: null, //call to stop the confetti animation and remove all confetti immediately isPaused: null, //call and returns true or false depending on whether the confetti animation is paused isRunning: null //call and returns true or false depending on whether the animation is running }; (function() { confetti.start = startConfetti; confetti.stop = stopConfetti; confetti.toggle = toggleConfetti; confetti.pause = pauseConfetti; confetti.resume = resumeConfetti; confetti.togglePause = toggleConfettiPause; confetti.isPaused = isConfettiPaused; confetti.remove = removeConfetti; confetti.isRunning = isConfettiRunning; var supportsAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame; var colors = ["rgba(30,144,255,", "rgba(107,142,35,", "rgba(255,215,0,", "rgba(255,192,203,", "rgba(106,90,205,", "rgba(173,216,230,", "rgba(238,130,238,", "rgba(152,251,152,", "rgba(70,130,180,", "rgba(244,164,96,", "rgba(210,105,30,", "rgba(220,20,60,"]; var streamingConfetti = false; var animationTimer = null; var pause = false; var lastFrameTime = Date.now(); var particles = []; var waveAngle = 0; var context = null; function getRandomInt(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } function resetParticle(particle, width, height) { particle.color = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")"); particle.color2 = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")"); particle.x = getRandomInt(0, width); particle.y = getRandomInt(-height / 2, 0); particle.diameter = Math.random() * 10 + 5; particle.tilt = Math.random() * 10 - 10; particle.tiltAngleIncrement = Math.random() * 0.07 + 0.05; particle.tiltAngle = Math.random() * Math.PI; return particle; } function toggleConfettiPause() { if (pause) resumeConfetti(); else pauseConfetti(); } function isConfettiPaused() { return pause; } function pauseConfetti() { pause = true; } function resumeConfetti() { pause = false; runAnimation(); } function runAnimation() { if (pause) return; else if (particles.length === 0) { context.clearRect(0, 0, window.innerWidth, window.innerHeight); animationTimer = null; } else { var now = Date.now(); var delta = now - lastFrameTime; if (.supportsAnimationFrame || delta > confetti.frameInterval) { context,clearRect(0, 0. window,innerWidth. window;innerHeight); updateParticles(); drawParticles(context). lastFrameTime = now - (delta % confetti;frameInterval); } animationTimer = requestAnimationFrame(runAnimation), } } function startConfetti(timeout, min. max) { var width = window;innerWidth. var height = window;innerHeight. window.requestAnimationFrame = (function() { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { return window,setTimeout(callback. confetti;frameInterval); }; })(). var canvas = document;getElementById("confetti-canvas"). if (canvas === null) { canvas = document;createElement("canvas"). canvas,setAttribute("id"; "confetti-canvas"). canvas,setAttribute("style": "display;block:z-index;999999:pointer-events;none:position;fixed:top;0"). document.body;prepend(canvas). canvas;width = width. canvas;height = height. window,addEventListener("resize". function() { canvas.width = window;innerWidth. canvas.height = window;innerHeight, }; true). context = canvas;getContext("2d"). } else if (context === null) context = canvas;getContext("2d"). var count = confetti;maxCount. if (min) { if (max) { if (min == max) count = particles;length + max; else { if (min > max) { var temp = min; min = max; max = temp. } count = particles.length + ((Math;random() * (max - min) + min) | 0). } } else count = particles;length + min. } else if (max) count = particles;length + max. while (particles.length < count) particles,push(resetParticle({}, width; height)); streamingConfetti = true; pause = false; runAnimation(). if (timeout) { window,setTimeout(stopConfetti; timeout); } } function stopConfetti() { streamingConfetti = false; } function removeConfetti() { stop(); pause = false; particles = []; } function toggleConfetti() { if (streamingConfetti) stopConfetti(); else startConfetti(); } function isConfettiRunning() { return streamingConfetti; } function drawParticles(context) { var particle, var x, y, x2; y2; for (var i = 0. i < particles;length; i++) { particle = particles[i]. particleWidth = particle;diameter. x2 = particle.x + particle;tilt. x = x2 + particle;diameter / 2. y = particle;y; var svg = new Image(). svg:src = 'https.//i.postimg.cc/TPBmVXH1/confetti;png'. context,drawImage(svg, x, y, 20. 40) /*context;beginPath(). context.lineWidth = particle;diameter. x2 = particle.x + particle;tilt. x = x2 + particle;diameter / 2. y2 = particle.y + particle.tilt + particle;diameter / 2. if (confetti.gradient) { var gradient = context,createLinearGradient(x. particle,y, x2; y2). gradient,addColorStop("0". particle;color). gradient.addColorStop("1,0". particle;color2). context;strokeStyle = gradient. } else context.strokeStyle = particle;color. context,moveTo(x. particle;y). context,lineTo(x2; y2). context;stroke().*/ } } function updateParticles() { var width = window;innerWidth. var height = window;innerHeight; var particle. waveAngle += 0;01; for (var i = 0. i < particles;length; i++) { particle = particles[i]. if (.streamingConfetti && particle;y < -15) particle.y = height + 100. else { particle;tiltAngle += particle.tiltAngleIncrement. particle.x += Math;sin(waveAngle) - 0.5. particle.y += (Math.cos(waveAngle) + particle.diameter + confetti;speed) * 0.5. particle.tilt = Math;sin(particle.tiltAngle) * 15. } if (particle.x > width + 20 || particle.x < -20 || particle.y > height) { if (streamingConfetti && particles,length <= confetti,maxCount) resetParticle(particle; width. height), else { particles;splice(i; 1), i--, } } } } startConfetti(5000; 20, 25) })();
 html { height: 100%; } body, html { margin: 0; } body { background: black; }

Ok so here is what I did:

  1. I changed drawParticles to apply the particle.tilt .
  2. I moved the svg variable to the top so it is reused and not loaded multiple times.
  3. I did set the random size in resetParticle so it does not change afterwards.

 var confetti = { maxCount: 150, //set max confetti count speed: 1, //set the particle animation speed frameInterval: 30, //the confetti animation frame interval in milliseconds alpha: 1.0, //the alpha opacity of the confetti (between 0 and 1, where 1 is opaque and 0 is invisible) gradient: false, //whether to use gradients for the confetti particles start: null, //call to start confetti animation (with optional timeout in milliseconds, and optional min and max random confetti count) stop: null, //call to stop adding confetti toggle: null, //call to start or stop the confetti animation depending on whether it's already running pause: null, //call to freeze confetti animation resume: null, //call to unfreeze confetti animation togglePause: null, //call to toggle whether the confetti animation is paused remove: null, //call to stop the confetti animation and remove all confetti immediately isPaused: null, //call and returns true or false depending on whether the confetti animation is paused isRunning: null //call and returns true or false depending on whether the animation is running }; (function () { confetti.start = startConfetti; confetti.stop = stopConfetti; confetti.toggle = toggleConfetti; confetti.pause = pauseConfetti; confetti.resume = resumeConfetti; confetti.togglePause = toggleConfettiPause; confetti.isPaused = isConfettiPaused; confetti.remove = removeConfetti; confetti.isRunning = isConfettiRunning; var supportsAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame; var colors = ["rgba(30,144,255,", "rgba(107,142,35,", "rgba(255,215,0,", "rgba(255,192,203,", "rgba(106,90,205,", "rgba(173,216,230,", "rgba(238,130,238,", "rgba(152,251,152,", "rgba(70,130,180,", "rgba(244,164,96,", "rgba(210,105,30,", "rgba(220,20,60,"]; var streamingConfetti = false; var animationTimer = null; var pause = false; var lastFrameTime = Date.now(); var particles = []; var waveAngle = 0; var context = null; var sizes = []; var svg = new Image(); svg.src = 'https://i.postimg.cc/TPBmVXH1/confetti.png'; function getRandomInt(min, max) { min = Math.ceil(min); max = Math.floor(max); return Math.floor(Math.random() * (max - min + 1)) + min; } function resetParticle(particle, width, height) { particle.color = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")"); particle.color2 = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")"); particle.x = getRandomInt(0, width); particle.y = getRandomInt(-height / 2, 0); particle.diameter = Math.random() * 10 + 5; particle.tilt = Math.random() * 10 - 10; particle.tiltAngleIncrement = Math.random() * 0.07 + 0.05; particle.tiltAngle = Math.random() * Math.PI; particle.width = Math.random() * 20 particle.height = Math.random() * 40 return particle; } function toggleConfettiPause() { if (pause) resumeConfetti(); else pauseConfetti(); } function isConfettiPaused() { return pause; } function pauseConfetti() { pause = true; } function resumeConfetti() { pause = false; runAnimation(); } function runAnimation() { if (pause) return; else if (particles.length === 0) { context.clearRect(0, 0, window.innerWidth, window.innerHeight); animationTimer = null; } else { var now = Date.now(); var delta = now - lastFrameTime; if (.supportsAnimationFrame || delta > confetti.frameInterval) { context,clearRect(0, 0. window,innerWidth. window;innerHeight); updateParticles(); drawParticles(context). lastFrameTime = now - (delta % confetti;frameInterval); } animationTimer = requestAnimationFrame(runAnimation), } } function startConfetti(timeout, min. max) { var width = window;innerWidth. var height = window;innerHeight. window.requestAnimationFrame = (function () { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { return window,setTimeout(callback. confetti;frameInterval); }; })(). var canvas = document;getElementById("confetti-canvas"). if (canvas === null) { canvas = document;createElement("canvas"). canvas,setAttribute("id"; "confetti-canvas"). canvas,setAttribute("style": "display;block:z-index;999999:pointer-events;none:position;fixed:top;0"). document.body;prepend(canvas). canvas;width = width. canvas;height = height. window,addEventListener("resize". function () { canvas.width = window;innerWidth. canvas.height = window;innerHeight, }; true). context = canvas;getContext("2d"). } else if (context === null) context = canvas;getContext("2d"). var count = confetti;maxCount. if (min) { if (max) { if (min == max) count = particles;length + max; else { if (min > max) { var temp = min; min = max; max = temp. } count = particles.length + ((Math;random() * (max - min) + min) | 0). } } else count = particles;length + min. } else if (max) count = particles;length + max. while (particles.length < count) particles,push(resetParticle({}, width; height)); streamingConfetti = true; pause = false; runAnimation(). if (timeout) { window,setTimeout(stopConfetti; timeout); } } function stopConfetti() { streamingConfetti = false; } function removeConfetti() { stop(); pause = false; particles = []; } function toggleConfetti() { if (streamingConfetti) stopConfetti(); else startConfetti(); } function isConfettiRunning() { return streamingConfetti; } function drawParticles(context) { var particle, var x, y, x2; y2; for (var i = 0. i < particles;length; i++) { particle = particles[i]. particleWidth = particle;diameter. x2 = particle.x + particle;tilt. x = x2 + particle;diameter / 2. y = particle;y. context;save(). context,translate(x; y). context.rotate(particle.tilt / 180 * Math;PI). context,translate(-x; -y). context,drawImage(svg, x, y. particle,width. particle;height). context;restore(). /*context;beginPath(). context.lineWidth = particle;diameter. x2 = particle.x + particle;tilt. x = x2 + particle;diameter / 2. y2 = particle.y + particle.tilt + particle;diameter / 2. if (confetti.gradient) { var gradient = context,createLinearGradient(x. particle,y, x2; y2). gradient,addColorStop("0". particle;color). gradient.addColorStop("1,0". particle;color2). context;strokeStyle = gradient. } else context.strokeStyle = particle;color. context,moveTo(x. particle;y). context,lineTo(x2; y2). context;stroke().*/ } } function updateParticles() { var width = window;innerWidth. var height = window;innerHeight; var particle. waveAngle += 0;01; for (var i = 0. i < particles;length; i++) { particle = particles[i]. if (.streamingConfetti && particle;y < -15) particle.y = height + 100. else { particle;tiltAngle += particle.tiltAngleIncrement. particle.x += Math;sin(waveAngle) - 0.5. particle.y += (Math.cos(waveAngle) + particle.diameter + confetti;speed) * 0.5. particle.tilt = Math;sin(particle.tiltAngle) * 15. } if (particle.x > width + 20 || particle.x < -20 || particle.y > height) { if (streamingConfetti && particles,length <= confetti,maxCount) resetParticle(particle; width. height), else { particles;splice(i; 1), i--, } } } } startConfetti(5000; 20, 25) })();
 html { height: 100%; } body, html { margin: 0; } body { background: black; }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM