为了账号安全,请及时绑定邮箱和手机立即绑定

对画布粒子应用随机旋转

对画布粒子应用随机旋转

白衣染霜花 2021-12-12 18:05:02
我正在尝试更新现有的粒子动画。在这个演示中,粒子只是具有不同lineWidths 的线条,它们在下落时具有随机大小和旋转。我的目标是用不同的形状替换线条,如下图所示,其他所有内容保持原样。我已经改变了形状,但我有几个问题:它不再像上面发布的原始演示链接中那样旋转。因为,我用形状的图像替换了线条,如果我增加粒子,我也会面临性能问题。如果我随机化大小,它会不断更新形状的大小,而不保留第一个随机大小。context.drawImage(svg, x, y, 20, 40)                  |                  vcontext.drawImage(svg, x, y, Math.random() * 20, Math.random() * 40)任何人都可以指出我应该解决上述问题的正确方向。感谢任何帮助!
查看完整描述

1 回答

?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

好的,这就是我所做的:

  1. 我改为drawParticles应用particle.tilt.

  2. 我将svg变量移到顶部,以便重复使用而不是多次加载。

  3. 我确实设置了随机大小,resetParticle所以它之后不会改变。

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;

}


查看完整回答
反对 回复 2021-12-12
  • 1 回答
  • 0 关注
  • 157 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号