JS Canvas,动画堆栈中的图像而不是每回合后的变化

时间:2016-10-19 14:26:14

标签: javascript arrays image animation canvas

我被困在这几天了,无法找到解决方案。我想要做的是,每个周期后图像都会改变,并且在所有图像按顺序显示之后,它会再次以第一个图像重新开始。现在我遇到的问题是右边的图像堆积起来。这是代码:



var canvas, ctx, x, y, w, e;
var brojac = 0;
var i = 0;

var images = [];
    images[0] = new Image();
    images[0].src = "https://www.a1smallbusinessmarketing.com/images/prosbo_hires.jpg";
    images[1] = new Image();
    images[1].src = "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png";
    images[2] = new Image();
    images[2].src ="http://www.jasonjsmith.com/img/small-business-seo.jpg";
    images[3] = new Image();
    images[3].src ="https://g.twimg.com/business/page/image/11TwitterForSmallBusiness-300_1.png";


function start_canvas() {
  function draw() {
    for (i = 0; i <= brojac; i++) {
      if (brojac == 4) {
        brojac = 0;
        i = 0;
      } else {
        ctx.drawImage(images[i], x, y);
      }
    }
  };
  function draw1(w, e) {
    ctx.drawImage(images[i - 1], w, e);
  };


  function update(time) {

    ctx.clearRect(0, 0, canvas.width, canvas.height);
    if (w >= x) {
      e += 8;
      y += 8;
    } else {
      x -= 4;
      w += 4;
    };
    draw(x, y);
    draw1(w, e);

    if (e > canvas.height) {
      brojac++;
      x = canvas.width - 190;
      y = 15;
      w = 1;
      e = 15;
    }
    requestAnimationFrame(update)

  }
  canvas = document.getElementById('canvas1');

  x = canvas.width - 190;
  y = 15;
  w = 1;
  e = 15;


  ctx = canvas.getContext('2d');
  requestAnimationFrame(update)

}
window.addEventListener("load", start_canvas);
&#13;
<style> canvas {
  border: #666 2px solid;
}
</style>
&#13;
<!DOCTYPE html>
<html>

<head>

</head>

<body>
  <canvas id="canvas1" width="1650" height="825" style="width: 650px; height: 330px;"></canvas>

</body>

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

*由于我在网上随机找到的图像,只能在最后两张图像中看到堆叠。如何让它们不叠加?
附带问题如果我想制作,比方说,数组中的图像[0,1]只到中间而不是掉线,我可以使用switch语句还是应该使用if? 提前谢谢。

1 个答案:

答案 0 :(得分:1)

使用(%)modulo循环

如果要遍历项目数组,可以使用%来获取数组索引。 %返回除数的余数。即0 % 4 == 03 % 4 == 34 % 4 == 07 % 4 == 3

Modulo (aka remainder) operator MDN

因此,如果你有一个项目数组,你只需创建一个索引并使用数组长度来获得余数。

 var currentIndex = 0;
 // then to loop through the array
 currentIndex = (currentIndex + 1) % array.length;

这非常方便,使我们不必添加条件语句来循环遍历数组等。

我重写了你的代码。我在更新循环中绘制图像,我检查图像是否已加载,但如果图像未加载,动画仍将播放。如果将if(images[currentImage].complete){移动到更新功能的开头并将右括号移动到requestAnimationFrame...以上的行,则在图像加载之前动画将不会启动。

// image names 
var imageURLS = [
    "https://www.a1smallbusinessmarketing.com/images/prosbo_hires.jpg",
    "https://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png",
    "http://www.jasonjsmith.com/img/small-business-seo.jpg",
    "https://g.twimg.com/business/page/image/11TwitterForSmallBusiness-300_1.png"
]
// load the images
var images = imageURLS.map(url=>{var img = new Image(); img.src = url; return img});

function start_canvas() {
    var canvas = document.createElement('canvas');
    canvas.width=1650;
    canvas.height=825;
    canvas.style.width = "650px"; // Note the canvas is scaled down
    canvas.style.height = "330px";
    document.body.appendChild(canvas);
    var ctx = canvas.getContext('2d');    
    var currentImage = 0; // points to the current image being rendered
    const imageStartY = 15;  // constants for image start and speeds
    const imageStartRight = canvas.width - 190;
    const imageStartLeft = 1;
    const horizontalSpeed = 4;
    const verticalSpeed = 8;
    var leftImg = {x : imageStartLeft,y : imageStartY};  // left and right image locations
    var rightImg = {x : imageStartRight,y : imageStartY};    
    // main loop
    function update(time) {  
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        if (leftImg.x >= rightImg.x) { // check if moving down
            leftImg.y += verticalSpeed;
            rightImg.y += verticalSpeed;
        } else {  // else moving towards center
            leftImg.x += horizontalSpeed;
            rightImg.x -= horizontalSpeed;
        };
        if(images[currentImage].complete){ // make sure the current image has loaded
            ctx.drawImage(images[currentImage],leftImg.x, leftImg.y); // draw both images
            ctx.drawImage(images[currentImage],rightImg.x, rightImg.y);
        }
        if (leftImg.y > canvas.height) { // if at bottom cycle to next image and start again
            currentImage = (currentImage + 1) % images.length; // loop image index % is modulo and returns the remainder 
            leftImg.x = imageStartLeft;
            leftImg.y = imageStartY;
            rightImg.x = imageStartRight;
            rightImg.y = imageStartY;
        }
        requestAnimationFrame(update);
    }
    requestAnimationFrame(update);
}
window.addEventListener("load", start_canvas);