簡體   English   中英

如何在Kinetic.js中使用畫布圖像制作動畫?

[英]How to make animation out of canvas images in Kinetic.js?

我有以下代碼應該是動畫的三幀,我怎么能把它們變成Kinetic.js中的動畫? 這是一個像pacman一樣的六角形,可以打開和關閉它的嘴。 我有三個畫布圖像,作為三個幀,Kinetic.js中是否有內置函數來執行此操作? 或者我應該從頭開始創建一個? 在制作精靈之后,我怎么能做其他動畫,比如移動它,或者旋轉它,而不會破壞動畫(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();
                }
        });

以下是如何從“chomping hexes”創建Kinetic.Sprite動畫

由於您已經有了hex +口坐標,因此您甚至不需要預先創建的spritesheet。

您可以使用html canvas元素動態創建“chomping”spritesheet。

方法:

  • 從臨時html canvas元素開始
  • 在畫布上繪制所有摳圖
  • 使用canvas.toDataURL將該畫布轉換為spritesheet圖像
  • 通常使用該spritesheet來運行Kinetic.Sprite動畫

這是從html畫布創建的動態創建的spritesheet

在此輸入圖像描述

以下代碼在屏幕上顯示畫布用於說明目的,但您將在屏幕外創建臨時畫布。

這是代碼和小提琴: 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>

您可以使用帶有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();

通過更改模數公式和案例編號,您可以更快地使幀變得更快。

//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;
}

如果你想讓他移動得比改變x增加的間隔更快:

//Move 5 pixels every frame.
group.setX(group.getX()+5);

的jsfiddle

這不是一個好的答案,但它是一個開始。


另一種方法

我想過使用toImage()方法將你的hex變成圖像,然后在Kinetic.Sprite使用它

http://kineticjs.com/docs/Kinetic.Shape.html#toImage

http://kineticjs.com/docs/Kinetic.Sprite.html

和教程: http//www.html5canvastutorials.com/kineticjs/html5-canvas-kineticjs-sprite-tutorial/

但是,我認為問題在於你需要為精靈設置一個圖像(例如: http//www.html5canvastutorials.com/demos/assets/blob-sprite.png

理想情況下,雖然為了您的目的,我認為使用Kinetic.Sprite是您正在尋找的,所以如果您可以使用您的pac man形狀設置基於精靈的圖像,那么您將被設置為執行大量的事情精靈

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM