0

I'm new to Canvas and I've started using an example of a simple linear motion animation from HTML Canvas Tutorials.

Is it possible to replace the rectangle so it displays an image instead?

Every time I've attempted editing the code the image that's outputted is static so I'm obviously doing something wrong.

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

                                    function drawRectangle(myRectangle, context) {
                                        context.beginPath();
                                        context.rect(myRectangle.x, myRectangle.y, myRectangle.width, myRectangle.height);
                                        context.fillStyle = '#8ED6FF';
                                        context.fill();
                                        context.lineWidth = myRectangle.borderWidth;
                                        context.strokeStyle = 'black';
                                        context.stroke();
                                        context.drawImage = 'images/player.png';
                                    }

                                    function animate(myRectangle, canvas, context, startTime) {
                                        // update
                                        var time = (new Date()).getTime() - startTime;

                                        var linearSpeed = 200;
                                        // pixels / second
                                        var newX = linearSpeed * time / 1000;

                                        if (newX < canvas.height - myRectangle.height - myRectangle.borderWidth / 2) {
                                            myRectangle.y = newX;
                                        }

                                        // clear
                                        context.clearRect(0, 0, canvas.width, canvas.height);

                                        drawRectangle(myRectangle, context);

                                        // request new frame
                                        requestAnimFrame(function() {
                                            animate(myRectangle, canvas, context, startTime);
                                        });
                                    }
                                    var canvas = document.getElementById('monopoly-piece');
                                    var context = canvas.getContext('2d');
                                    var img = new Image;

                                    var myRectangle = {
                                        x: 20,
                                        y: 0,
                                        width: 50,
                                        height: 50,
                                        borderWidth: 5,
                                        img: 'images/player.png'
                                    };

                                    drawRectangle(myRectangle, context);

                                     // wait one second before starting animation
                                    setTimeout(function() {
                                        var startTime = (new Date()).getTime();
                                        animate(myRectangle, canvas, context, startTime);
                                    }, 1000);

Any help would be much appreciated, Thanks in advance. :)

user2879183
  • 55
  • 3
  • 10
  • this might help: http://www.w3schools.com/tags/canvas_drawimage.asp – snies Sep 23 '14 at 12:18
  • Thanks for the response @snies I'm aware of the drawImage method but as a complete novice of Canvas I'm not entirely sure how to implement it into the existing code... – user2879183 Sep 23 '14 at 13:17

2 Answers2

3

Ok, here you go, a working example at jsfiddle: http://jsfiddle.net/zymz2dLo/61/

window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame;

// get canvas and create drawing context
// this assumes there is some canvas with id 'myCanvas'
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');

// create image
var img = document.createElement("img");

// fill image from data string
//img.src = "data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=="; // insert a dot image contains 1px

// or fill image from url
img.src = "http://www.w3schools.com/tags/img_the_scream.jpg"


// define the linear speeds
var xSpeed = 0.05;  //px per ms
var ySpeed = 0.01;

// this function will animate the next 'frame' 
// based on input from the last 
function animate(nowTime, lastTime, xPos, yPos) {
    if ((img.style.width + xPos) > canvas.width) {
        xPos = 0;
        yPos = 0;
    }

    // calculate the delta in order to match the speed 
    var timeDelta = nowTime - lastTime;
    var xDelta = xSpeed * timeDelta;
    var yDelta = ySpeed * timeDelta;

    // clear
    context.clearRect(0, 0, canvas.width, canvas.height);

    //draw img
    context.drawImage(img, xPos, yPos);

    //schedule animation for the next available frame
    requestAnimationFrame(
        //wrap animate in a anonymous function to 
        //match the callback signature 
        function(timestamp){
            animate(timestamp, nowTime, xPos + xDelta, yPos + yDelta);
        }
    );
}

animate(0, 0,  10, 1);

additional info can be found here:

http://www.w3schools.com/tags/canvas_drawimage.asp

How to generate an Image from imageData in javascript?

https://developer.mozilla.org/en/docs/Web/API/window.requestAnimationFrame

EDIT : The above example updates as fast as possible, to scale it down a bit wrap the call to requestAnimationFrame in a setTimeout call.

Community
  • 1
  • 1
snies
  • 3,461
  • 1
  • 22
  • 19
  • Wow thanks a lot @snies . One small thing which is that I need the image to stop animating once it hits the edge of the canvas like the rectangle does in the tutorial. Is this to do with the requestAnimationFrame function? – user2879183 Sep 23 '14 at 14:05
  • yup, you would have to guard the execution of requestAnimationFrame with some stop condition like `if (xPos < canvas.width)` or something like that. And of course than you don't need the rest to zero part. – snies Sep 23 '14 at 14:12
0

Thanks @snies . I managed to get the effect I was looking for with the following code. Could probably do with a bit of tidying up but it works for now

window.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.oRequestAnimationFrame;

                                    var canvas = document.getElementById('monopoly-piece');
                                    var context = canvas.getContext('2d');

                                    var img = document.createElement("img");
                                    img.src = "images/player.png"

                                    var xSpeed = 0;  //px per ms
                                    var ySpeed = 0.1;

                                    function animate(nowTime, lastTime, xPos, yPos) {
                                        // update
                                        if ((img.style.height + yPos) > canvas.height) {
                                            xPos = 0;
                                            yPos = 0;
                                        }
                                        var timeDelta = nowTime - lastTime;
                                        var xDelta = xSpeed * timeDelta;
                                        var yDelta = ySpeed * timeDelta;

                                        // clear
                                        context.clearRect(0, 0, canvas.width, canvas.height);

                                        //draw img
                                        context.drawImage(img, xPos, yPos);

                                        if (yPos > canvas.height - img.height ) {

                                        }
                                        else {
                                            requestAnimationFrame(
                                                    function(timestamp){
                                                        animate(timestamp, nowTime, xPos + xDelta, yPos + yDelta);
                                                    }
                                                );
                                            }

                                    }

                                animate(0, 0, 20, 1);
user2879183
  • 55
  • 3
  • 10