寻找画布关键帧暂停关键帧动画示例

Posted

技术标签:

【中文标题】寻找画布关键帧暂停关键帧动画示例【英文标题】:Looking for Canvas Keyframe Pause Keyframe animation example 【发布时间】:2013-04-04 14:03:24 【问题描述】:

我只是在寻找一种在画布中创建关键帧动画的方法 向左停顿下去。而已。我的整本书和互联网都有各种简洁的流畅动画和交互性课程,css3 有关键帧,但除了插件或框架之外,我找不到任何用于画布 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);
  ());

添加了我能弄清楚的唯一答案,嵌套 if 条件,呸。我不想尝试根据此设置制作任何 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】:

[编辑以提供动画框架]

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

我保持简单,但您当然可以在此框架上构建。

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

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

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

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

下面的代码将导致对象:

    向左移动超过 20 帧, 暂停 30 帧, 向下移动超过 20 帧。

请注意,可以使用链接添加操作。

 // 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; 
    canvasborder: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>

【讨论】:

谢谢!尽管我对包装 requestAnimationFrame 的 setTimeout 如何保持适当的时间感到困惑。我认为这是 requestAnimationFrame 替换 setTimeout 的全部意义,因为它不是基于近距离时间,只是浏览器事件气泡 读得很好,谢谢,但它并不能真正解开谜团。我在上面添加了一些嵌套的 if 条件代码,这是我唯一能通过将书中的章节文件混合在一起来弄清楚的事情 apress html5 动画。这真的是无框架javascript方式的唯一解决方案吗? 好的,请参阅我编辑的答案。我编写了一个 javascript 框架来制作关键帧动画。随意使用/添加它以满足您的需求。 哦,太棒了!我马上去看看,谢谢!当你打字的时候,我有点想工作,因为我重新重新阅读 if 条件规则并阅读了很多博客来获得一个工作示例。但老实说,我只是对 vars 感到厌烦并且厌倦了反击。不知道设计模式会被称为什么。 jsfiddle.net/Wv9Gw 我不能给你足够的投票!所以只会说超独角兽彩虹谢谢你!从现在开始,我有很多东西要阅读和学习。再次感谢您。

以上是关于寻找画布关键帧暂停关键帧动画示例的主要内容,如果未能解决你的问题,请参考以下文章

scss [css:加载动画] css关键帧动画示例。 #css #sass

什么是关键帧动画

到底啥是动画关键帧啊

什么是关键帧动画

css3关键帧悬停动画firefox

动画的五个关键帧都有哪些?