[英]How to make animation out of canvas images in Kinetic.js?
I have the following code that is supposed to be three frames of an animation, how can I turn them into an animation in Kinetic.js? 我有以下代码应该是动画的三帧,我怎么能把它们变成Kinetic.js中的动画? It's a hex like pacman, that opens and closes its mouth.
这是一个像pacman一样的六角形,可以打开和关闭它的嘴。 I have three canvas images, as three frames, is there any built in function in Kinetic.js to do this?
我有三个画布图像,作为三个帧,Kinetic.js中是否有内置函数来执行此操作? or should I create one from scratch?
或者我应该从头开始创建一个? after I made the sprite, how can I do other animations like move it around, or rotate it, without breaking the animation(the pacman should still open and close its mouth)?
在制作精灵之后,我怎么能做其他动画,比如移动它,或者旋转它,而不会破坏动画(pacman应该仍然打开并关闭它的嘴)?
pacMan1 = new Kinetic.Shape({
x: 15,
y: 13,
//fill: 'rgb(62, 53, 67)',
// a Kinetic.Canvas renderer is passed into the drawFunc function
drawFunc: function (canvas) {
var context = canvas.getContext();
// layer1/Compound Path
context.save();
context.beginPath();
// layer1/Compound Path/Path
context.moveTo(54.0, 12.8);
context.lineTo(34.2, 1.4);
context.bezierCurveTo(31.2, -0.3, 27.6, -0.3, 24.7, 1.4);
context.lineTo(4.9, 12.8);
context.bezierCurveTo(1.9, 14.5, 0.1, 17.7, 0.1, 21.0);
context.lineTo(0.1, 43.9);
context.bezierCurveTo(0.1, 47.3, 1.9, 50.5, 4.9, 52.1);
context.lineTo(24.7, 63.6);
context.bezierCurveTo(27.6, 65.3, 31.2, 65.3, 34.2, 63.6);
context.lineTo(54.0, 52.1);
context.bezierCurveTo(56.9, 50.5, 58.7, 47.3, 58.7, 43.9);
context.lineTo(58.7, 21.0);
context.bezierCurveTo(58.7, 17.7, 56.9, 14.5, 54.0, 12.8);
context.closePath();
// layer1/Compound Path/Path
context.moveTo(32.3, 10.8);
context.bezierCurveTo(30.7, 10.8, 29.5, 9.5, 29.5, 8.0);
context.bezierCurveTo(29.5, 6.4, 30.7, 5.1, 32.3, 5.1);
context.bezierCurveTo(33.9, 5.1, 35.1, 6.4, 35.1, 8.0);
context.bezierCurveTo(35.1, 9.5, 33.9, 10.8, 32.3, 10.8);
context.closePath();
context.fillStyle = "rgb(62, 53, 67)";
context.fill();
context.lineWidth = 0.3;
context.stroke();
canvas.fillStroke(this);
context.restore();
}
});
pacMan2 = new Kinetic.Shape({
x: 15,
y: 13,
//fill: 'rgb(62, 53, 67)',
// a Kinetic.Canvas renderer is passed into the drawFunc function
drawFunc: function (canvas) {
var context = canvas.getContext();
// layer1/Compound Path
context.save();
context.beginPath();
// layer1/Compound Path/Path
context.moveTo(29.1, 36.9);
context.bezierCurveTo(27.6, 36.0, 26.7, 34.5, 26.7, 32.8);
context.bezierCurveTo(26.7, 31.2, 27.6, 29.6, 29.1, 28.8);
context.lineTo(55.2, 13.7);
context.bezierCurveTo(54.8, 13.4, 54.4, 13.1, 54.0, 12.8);
context.lineTo(34.2, 1.4);
context.bezierCurveTo(31.2, -0.3, 27.6, -0.3, 24.7, 1.4);
context.lineTo(4.9, 12.8);
context.bezierCurveTo(1.9, 14.5, 0.1, 17.7, 0.1, 21.0);
context.lineTo(0.1, 43.9);
context.bezierCurveTo(0.1, 47.3, 1.9, 50.5, 4.9, 52.1);
context.lineTo(24.7, 63.6);
context.bezierCurveTo(27.6, 65.3, 31.2, 65.3, 34.2, 63.6);
context.lineTo(54.0, 52.1);
context.bezierCurveTo(54.2, 52.0, 54.5, 51.8, 54.7, 51.7);
context.lineTo(29.1, 36.9);
context.closePath();
// layer1/Compound Path/Path
context.moveTo(32.3, 5.1);
context.bezierCurveTo(33.9, 5.1, 35.1, 6.4, 35.1, 8.0);
context.bezierCurveTo(35.1, 9.5, 33.9, 10.8, 32.3, 10.8);
context.bezierCurveTo(30.7, 10.8, 29.5, 9.5, 29.5, 8.0);
context.bezierCurveTo(29.5, 6.4, 30.7, 5.1, 32.3, 5.1);
context.closePath();
context.fillStyle = "rgb(62, 53, 67)";
context.fill();
context.lineWidth = 0.3;
context.stroke();
canvas.fillStroke(this);
context.restore();
}
});
pacMan3 = new Kinetic.Shape({
x: 15,
y: 13,
//fill: 'rgb(62, 53, 67)',
// a Kinetic.Canvas renderer is passed into the drawFunc function
drawFunc: function (canvas) {
var context = canvas.getContext();
// layer1/Compound Path
context.save();
context.beginPath();
// layer1/Compound Path/Path
context.moveTo(32.0, 36.9);
context.bezierCurveTo(28.7, 36.0, 26.7, 34.5, 26.7, 32.8);
context.bezierCurveTo(26.7, 31.2, 28.7, 29.6, 32.0, 28.8);
context.lineTo(58.7, 22.0);
context.lineTo(58.7, 21.0);
context.bezierCurveTo(58.7, 17.7, 56.9, 14.5, 54.0, 12.8);
context.lineTo(34.2, 1.4);
context.bezierCurveTo(31.2, -0.3, 27.6, -0.3, 24.7, 1.4);
context.lineTo(4.9, 12.8);
context.bezierCurveTo(1.9, 14.5, 0.1, 17.7, 0.1, 21.0);
context.lineTo(0.1, 43.9);
context.bezierCurveTo(0.1, 47.3, 1.9, 50.5, 4.9, 52.1);
context.lineTo(24.7, 63.6);
context.bezierCurveTo(27.6, 65.3, 31.2, 65.3, 34.2, 63.6);
context.lineTo(54.0, 52.1);
context.bezierCurveTo(56.9, 50.5, 58.7, 47.3, 58.7, 43.9);
context.lineTo(58.7, 43.7);
context.lineTo(32.0, 36.9);
context.closePath();
// layer1/Compound Path/Path
context.moveTo(32.3, 5.1);
context.bezierCurveTo(33.9, 5.1, 35.1, 6.4, 35.1, 8.0);
context.bezierCurveTo(35.1, 9.5, 33.9, 10.8, 32.3, 10.8);
context.bezierCurveTo(30.7, 10.8, 29.5, 9.5, 29.5, 8.0);
context.bezierCurveTo(29.5, 6.4, 30.7, 5.1, 32.3, 5.1);
context.closePath();
context.fillStyle = "rgb(62, 53, 67)";
context.fill();
context.lineWidth = 0.3;
context.stroke();
canvas.fillStroke(this);
context.restore();
}
});
Here's how to create a Kinetic.Sprite animation from your “chomping hexes” 以下是如何从“chomping hexes”创建Kinetic.Sprite动画
Since you already have the hex + mouth coordinates, you don't even need a pre-created spritesheet. 由于您已经有了hex +口坐标,因此您甚至不需要预先创建的spritesheet。
You can dynamically create your "chomping" spritesheet using an html canvas element. 您可以使用html canvas元素动态创建“chomping”spritesheet。
The method: 方法:
This is the dynamically created spritesheet created from the html canvas 这是从html画布创建的动态创建的spritesheet
The following code shows the canvas on-screen for illustration purposes, but you would create your temporary canvas offscreen. 以下代码在屏幕上显示画布用于说明目的,但您将在屏幕外创建临时画布。
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/sEjvx/ 这是代码和小提琴: http : //jsfiddle.net/m1erickson/sEjvx/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.5.min.js"></script>
<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:400px;
height:400px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 400,
height: 400
});
var layer = new Kinetic.Layer();
stage.add(layer);
// get a reference to the temp canvas
// it will be used to dynamically create a spritesheet
var tempCanvas=document.getElementById("canvas");
var context=tempCanvas.getContext("2d");
// define the sprites
var pac;
var translateX=0;
var y1=18;
var y2=46;
var ychange=2.5;
var width=70;
var height=70;
var chomping=[];
var animations={
stopped:[{x:0,y:0,width:width,height:height}],
chomp:chomping
};
// draw the sprites on the canvas
// also add the sprite definitions (x,y,width,height)
// to the chomping animation
for(var i=0;i<8;i++){
drawSprite(translateX,y1,y2);
translateX+=70;
y1+=2;
y2-=2;
if(i<7){
chomping.push({x:translateX,y:0,width:width,height:height});
}
}
// convert the sprites on the canvas to a spritesheet image
// and create a Kinetic.Sprite
var spritesheet=new Image();
spritesheet.onload=function(){
pac=new Kinetic.Sprite({
x:100,
y:75,
image:spritesheet,
animations:animations,
framerate:15,
index:0
});
layer.add(pac);
pac.setAnimation("stopped");
pac.start();
layer.draw();
}
spritesheet.src=tempCanvas.toDataURL();
// wire up the buttons to start the chomp and stopped animations
$("#chomp").click(function(){ pac.setAnimation("chomp"); });
$("#stopped").click(function(){ pac.setAnimation("stopped"); });
// draw 1 sprite on the canvas
function drawSprite(translateX,y1,y2){
// draw hexagon
context.save();
context.translate(translateX,0);
context.beginPath();
context.moveTo(54.0, 12.8);
context.lineTo(34.2, 1.4);
context.bezierCurveTo(31.2, -0.3, 27.6, -0.3, 24.7, 1.4);
context.lineTo(4.9, 12.8);
context.bezierCurveTo(1.9, 14.5, 0.1, 17.7, 0.1, 21.0);
context.lineTo(0.1, 43.9);
context.bezierCurveTo(0.1, 47.3, 1.9, 50.5, 4.9, 52.1);
context.lineTo(24.7, 63.6);
context.bezierCurveTo(27.6, 65.3, 31.2, 65.3, 34.2, 63.6);
context.lineTo(54.0, 52.1);
context.bezierCurveTo(56.9, 50.5, 58.7, 47.3, 58.7, 43.9);
context.lineTo(58.7, 21.0);
context.bezierCurveTo(58.7, 17.7, 56.9, 14.5, 54.0, 12.8);
context.closePath();
context.fillStyle="blue";
context.fill();
// draw eye
context.beginPath();
context.arc(34,10,3,0,Math.PI*2,false);
context.closePath();
context.fillStyle="white";
context.fill();
context.strokeStyle="orange";
context.lineWidth=1.5;
context.stroke();
// draw mouth in various stages of chomping
context.beginPath();
context.moveTo(59,y1);
context.lineTo(25,32);
context.lineTo(59,y2);
context.closePath();
context.fillStyle="white";
context.fill();
context.restore();
}
}); // end $(function(){});
</script>
</head>
<body>
<button id="chomp">Chomp</button>
<button id="stopped">Stop</button>
<div id="container"></div><br>
<canvas id="canvas" width=600 height=100></canvas>
</body>
</html>
You can use a Kinetic.Animation
with a switch statement to determine which frame to show, something like this: 您可以使用带有switch语句的
Kinetic.Animation
来确定要显示的帧,如下所示:
var group = new Kinetic.Group({
x:10,
y:10
});
group.add(pacMan1);
group.add(pacMan2);
group.add(pacMan3);
layer.add(group);
layer.draw();
pacMan2.hide();
pacMan3.hide();
var frameCount = 0;
var anim = new Kinetic.Animation(function (frame) {
frameCount++;
var mod = frameCount % 30;
switch (mod) {
case 0:
pacMan1.show();
pacMan2.hide();
pacMan3.hide();
break;
case 10:
pacMan1.hide();
pacMan2.show();
pacMan3.hide();
break;
case 20:
pacMan1.hide();
pacMan2.hide();
pacMan3.show();
break;
}
group.setX(group.getX()+1);
}, layer);
anim.start();
You can make the frames go by faster by changing the modulo formula and the case numbers. 通过更改模数公式和案例编号,您可以更快地使帧变得更快。
//Faster
var mod = frameCount % 3;
switch (mod) {
case 0:
break;
case 1:
break;
case 2:
break;
}
//Slower
var mod = frameCount % 300;
switch (mod) {
case 0:
break;
case 100:
break;
case 200:
break;
}
And if you want him to move faster than change the interval that x
increases by: 如果你想让他移动得比改变
x
增加的间隔更快:
//Move 5 pixels every frame.
group.setX(group.getX()+5);
It's not a great answer, but it's a start. 这不是一个好的答案,但它是一个开始。
I thought of using the toImage()
method to turn your hex
shapes into images, then using that in a Kinetic.Sprite
我想过使用
toImage()
方法将你的hex
变成图像,然后在Kinetic.Sprite
使用它
http://kineticjs.com/docs/Kinetic.Shape.html#toImage http://kineticjs.com/docs/Kinetic.Shape.html#toImage
http://kineticjs.com/docs/Kinetic.Sprite.html http://kineticjs.com/docs/Kinetic.Sprite.html
And a tutorial: http://www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-sprite-tutorial/ 和教程: http : //www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-sprite-tutorial/
But, I think the problem with that is you need to have an image set up for sprites (something like: http://www.html5canvastutorials.com/demos/assets/blob-sprite.png ) 但是,我认为问题在于你需要为精灵设置一个图像(例如: http : //www.html5canvastutorials.com/demos/assets/blob-sprite.png )
Ideally though for your purpose, I think that using a Kinetic.Sprite
is what you're looking for so if you can set up that sprite based image with your pac man shapes then you'll be set to do a whole ton of things with the sprite . 理想情况下,虽然为了您的目的,我认为使用
Kinetic.Sprite
是您正在寻找的,所以如果您可以使用您的pac man形状设置基于精灵的图像,那么您将被设置为执行大量的事情精灵 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.