对画布粒子应用随机旋转

我正在尝试更新现有的粒子动画。在这个演示中,粒子只是具有不同lineWidths 的线条,它们在下落时具有随机大小和旋转。

我的目标是用不同的形状替换线条,如下图所示,其他所有内容保持原样。

http://img3.mukewang.com/61b5c9680001ba5601760333.jpg

我已经改变了形状,但我有几个问题:

  1. 它不再像上面发布的原始演示链接中那样旋转。

  2. 因为,我用形状的图像替换了线条,如果我增加粒子,我也会面临性能问题。

  3. 如果我随机化大小,它会不断更新形状的大小,而不保留第一个随机大小。

context.drawImage(svg, x, y, 20, 40)

                  |

                  v

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

任何人都可以指出我应该解决上述问题的正确方向。感谢任何帮助!


白衣染霜花
浏览 158回答 1
1回答

幕布斯6054654

好的,这就是我所做的:我改为drawParticles应用particle.tilt.我将svg变量移到顶部,以便重复使用而不是多次加载。我确实设置了随机大小,resetParticle所以它之后不会改变。var confetti = {&nbsp; maxCount: 150,&nbsp; &nbsp; &nbsp; &nbsp; //set max confetti count&nbsp; speed: 1,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//set the particle animation speed&nbsp; frameInterval: 30,&nbsp; &nbsp; //the confetti animation frame interval in milliseconds&nbsp; alpha: 1.0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//the alpha opacity of the confetti (between 0 and 1, where 1 is opaque and 0 is invisible)&nbsp; gradient: false,&nbsp; //whether to use gradients for the confetti particles&nbsp; start: null,&nbsp; &nbsp; &nbsp; //call to start confetti animation (with optional timeout in milliseconds, and optional min and max random confetti count)&nbsp; stop: null,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//call to stop adding confetti&nbsp; toggle: null,&nbsp; &nbsp; &nbsp;//call to start or stop the confetti animation depending on whether it's already running&nbsp; pause: null,&nbsp; &nbsp; &nbsp; //call to freeze confetti animation&nbsp; resume: null,&nbsp; &nbsp; &nbsp;//call to unfreeze confetti animation&nbsp; togglePause: null,&nbsp; &nbsp; //call to toggle whether the confetti animation is paused&nbsp; remove: null,&nbsp; &nbsp; &nbsp;//call to stop the confetti animation and remove all confetti immediately&nbsp; isPaused: null,&nbsp; &nbsp; &nbsp; &nbsp;//call and returns true or false depending on whether the confetti animation is paused&nbsp; isRunning: null&nbsp; &nbsp; &nbsp; &nbsp;//call and returns true or false depending on whether the animation is running};(function () {&nbsp; confetti.start = startConfetti;&nbsp; confetti.stop = stopConfetti;&nbsp; confetti.toggle = toggleConfetti;&nbsp; confetti.pause = pauseConfetti;&nbsp; confetti.resume = resumeConfetti;&nbsp; confetti.togglePause = toggleConfettiPause;&nbsp; confetti.isPaused = isConfettiPaused;&nbsp; confetti.remove = removeConfetti;&nbsp; confetti.isRunning = isConfettiRunning;&nbsp; var supportsAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame;&nbsp; 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,"];&nbsp; var streamingConfetti = false;&nbsp; var animationTimer = null;&nbsp; var pause = false;&nbsp; var lastFrameTime = Date.now();&nbsp; var particles = [];&nbsp; var waveAngle = 0;&nbsp; var context = null;&nbsp;&nbsp;&nbsp; var sizes = [];&nbsp;&nbsp; var svg = new Image();&nbsp;&nbsp;&nbsp; svg.src = 'https://i.postimg.cc/TPBmVXH1/confetti.png';&nbsp; function getRandomInt(min, max) {&nbsp; &nbsp; min = Math.ceil(min);&nbsp; &nbsp; max = Math.floor(max);&nbsp; &nbsp; return Math.floor(Math.random() * (max - min + 1)) + min;&nbsp; }&nbsp; function resetParticle(particle, width, height) {&nbsp; &nbsp; particle.color = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")");&nbsp; &nbsp; particle.color2 = colors[(Math.random() * colors.length) | 0] + (confetti.alpha + ")");&nbsp; &nbsp; particle.x = getRandomInt(0, width);&nbsp; &nbsp; particle.y = getRandomInt(-height / 2, 0);&nbsp; &nbsp; particle.diameter = Math.random() * 10 + 5;&nbsp; &nbsp; particle.tilt = Math.random() * 10 - 10;&nbsp; &nbsp; particle.tiltAngleIncrement = Math.random() * 0.07 + 0.05;&nbsp; &nbsp; particle.tiltAngle = Math.random() * Math.PI;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; particle.width = Math.random() * 20&nbsp; &nbsp; particle.height = Math.random() * 40&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; return particle;&nbsp; }&nbsp; function toggleConfettiPause() {&nbsp; &nbsp; if (pause)&nbsp; &nbsp; &nbsp; resumeConfetti();&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; pauseConfetti();&nbsp; }&nbsp; function isConfettiPaused() {&nbsp; &nbsp; return pause;&nbsp; }&nbsp; function pauseConfetti() {&nbsp; &nbsp; pause = true;&nbsp; }&nbsp; function resumeConfetti() {&nbsp; &nbsp; pause = false;&nbsp; &nbsp; runAnimation();&nbsp; }&nbsp; function runAnimation() {&nbsp; &nbsp; if (pause)&nbsp; &nbsp; &nbsp; return;&nbsp; &nbsp; else if (particles.length === 0) {&nbsp; &nbsp; &nbsp; context.clearRect(0, 0, window.innerWidth, window.innerHeight);&nbsp; &nbsp; &nbsp; animationTimer = null;&nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; var now = Date.now();&nbsp; &nbsp; &nbsp; var delta = now - lastFrameTime;&nbsp; &nbsp; &nbsp; if (!supportsAnimationFrame || delta > confetti.frameInterval) {&nbsp; &nbsp; &nbsp; &nbsp; context.clearRect(0, 0, window.innerWidth, window.innerHeight);&nbsp; &nbsp; &nbsp; &nbsp; updateParticles();&nbsp; &nbsp; &nbsp; &nbsp; drawParticles(context);&nbsp; &nbsp; &nbsp; &nbsp; lastFrameTime = now - (delta % confetti.frameInterval);&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; animationTimer = requestAnimationFrame(runAnimation);&nbsp; &nbsp; }&nbsp; }&nbsp; function startConfetti(timeout, min, max) {&nbsp; &nbsp; var width = window.innerWidth;&nbsp; &nbsp; var height = window.innerHeight;&nbsp; &nbsp; window.requestAnimationFrame = (function () {&nbsp; &nbsp; &nbsp; return window.requestAnimationFrame ||&nbsp; &nbsp; &nbsp; &nbsp; window.webkitRequestAnimationFrame ||&nbsp; &nbsp; &nbsp; &nbsp; window.mozRequestAnimationFrame ||&nbsp; &nbsp; &nbsp; &nbsp; window.oRequestAnimationFrame ||&nbsp; &nbsp; &nbsp; &nbsp; window.msRequestAnimationFrame ||&nbsp; &nbsp; &nbsp; &nbsp; function (callback) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return window.setTimeout(callback, confetti.frameInterval);&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; })();&nbsp; &nbsp; var canvas = document.getElementById("confetti-canvas");&nbsp; &nbsp; if (canvas === null) {&nbsp; &nbsp; &nbsp; canvas = document.createElement("canvas");&nbsp; &nbsp; &nbsp; canvas.setAttribute("id", "confetti-canvas");&nbsp; &nbsp; &nbsp; canvas.setAttribute("style", "display:block;z-index:999999;pointer-events:none;position:fixed;top:0");&nbsp; &nbsp; &nbsp; document.body.prepend(canvas);&nbsp; &nbsp; &nbsp; canvas.width = width;&nbsp; &nbsp; &nbsp; canvas.height = height;&nbsp; &nbsp; &nbsp; window.addEventListener("resize", function () {&nbsp; &nbsp; &nbsp; &nbsp; canvas.width = window.innerWidth;&nbsp; &nbsp; &nbsp; &nbsp; canvas.height = window.innerHeight;&nbsp; &nbsp; &nbsp; }, true);&nbsp; &nbsp; &nbsp; context = canvas.getContext("2d");&nbsp; &nbsp; } else if (context === null)&nbsp; &nbsp; &nbsp; context = canvas.getContext("2d");&nbsp; &nbsp; var count = confetti.maxCount;&nbsp; &nbsp; if (min) {&nbsp; &nbsp; &nbsp; if (max) {&nbsp; &nbsp; &nbsp; &nbsp; if (min == max)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count = particles.length + max;&nbsp; &nbsp; &nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (min > max) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var temp = min;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; min = max;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; max = temp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; count = particles.length + ((Math.random() * (max - min) + min) | 0);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; } else&nbsp; &nbsp; &nbsp; &nbsp; count = particles.length + min;&nbsp; &nbsp; } else if (max)&nbsp; &nbsp; &nbsp; count = particles.length + max;&nbsp; &nbsp; while (particles.length < count)&nbsp; &nbsp; &nbsp; particles.push(resetParticle({}, width, height));&nbsp; &nbsp; streamingConfetti = true;&nbsp; &nbsp; pause = false;&nbsp; &nbsp; runAnimation();&nbsp; &nbsp; if (timeout) {&nbsp; &nbsp; &nbsp; window.setTimeout(stopConfetti, timeout);&nbsp; &nbsp; }&nbsp; }&nbsp; function stopConfetti() {&nbsp; &nbsp; streamingConfetti = false;&nbsp; }&nbsp; function removeConfetti() {&nbsp; &nbsp; stop();&nbsp; &nbsp; pause = false;&nbsp; &nbsp; particles = [];&nbsp; }&nbsp; function toggleConfetti() {&nbsp; &nbsp; if (streamingConfetti)&nbsp; &nbsp; &nbsp; stopConfetti();&nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; startConfetti();&nbsp; }&nbsp; function isConfettiRunning() {&nbsp; &nbsp; return streamingConfetti;&nbsp; }&nbsp; function drawParticles(context) {&nbsp; &nbsp; var particle;&nbsp; &nbsp; var x, y, x2, y2;&nbsp; &nbsp; for (var i = 0; i < particles.length; i++) {&nbsp; &nbsp; &nbsp; particle = particles[i];&nbsp; &nbsp; &nbsp; particleWidth = particle.diameter;&nbsp; &nbsp; &nbsp; x2 = particle.x + particle.tilt;&nbsp; &nbsp; &nbsp; x = x2 + particle.diameter / 2;&nbsp; &nbsp; &nbsp; y = particle.y;&nbsp; &nbsp; &nbsp; context.save();&nbsp; &nbsp; &nbsp; context.translate(x, y);&nbsp; &nbsp; &nbsp; context.rotate(particle.tilt / 180 * Math.PI);&nbsp; &nbsp; &nbsp; context.translate(-x, -y);&nbsp; &nbsp; &nbsp; context.drawImage(svg, x, y, particle.width, particle.height);&nbsp; &nbsp; &nbsp; context.restore();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; /*context.beginPath();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.lineWidth = particle.diameter;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x2 = particle.x + particle.tilt;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; x = x2 + particle.diameter / 2;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y2 = particle.y + particle.tilt + particle.diameter / 2;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (confetti.gradient) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var gradient = context.createLinearGradient(x, particle.y, x2, y2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gradient.addColorStop("0", particle.color);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; gradient.addColorStop("1.0", particle.color2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.strokeStyle = gradient;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.strokeStyle = particle.color;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.moveTo(x, particle.y);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.lineTo(x2, y2);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; context.stroke();*/&nbsp; &nbsp; }&nbsp; }&nbsp; function updateParticles() {&nbsp; &nbsp; var width = window.innerWidth;&nbsp; &nbsp; var height = window.innerHeight;&nbsp; &nbsp; var particle;&nbsp; &nbsp; waveAngle += 0.01;&nbsp; &nbsp; for (var i = 0; i < particles.length; i++) {&nbsp; &nbsp; &nbsp; particle = particles[i];&nbsp; &nbsp; &nbsp; if (!streamingConfetti && particle.y < -15)&nbsp; &nbsp; &nbsp; &nbsp; particle.y = height + 100;&nbsp; &nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; particle.tiltAngle += particle.tiltAngleIncrement;&nbsp; &nbsp; &nbsp; &nbsp; particle.x += Math.sin(waveAngle) - 0.5;&nbsp; &nbsp; &nbsp; &nbsp; particle.y += (Math.cos(waveAngle) + particle.diameter + confetti.speed) * 0.5;&nbsp; &nbsp; &nbsp; &nbsp; particle.tilt = Math.sin(particle.tiltAngle) * 15;&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; if (particle.x > width + 20 || particle.x < -20 || particle.y > height) {&nbsp; &nbsp; &nbsp; &nbsp; if (streamingConfetti && particles.length <= confetti.maxCount)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; resetParticle(particle, width, height);&nbsp; &nbsp; &nbsp; &nbsp; else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; particles.splice(i, 1);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; i--;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; }&nbsp; startConfetti(5000, 20, 25)})();html {&nbsp; height: 100%;}body, html {&nbsp; margin: 0;}body {&nbsp; background: black;}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript