在html画布上移动图像

t8e9dugd  于 2022-12-21  发布在  其他
关注(0)|答案(5)|浏览(148)

我正在尝试将一个图像从右边移到中间,我不确定这是否是最好的方法。

var imgTag = null;
    var x = 0;
    var y = 0;
    var id;

    function doCanvas()
    {
        var canvas = document.getElementById('icanvas');
        var ctx = canvas.getContext("2d");
        var imgBkg = document.getElementById('imgBkg');
        imgTag = document.getElementById('imgTag');

        ctx.drawImage(imgBkg, 0, 0);

        x = canvas.width;
        y = 40;

        id = setInterval(moveImg, 0.25);

    }

    function moveImg()
    {
        if(x <= 250)
            clearInterval(id);

        var canvas = document.getElementById('icanvas');
        var ctx = canvas.getContext("2d");

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

        var imgBkg = document.getElementById('imgBkg');
        ctx.drawImage(imgBkg, 0, 0);

        ctx.drawImage(imgTag, x, y);

        x = x - 1;
    }

有什么建议吗?

0g0grzrc

0g0grzrc1#

这个问题已经有5年的历史了,但既然我们现在有了requestAnimationFrame()方法,这里有一个使用vanilla JavaScript的方法:

var imgTag = new Image(),
    canvas = document.getElementById('icanvas'),
    ctx = canvas.getContext("2d"),
    x = canvas.width,
    y = 0;

imgTag.onload = animate;
imgTag.src = "http://i.stack.imgur.com/Rk0DW.png";   // load image

function animate() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);  // clear canvas
  ctx.drawImage(imgTag, x, y);                       // draw image at current position
  x -= 4;
  if (x > 250) requestAnimationFrame(animate)        // loop
}
<canvas id="icanvas" width=640 height=180></canvas>
0aydgbwb

0aydgbwb2#

drawImage()允许定义在目标画布上绘制源图像的哪一部分。我建议为每个moveImg()计算前一个图像的位置,用imgBkg的那一部分覆盖前一个图像,然后绘制新图像。假设这将保存一些计算能力。

elcex8rz

elcex8rz3#

这就是我的答案。

var canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");

var myImg = new Image();
var myImgPos = {
  x: 250,
  y: 125,
  width: 50,
  height: 25
}

function draw() {
  myImg.onload = function() {
    ctx.drawImage(myImg, myImgPos.x, myImgPos.y, myImgPos.width, myImgPos.height);
  }

  myImg.src = "https://mario.wiki.gallery/images/thumb/c/cc/NSMBUD_Mariojump.png/1200px-NSMBUD_Mariojump.png";
}

function moveMyImg() {
  ctx.clearRect(myImgPos.x, myImgPos.y, myImgPos.x + myImgPos.width, myImgPos.y +
    myImgPos.height);
  myImgPos.x -= 5;
}

setInterval(draw, 50);
setInterval(moveMyImg, 50);
<canvas id="canvas" class="canvas" width="250" height="150"></canvas>
m0rkklqb

m0rkklqb4#

对于无滞后动画,我通常使用kinetic.js。

var stage = new Kinetic.Stage({
        container: 'container',
        width: 578,
        height: 200
      });
      var layer = new Kinetic.Layer();

      var hexagon = new Kinetic.RegularPolygon({
        x: stage.width()/2,
        y: stage.height()/2,
        sides: 6,
        radius: 70,
        fill: 'red',
        stroke: 'black',
        strokeWidth: 4
      });

      layer.add(hexagon);
      stage.add(layer);

      var amplitude = 150;
      var period = 2000;
      // in ms
      var centerX = stage.width()/2;

      var anim = new Kinetic.Animation(function(frame) {
        hexagon.setX(amplitude * Math.sin(frame.time * 2 * Math.PI / period) + centerX);
      }, layer);

      anim.start();

如果你想看的话,这里有个例子。
http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-animate-position-tutorial/
我建议这样做的原因是,setInterval或setTimeout是一个特殊的函数,当大量的动画同时发生时会引起问题,但是动态的。动画处理帧率更智能。

tyky79it

tyky79it5#

用示例解释window.requestAnimationFrame()

在下面的代码片段中,我将使用一个图像作为将要设置动画的部分。
老实说...... window.requestAnimationFrame()对我来说并不容易理解,这就是为什么我尽可能清晰直观地编写它,这样你就可以比我更容易理解它。

const 
  canvas = document.getElementById('root'),
  btn = document.getElementById('btn'),
  ctx = canvas.getContext('2d'),
  brickImage = new Image(),
  piece = {image: brickImage, x:400, y:70, width:70};
  
brickImage.src = "https://i.stack.imgur.com/YreH6.png";
     
// When btn is clicked execute start()     
btn.addEventListener('click', start) 

function start(){
    btn.value = 'animation started'  
    
    // Start gameLoop()
    brickImage.onload = window.requestAnimationFrame(gameLoop) 
}

function gameLoop(){ 
  // Clear canvas
  ctx.clearRect(0, 0, canvas.width, canvas.height)
  
  // Draw at coordinates x and y
  ctx.drawImage(piece.image, piece.x, piece.y)     
  
  let pieceLeftSidePos = piece.x;
  let middlePos = canvas.width/2 - piece.width/2;
  
  // Brick stops when it gets to the middle of the canvas
  if(pieceLeftSidePos > middlePos) piece.x -= 2;

  window.requestAnimationFrame(gameLoop)   // Needed to keep looping
}
<input id="btn" type="button" value="start" />
<p>
<canvas id="root" width="400" style="border:1px solid grey">
    • 一个关键点**

在**start()**函数中,我们有:

brickImage.onload = window.requestAnimationFrame(gameLoop);

这也可以写成:window.requestAnimationFrame(gameLoop);,它可能会工作,但我添加的brickImage.onload,以确保图像已加载第一。如果没有,它可能会导致一些问题。

    • 注意:**window.requestAnimationFrame()通常每秒循环60次。

相关问题