如何降低画布动画的速度?

问题描述 投票:0回答:2

我正在使用java脚本& canvas创建一个动画。我使用一个fiddle作为参考,目前对象随机生成&从右上角落到左下角,这是好的,但问题是速度的对象生成&落在高速。我想让动画流有点慢& 平滑.我是新的画布编程,任何帮助将是非常有用的。

(function() {
  var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame ||
    function(callback) {
      window.setTimeout(callback, 1000 / 60);
    };
  window.requestAnimationFrame = requestAnimationFrame;
})();

var particleArr = [],
  canvas = document.getElementById("canvas"),
  ctx = canvas.getContext("2d"),
  flakeCount = 700,
  mouseX = -100,
  mouseY = -100,
  xMultiplier = 0.015


canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

function getRandomColor() {
  // Random Color Generate
  const colorArr = ["rgba(215,88,69, 1)", "rgba(117, 161, 199, 1)"]; // Blue & Orange Color
  const randomColor = colorArr[Math.floor(Math.random() * colorArr.length)];

  return randomColor;
}

function flow() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  for (var i = 0; i < flakeCount; i++) {
    var flake = particleArr[i],
      x = mouseX,
      y = mouseY,
      minDist = 150,
      x2 = flake.x,
      y2 = flake.y;

    var dist = Math.sqrt((x2 - x) * (x2 - x) + (y2 - y) * (y2 - y)),
      dx = x2 - x,
      dy = y2 - y;

    if (dist < minDist) {
      var force = minDist / (dist * dist),
        xcomp = (x - x2) / dist,
        ycomp = (y - y2) / dist,
        deltaV = force / 2;

      flake.velX -= deltaV * xcomp;
      flake.velY -= deltaV * ycomp;

    } else {
      flake.velX *= .98;
      if (flake.velY <= flake.speed) {
        flake.velY = flake.speed
      }
      flake.velX += Math.cos(flake.step += .05) * flake.stepSize;
    }

    ctx.fillStyle = getRandomColor();

    flake.y += flake.velY;
    flake.x += flake.velX;

    if (flake.y >= canvas.height || flake.y <= 0) {
      reset(flake);
    }

    if (flake.x >= canvas.width || flake.x <= 0) {
      reset(flake);
    }

    ctx.beginPath();
    ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);
    ctx.fill();
  }
  requestAnimationFrame(flow);

};

function reset(flake) {
  let temp = (Math.random() * 1) + 0.5;
  flake.x = canvas.width;
  flake.y = 50;
  flake.size = (Math.random() * 3) + 5;
  flake.speed = (Math.random() * 7) + 0.5;
  flake.velY = flake.speed;
  flake.velX = -xMultiplier * canvas.width * temp;
  // flake.opacity = (Math.random() * 0.5) + 0.3;
}

function init() {
  for (var i = 0; i < flakeCount; i++) {
    var x = canvas.width,
      y = 50,
      size = (Math.random() * 3) + 5,
      // speed = (Math.random() * 1) + 0.5;
      speed = 0;
    // opacity = (Math.random() * 0.5) + 0.3;

    particleArr.push({
      speed: speed,
      velY: speed,
      velX: -xMultiplier * canvas.width * speed,
      x: x,
      y: y,
      size: size,
      stepSize: (Math.random()) / 30,
      step: 0,
      angle: 360
      // opacity: opacity
    });
  }

  flow();
};

canvas.addEventListener("mousemove", function(e) {
  mouseX = e.clientX,
    mouseY = e.clientY
});

window.addEventListener('resize', onWindowResize, false);

function onWindowResize() {

  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
}

init();
canvas {
  background-color: #000000 !important;
}

body {
  margin: 0;
  overflow: hidden;
}
<canvas id="canvas"></canvas>
javascript jquery css html5-canvas fabricjs
2个回答
0
投票

那个每一帧调用flow()的requestAnimationFrame()函数是为了让谁的电脑尽可能快地运行。我不会破坏你的实际渲染循环。

试试在 flake.speedxMultiplier. 这两个是影响粒子速度的主要变量。你可以看到每次通过flow()循环时,你是如何根据每个粒子的速度属性和位置来调整它们的位置的。然后最后用 ctx.arc(flake.x, flake.y, flake.size, 0, Math.PI * 2);

所以传递给ctx.arc()的任何变量都会影响粒子的位置。而且这些变量中的许多变量每次在循环中都会被重新计算。

我不是这里的专家,但也许可以试着摆弄一下你的变量。

https:/codepen.ionitwitpenXWXJNaJ。


0
投票

https:/jsfiddle.netz6r8h5de

如果问题是屏幕上有太多的薄片,将计数从700调低。

flakeCount = 100,

0
投票

无法找出你想减慢的是什么,因为代码中有几个特效和交互。

我从头开始重写,因为你的代码有点老派。

与其玩你的常量,不如让OI添加全局变量。rate (在源的顶部)用来控制动画播放的速度,包括用户的互动。

我添加了两个按钮来减慢或加快动画的播放速度。

希望能帮到你:)

var rate = 1;
slower.addEventListener("click", () => rate *= 1 / 1.2);
faster.addEventListener("click", () => rate *= 1.2);

const flakes = [], flakeCount = 700, xMultiplier = 0.015;
const minDist = 150,  minDistSqr = minDist * minDist;
const colors = ["#F99","#F83","#AF9","#ED9","#AC8","#FA9" ];
const ctx = canvas.getContext("2d");

const mouse = {x: -100, y: -100};
const randPick = (arr, len = arr.length) => arr[Math.random() * len | 0];
Math.rand = (min, range) => Math.random() * range + min;
   
function Flake() {
  this.reset();
  this.stepSize = Math.random() / 30;
  this.step = 0;
}
Flake.prototype = {
  reset() {
    this.x = canvas.width;
    this.y = 50;
    this.size = Math.rand(5, 3);
    this.speed = Math.rand(0.5, 7);
    this.velY = this.speed;
    this.velX = -xMultiplier * canvas.width * Math.rand(0.5, 1);
    this.col = randPick(colors);
  },
  draw() {
    ctx.fillStyle = this.col;
    const s = this.size, sh = -s / 2;
    ctx.fillRect(this.x + sh, this.y + sh, s, s);
  },
  update(w, h) {
    const f = this;
    const dx = f.x - mouse.x;
    const dy = f.y - mouse.y;
    const distSqr = dx * dx + dy * dy;
    if (distSqr < minDistSqr) {
      const deltaV = 2 * minDist * rate / distSqr ** 1.5;
      f.velX -= deltaV * dx;
      f.velY -= deltaV * dy;
    } else {
      f.velX -= 0.1 * rate * f.velX;
      if (f.velY <= f.speed ) { f.velY = f.speed }
      f.velX += Math.cos(f.step += 0.05 * rate) * f.stepSize  * rate;
    }
    f.y += f.velY * rate;
    f.x += f.velX * rate;
    if (f.y >= h || f.y <= 0 || f.x >= w || f.x <= 0) { this.reset() }
    else { this.draw() }
  }
};

init();
mainLoop();
function mainLoop() {
  if (innerWidth !== canvas.width || innerHeight !== canvas.height) { resize() }
  else { ctx.clearRect(0, 0, canvas.width, canvas.height) }
  for (const f of flakes) { f.update(canvas.width, canvas.height) }
  requestAnimationFrame(mainLoop);
}

function init() {
  var i = flakeCount;
  while (i--) { flakes.push(new Flake()) }
}

canvas.addEventListener("mousemove", e => { mouse.x = e.clientX; mouse.y = e.clientY });
function resize() { canvas.width = innerWidth;  canvas.height = innerHeight }
canvas {
  background-color: #000;
}

body {
  margin: 0;

}
.buttons {
  position: absolute;
  top: 12px;
  left: 12px;
  color: #000;
  background-color: #AAA; 
}
.buttons > div {
  margin: 3px;
  padding: 3px;
  background-color: #EEE;
  cursor: pointer;
}
.buttons > div:hover {
  background-color: #DEF; 
}
<canvas id="canvas"></canvas>
<div class = "buttons">
<div id="slower">Slower</div>
<div id="faster">Faster</div>
</div>
© www.soinside.com 2019 - 2024. All rights reserved.