2 images animated using Javascript

馋奶兔 提交于 2020-01-16 20:20:43

问题


From doing research and asking for help I have so far built an animation moving from left to right using the code in the JSFiddle below. This loops every 20 seconds.

http://jsfiddle.net/a9HdW/3/

However now I need a second image that moves from right to left and for this to automatically trigger straight after the first image has completed its animation. If you could do this that would be amazing.

Thanks In Advance

<canvas id="canvas" width="1600" height="300"></canvas>
<script>
window.requestAnimFrame = (function(){
window.requestAnimationFrame       ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame    ||
window.oRequestAnimationFrame      ||
window.msRequestAnimationFrame     ||
function( callback ){
    window.setTimeout(callback, 1000 / 60);
};
})();

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

function Card(x,y){
this.x = x || -300;
this.y = y || 0;
this.width = 0;
this.height = 0;
this.img=new Image();

this.init=function(){

// this makes myCard available in the img.onload function
// otherwise "this" inside img.onload refers to the img
var self=this;

this.img.onload = function() 
{
    // getting width and height of the image
    self.width = this.width;
    self.height = this.height;
    self.draw();

    loop();

}
this.img.src = "f15ourbase.png";  
}

this.draw = function(){
cx.drawImage(this.img, this.x, this.y);
}

}

var myCard = new Card(50,50);
myCard.init();

function loop(){


if((myCard.x + myCard.width) < canvas.width){
requestAnimFrame(loop);
} else {

  setTimeout(function() {
   // resetting card back to old state
   myCard.x = 50;
   myCard.y = 50;
   // call the loop again
   loop();
}, 20000);

}

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

myCard.x = myCard.x + 15;

myCard.draw();

}


回答1:


This is little bit complicated, however, it boils down to formatting your Card function to understand which direction it is going to. Therefore you will need direction parameter and more complicated draw function which updates your card movement to direction it is supposed to go, like this:

// Updating own position, based on direction
if(this.direction === 1) {
   this.x = this.x + this.stepSize; // we move to right

   // if I am over canvas at right, I am done animating
   if(this.x >= canvas.width) {
       this.finishedAnimation = true;
   }     

} else {
   this.x = this.x - this.stepSize; // we move to left

   // if I am over canvas at left, I am done animating
   if(this.x <= -this.width) {
       this.finishedAnimation = true;
   }

}     

Also, because timing is important - you will need to trigger other card movement only after the first one is completed. Like this:

// We won't draw next card before previous is finished
if(!cardToRight.finishedAnimation) {
   cardToRight.draw();
} else {
   // Card at right is finished, we move the left card now
   cardToLeft.draw();
}

To summarize my points, I made a code which has code comments to explain it's contents, go it through carefully:

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

// Variable declarations
var canvas = document.getElementById("canvas"),
    cx = canvas.getContext("2d"),
    // Handlers for both of the cards
    cardToRight,
    cardToLeft;

/**
 * Card declaration
 *  
 */
var Card = function(x, y, direction) {

    // how many pixels we move
    this.stepSize = 5;
    // x and y position on canvas
    this.x = x;
    this.y = y;
    // Copy values are used when reset is done
    this.xCopy = this.x;
    this.yCopy = this.y;
    // handle to specify if animation finished
    this.finishedAnimation = false;
    // 1 means move to right, 0 means move to left
    this.direction = direction;
    // Image of the card
    this.img = undefined;
    // Image url for this card
    this.imgSrc = "http://placehold.it/350x150"; // for your image: "f15ourbase.png"
    // Image width
    this.width = 0;

};

/**
 * Initialize
 *
 */
Card.prototype.init = function(callback) {

   // self refers to this card
   var self = this;

   this.img = new Image();

   // onload success callback
   this.img.onload = function() {

       // Setting own width
       self.width = this.width;

       // triggering callback on successfull load
       return callback();

   };

   // onload failure callback
   this.img.onerror = function() {
       // Returning error message for the caller of this method
       return callback("Loading image " + this.imgSrc + " failed!");
   };

   // Triggering image loading
   this.img.src = this.imgSrc;

};

/**
 * Draw self
 *
 */
Card.prototype.draw = function() {

    // Updating own position, based on direction
    if(this.direction === 1) {
        this.x = this.x + this.stepSize; // we move to right

        // if I am over canvas at right, I am done animating
        if(this.x >= canvas.width) {
            this.finishedAnimation = true;
        }     

    } else {
        this.x = this.x - this.stepSize; // we move to left

        // if I am over canvas at left, I am done animating
        if(this.x <= -this.width) {
            this.finishedAnimation = true;
        }  

    }

    // cx (context) could be also passed, now it is global
    cx.drawImage(this.img, this.x, this.y);

};

/**
 * Reset self
 *
 */
Card.prototype.reset = function() {

    // Using our copy values
    this.x = this.xCopy;
    this.y = this.yCopy;

    // handle to specify if animation finished
    this.finishedAnimation = false;

};

/**
 * Main loop
 *
 */
function loop() {

    // Clear canvas
    cx.clearRect(0, 0, canvas.width, canvas.height);

    // We won't draw next card before previous is finished
    // Alternatively, you could make getter for finishedAnimation
    if(!cardToRight.finishedAnimation) {
        cardToRight.draw();
    } else {
        // Card at right is finished, we move the left card now
        cardToLeft.draw();
    }

    // If cardToLeft not yet animated, we are still pending
    if(!cardToLeft.finishedAnimation) {
        // Schedule next loop 
        // "return" makes sure that we are not executing lines below this
        return requestAnimFrame(loop); 
    }

    // Animation finished, starting again after 5 seconds
    setTimeout(function() {
       // Resetting cards
       cardToRight.reset(); 
       cardToLeft.reset();

       // Start the loop again
       loop();

    }, 5000); // 5000 milliseconds = 5 seconds

};


/**
 * Main program below
 *
 */

// Card to right (1 denotes it's direction to right)
cardToRight = new Card(50, 50, 1);

// Card to left  (0 denotes it's direction to left)
cardToLeft = new Card(1000, 50, 0);

// Initialize cardToRight & cardToLeft
// Because using only two cards, we can do a bit nesting here
cardToRight.init(function(err) {

    // If error with image loading
    if(err) {
        return alert(err);
    }

    // Trying to initialize cardToLeft
    cardToLeft.init(function(err) {

        // If error with image loading
        if(err) {
            alert(err);
        }

        // All ok, lets do the main program
        loop();  

    });

});

As a special note: If you wan't your cards appear outside the canvas remember to change values of below accordingly:

// Card to right (1 denotes it's direction to right)
cardToRight = new Card(50, 50, 1); // 50    <- x position of right card

// Card to left  (0 denotes it's direction to left)
cardToLeft = new Card(1000, 50, 0); // 1000 <- x position of left card

Finally, here is working JsFiddle example



来源:https://stackoverflow.com/questions/22895589/2-images-animated-using-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!