javascriptcanvashtml5-canvasputimagedata

Animating / Move canvas image that has been placed by putImageData


I have a jpeg image that has been decoded, and I am writing it to canvas with putImageData. Is it possible to then move this image around? I cannot find any documentation on it.

The idea is that I will crop a certain part of the decoded image with dirtyX and dirtyY, and now I would like to crop another part of the image. I'm using the decoded image like a spritesheet.


Solution

  • Use the clipping version of drawImage to draw your individual sprites to the canvas

    (Don't use getImageData & putImageData for clipping since drawImage is easier and faster.)

    If you want to use your decoded image as a spritesheet then you can use the canvas's clipping version of context.drawImage to clip a particular sub-section of your spritesheet and draw it to the canvas.

    Here's a previous SO post about the clipping version of drawImage.

    HTML / Java Script Canvas - how to draw an image between source and destination points?

    Here's example code and a Demo:

    Note that the way to "move" sprites on the canvas is to clear the canvas and redraw the desired sprite in it's new position. (You can't "move" an existing drawing on the canvas).

    $(window).load(function(){
    
      // canvas related variables       
      var canvas=document.getElementById("canvas");
      var ctx=canvas.getContext("2d");
    
      // animation related variables
      var lastFlap,lastMove;
    
      // define a bird object
      // x,y are the position of the bird on the canvas
      // spriteX,spriteY is the position of the first desired
      //      sprite image on the spritesheet
      // width,height is the size of 1 sprite image
      // currentFrame is the index of which of the sprite images to display
      // currentDirection.  The sprite plays forward and then backward to
      //      accomplish 1 flap.  This determines if the next frame index will
      //      be increased (play forward) or decreased (play backward)
      var bird={
        x:30,
        y:30,
        spriteX:0,
        spriteY:52,
        width:51,
        height:51,
        frames:4,
        currentFrame:0,
        currentDirection:1
      }
    
      // load the spritesheet and start the animation
      var spritesheet=new Image();
      spritesheet.onload=start;
      spritesheet.src="https://dl.dropboxusercontent.com/u/139992952/multple/birdSpritesheet.png";
      function start(){
        requestAnimationFrame(animate);
      }
    
      function animate(time){
    
        // request another animation frame
    
        if(bird.x<canvas.width){
          requestAnimationFrame(animate);
        }
    
        // if the lastFlap or lastMove times don't aren't set, then set them
    
        if(!lastFlap){lastFlap=time;}
        if(!lastMove){lastMove=time;}
    
        // calculate the elapsed times since the last flap and the last move
    
        var elapsedFlap=time-lastFlap;
        var elapsedMove=time-lastMove;
    
        // if 50ms have elapsed, advance to the next image in this sprite
    
        if(elapsedFlap>50){
    
          // advance to next sprite on the spritesheet (flap)
    
          bird.currentFrame+=bird.currentDirection;
    
          // clamp bird.currentFrame between 0-3  (0,1,2,3)
          // (because there are 4 images that make up the whole bird sprite)
    
          if(bird.currentFrame<0 || bird.currentFrame>bird.frames-1){
            bird.currentDirection*=-1;
            bird.currentFrame+=bird.currentDirection;
          }
    
          // reset the flap timer
    
          lastFlap=time;
        }
    
        // locate the current sprite from the spritesheet
    
        var sx=bird.spriteX+bird.currentFrame*bird.width;
        var sy=bird.spriteY;
    
        // if 100ms have elapsed, move the bird across the canvas
    
        if(elapsedMove>100){
          bird.x+=3;
          lastMove=time;
        }
    
        // clear the whole canvas
    
        ctx.clearRect(0,0,canvas.width,canvas.height);
    
        // draw the current part of the bird sprite at the current bird.x
    
        ctx.drawImage(spritesheet,
                      sx,sy,bird.width,bird.height,
                      bird.x,bird.y,bird.width,bird.height
                     );
    
      }
    
    }); // end $(function(){});
    body{ background-color: white; }
    canvas{border:1px solid red;}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <h4>The canvas animating a clipped sprite</h4>
    <canvas id="canvas" width=300 height=100></canvas>
    <br>
    <h4>The spritesheet</h4>
    <img id=spritesheet src='https://dl.dropboxusercontent.com/u/139992952/multple/birdSpritesheet.png'>