寻找Canvas Keyframe Pause Keyframe动画示例

时间:2013-04-12 06:35:54

标签: javascript canvas

我只是想找一种在画布上创建关键帧动画的方法 左转暂停下去。而已。我的整本书和互联网都有各种各样的流畅的动画和交互性课程,css3有关键帧,但是我找不到任何关于canvas javascript的插件或框架,我将来会使用但我现在想要一个简单的方法

  (function drawFrame () {
    window.requestAnimationFrame(drawFrame, canvas);
    context.clearRect(0, 0, canvas.width, canvas.height);

    ball.x += vx;
    ball.pause(2)// 2 seconds;
    ball.y += vx+1;
    ball.draw(context);
  }());

添加了我能解决的唯一答案,如果有条件,则嵌套。我不想尝试在此设置中制作任何4个以上的关键帧

// Check to see if it reached target
       if (Math.abs(dx) < 1) {
          ball.x = targetX;
          //window.cancelRequestAnimationFrame(animRequest);
          log.value = "Animation done!";

// if it did, now fire off the second keyframe and check if it reached new target
          if(Math.abs(dy) < 1){
            ball.y = targetY;
          } else{
            var vy = dy * easing;
            ball.y += vy;
          }

        } 

// Otherwise continue first keyframe move.
        else {
          var vx = dx * easing;
          ball.x += vx;
        }
        ball.draw(context);
      }

1 个答案:

答案 0 :(得分:2)

[编辑提供动画框架]

这是我创建的用于执行关键帧动画的入门框架

我保持简单,但你可以建立在这个框架上。

您可以定义一个或多个要在关键帧中使用的画布对象,如下所示:

        // define a drawing function that will draw your object on the canvas
        var drawFn1=function(context,x,y){
            var radius=30;
            context.strokeStyle="blue";
            context.lineWidth=5;
            context.fillStyle="green";
            context.beginPath();
            context.arc(x, y, radius, 0, 2 * Math.PI, false);
            context.stroke();
            context.fill();
        }

        // create a new displayobject
        var displayObject1=new DisplayObject(200,100,drawFn1);

然后将1个或多个显示对象添加到对象数组中。您可以单独为所有这些对象设置关键帧 - 所有对象都可以有单独的动画。

        // create an array of DisplayObjects
        var displayObjects=[];

        // push our displayObject1 into displayObjects
        displayObjects.push(displayObject1);

然后添加您希望对象执行的操作(以及完成这些操作的持续时间)。您可以根据需要添加任意组合的动作。现在,我只编写了2个动作:“移动”和“暂停”。您当然可以向框架添加更多操作。

如果需要,您可以在播放当前关键帧时添加操作。当前操作完成后,任何添加的操作都会排队等待执行。

以下代码将使对象:

  1. 向左移动超过20帧,
  2. 暂停30帧,
  3. 向下移动超过20帧。
  4. 请注意,可以使用链接添加操作。

     // add actions for the displayobject
     displayObject1.moveBy(-75,0,20).pause(30).moveBy(0,75,20);
    

    这是代码和小提琴:http://jsfiddle.net/m1erickson/RjR9C/

    <!doctype html>
    <html>
    <head>
    <link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    
    <style>
        body{ background-color: ivory; padding:15px; }
        canvas{border:1px solid red;}
    </style>
    
    <script>
        $(function(){
    
            var canvas=document.getElementById("canvas");
            var ctx=canvas.getContext("2d");
    
    
            // defines an action to accomplish
            function Action(type,msDuration){
                var type=type;
                var duration=msDuration;
                var incrementalX;
                var incrementalY;
            }
    
    
            function DisplayObject(X,Y,Drawfunction){
    
                this.drawFunction=Drawfunction;
                this.x=X;
                this.y=Y;
    
                this.actionStack=[];
                this.currentAction=null;
                this.IsActive=false;
    
            }
            DisplayObject.prototype.pause=function(duration){
                var action=new Action();
                action.type="pause";
                action.duration=duration;
                this.actionStack.push(action)
                this.IsActive=true;
                return(this);
            }
            DisplayObject.prototype.test=function(){
              alert("test");
            }
            DisplayObject.prototype.moveBy=function(offsetX,offsetY,duration){
                var action=new Action();
                action.type="moveBy";
                action.duration=duration;
                action.incrementalX=offsetX/duration;
                action.incrementalY=offsetY/duration;
                this.actionStack.push(action)
                this.IsActive=true;
                return(this);
            }
            DisplayObject.prototype.tick=function(context){
    
                // If we have nothing to do...outta here!
                if(!this.IsActive){return;};
    
                //
                if(!this.currentAction){
                    this.currentAction=this.actionStack.shift();
                }
    
                // animate the current frame
                this.doNextFrame(context);
    
                // decrement the tick countdown on our current action
                this.currentAction.duration--;
    
                // if this action is done then load the next action
                if(this.currentAction.duration<=0){
                    if(this.actionStack.length>0){
                        this.currentAction=this.actionStack.shift();
                    }else{
                        this.currentAction=null;
                        this.IsActive=false;
                    }
                }
    
            }
            DisplayObject.prototype.doNextFrame=function(context){
    
                // update based on currentAction
                switch(this.currentAction.type){
                    case "pause":
                        break;
                    case "moveBy":
                        this.x+=this.currentAction.incrementalX;
                        this.y+=this.currentAction.incrementalY;
                        break;
                    default:
                        break;
                }
    
                // draw ourself
                this.drawFunction(context,this.x,this.y);
    
            }
    
    
            //  Here’s how you make use of this AnimationFrame framework
    
            var drawFn1=function(context,x,y){
                var radius=30;
                context.strokeStyle="blue";
                context.lineWidth=5;
                context.fillStyle="green";
                context.beginPath();
                context.arc(x, y, radius, 0, 2 * Math.PI, false);
                context.stroke();
                context.fill();
            }
            // create a new displayobject
            var displayObject1=new DisplayObject(200,100,drawFn1);
            // add actions for the displayobject
            displayObject1.moveBy(-75,0,20).pause(30).moveBy(0,75,20);
    
    
            // create an array of DisplayObjects
            var displayObjects=[];
            // push our displayObject1 into displayObjects
            displayObjects.push(displayObject1);
    
            function runOneFrame(){
                ctx.clearRect(0,0,canvas.width,canvas.height);
                for(var i=0;i<displayObjects.length;i++){
                    displayObjects[i].tick(ctx);
                }
            }
    
            var fps = 20;
            function Ticker() {
                setTimeout(function() {
                    requestAnimationFrame(Ticker);
                    runOneFrame();
                }, 1000/fps);
            }
    
            $("#go").click(function () { Ticker(); $("#go").hide(); });        
    
        }); // end $(function(){});
    </script>
    
    </head>
    
    <body>
        <button id="go">Begin animation frames</button><br/>
        <p>The display will go left, pause and go down.</p>
        <canvas id="canvas" width=300 height=300></canvas>
    </body>
    </html>