HTML Canvas尝试创建一个矩形的动画链,它们之间有轻微的延迟/距离

时间:2017-09-02 00:18:14

标签: javascript animation canvas requestanimationframe

我正在尝试使用带有requestAnimationFrame的Html Canvas创建多个动画矩形。至于现在,我设法完成了我想要的只有一个动画矩形,但我无法找到如何创建更多的矩形,这些矩形只是在一条直线上并且以相等的距离相互跟随。

此外,每个矩形内还有一个随机数据(I,II或III)。

这是我的实际代码:



//Referencing canvas
  		var canvas = document.getElementById("my-canvas");
		var ctx = canvas.getContext("2d");


  		//Make Canvas fullscreen and responsive
	    function resize() {
			canvas.width = window.innerWidth;
			canvas.height = window.innerHeight;
		}
		window.addEventListener('resize', resize, false); resize();
		
		//FPS
		var framesPerSecond = 60;

		//Default Y pos to center;
		var yPos = canvas.height / 2;
		//Default X pos offset
		var xPos = -150;

		//Speed (increment)
		var speed = 2;

		//Our array to store rectangles objects
		var rectangles = [] ;

		//Dynamic Number from database
		var quote = ["I", "II", "III"];

		//Random number for testing purpose
		var rand = quote[Math.floor(Math.random() * quote.length)];


		//Draw Rectangle
		function drawRectangle () {

			setTimeout(function() {
	        	 requestAnimationFrame(drawRectangle); 


				ctx.clearRect(0, 0, canvas.width, canvas.height);

				//Background color
				ctx.fillStyle = "yellow";
				//Position, size.
				var rectWidth = 70;
				var rectHeigth = 55;
				ctx.fillRect(xPos,yPos,rectWidth,rectHeigth);

				ctx.font = "32px Arial";
				ctx.textAlign = "center"; 
				ctx.textBaseline = "middle";
				ctx.fillStyle = "black";

				//Data Layer
				var dataLayer = ctx.fillText(rand,xPos+(rectWidth/2),yPos+(rectHeigth/2));


				xPos += speed;
	 
	 			//Infinite loop for test
			  	if (xPos > 1080) {
			    	xPos = -150;
			  	}

  		    }, 1000 / framesPerSecond);

		}

		drawRectangle ();

canvas {background-color: #131217}

body { margin: 0; overflow: hidden; }

<!DOCTYPE html>
<html lang="en">
  
  <head>
    <meta charset="utf-8">
    <title>Moving Blocks</title>

    <style>

	    canvas {background-color: #131217}

	    body { margin: 0; overflow: hidden; }

    </style>
    
  </head>


  <body>

  	<canvas id="my-canvas"></canvas>
    
  </body>


</html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:0)

设置对象数组的动画。

对于动画,您最好使用单个渲染函数,将所有对象渲染为一帧,而不是为每个对象创建单独的渲染帧。

至于广场,有很多方法可以让他们做你想做的事。这有点难以回答,因为你想要的并不完全清楚。

这个答案将使用一个矩形对象,它包含所有需要渲染和移动的东西。矩形将保留在一个数组中,主渲染函数将依次更新和渲染每个矩形。

将会有一个生成函数的生成函数,直到达到限制为止。

// constants up the top
const quote = ["I", "II", "III"];
// function selects a random Item from an array
const randItem = (array) => array[(Math.random() * array.length) | 0];

// array to hold all rectangles
const rectangles = [];
var maxRectangles = 20;
const spawnRate = 50; // number of frames between spawns
var spawnCountdown = spawnRate;

//Referencing canvas
const ctx = canvas.getContext("2d");
var w, h; // global canvas width and height. 
resizeCanvas(); // size the canvas to fit the page

requestAnimationFrame(mainLoop); // this will start when all code below has been run
function mainLoop() {
  // resize in the rendering frame as using the resize
  // event has some issuse and this is more efficient.
  if (w !== innerWidth || h !== innerHeight) {
    resizeCanvas();
  }
  ctx.clearRect(0, 0, w, h);
  spawnRectangle(); // spawns rectangles
  updateAllRectangles(); // moves all active rectangles
  drawAllRectangles(); // I will let you gues what this does... :P

  requestAnimationFrame(mainLoop);
}

function resizeCanvas() {
  w = canvas.width = innerWidth;
  h = canvas.height = innerHeight;

  // and reset any canvas constants
  ctx.font = "32px Arial";
  ctx.textAlign = "center";
  ctx.textBaseline = "middle";
}

// function to spawn a rectangle
function spawnRectangle() {
  if (rectangles.length < maxRectangles) {
    if (spawnCountdown) {
      spawnCountdown -= 1;
    } else {
      rectangles.push(
        createRectangle({
          y: canvas.height / 2, // set at center
          text: randItem(quote),
          dx: 2, // set the x speed
        })
      );
      spawnCountdown = spawnRate;
    }
  }
}


// define the default rectangle

const rectangle = {
  x: -40, // this is the center of the rectangle
  y: 0,
  dx: 0, // delta x and y are the movement per frame
  dy: 0,
  w: 70, // size
  h: 55,
  color: "yellow",
  text: null,
  textColor: "black",
  draw() { // function to draw this rectangle
    ctx.fillStyle = this.color;
    ctx.fillRect(this.x - this.w / 2, this.y - this.h / 2, this.w, this.h);
    ctx.fillStyle = this.textColor;
    ctx.fillText(this.text, this.x, this.y);
  },
  update() { // moves the rectangle
    this.x += this.dx;
    this.y += this.dy;
    if (this.x > canvas.width + this.w / 2) {
      this.x = -this.w / 2;
      // if the rectangle makes it to the other
      // side befor all rectangles are spawnd
      // then reduce the number so you dont get any
      // overlap
      if (rectangles.length < maxRectangles) {
        maxRectangles = rectangles.length;
      }
    }
  }
}

// creats a new rectangle. Setting can hold any unique
// data for the rectangle
function createRectangle(settings) {
  return Object.assign({}, rectangle, settings);
}

function updateAllRectangles() {
  var i;
  for (i = 0; i < rectangles.length; i++) {
    rectangles[i].update();
  }
}

function drawAllRectangles() {
  var i;
  for (i = 0; i < rectangles.length; i++) {
    rectangles[i].draw();
  }
}
canvas {
  position: absolute;
  top: 0px;
  left: 0px;
  background-color: #131217;
}

body {
  margin: 0;
  overflow: hidden;
}
<canvas id="canvas"></canvas>