2张使用Java动画制作的图片 [英] 2 images animated using Javascript
问题描述
到目前为止,通过进行研究和寻求帮助,我已经使用下面的JSFiddle中的代码构建了一个从左向右移动的动画.每20秒循环一次.
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.
但是,现在我需要第二张图像从右向左移动,并在第一张图像完成动画后立即自动触发. 如果您能做到这一点,那就太好了.
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.
预先感谢
<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();
}
推荐答案
这有点复杂,但是归结为格式化Card
函数的格式以了解它的方向.因此,您将需要direction
参数和更复杂的绘制函数,该函数会将您的卡片移动更新到应该移动的方向,例如:
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
最后,这里正在工作 JsFiddle示例
Finally, here is working JsFiddle example
这篇关于2张使用Java动画制作的图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!