为什么这个requestAnmationFrame脚本不起作用?

时间:2012-05-21 05:49:12

标签: html5

我想用html5制作一个球,我实现了这个小脚本。但是,我看不到任何动画..我该如何解决这个问题?

<html>
    <head>
        <meta charset="utf-8">
        <script>
            canvas = document.getElementById("canvas");         
            window.onload=function(){
            if (document.createElement("canvas").getContext){
                //alert("browser supports canvas");
                //console.log(document.getElementById("canvas").getContext);
                canvas = document.getElementById("canvas");
                shape = new shapes();
                shape.drawball(canvas,100,"red");




                }
            };


function shapes(){
    this.drawtriangle = function(canvas){
        triangles = new triangle(0,0,0,200,200,200);
        triangles.draw(canvas.getContext('2d'));    
    }

    this.drawball = function(canvas,radius,color) {
        ball = new Ball(radius,color);
        ball.draw(canvas.getContext('2d'),canvas);
    }
}


function coordinates(x1,y1){
    this.x = x1;
    this.y = y1;
}





function angle(angle,speed){
    this.angle = angle;
    this.speed = speed;
}

function Ball(radius,color){
    this.origin = new coordinates(100,100);
    this.radius = (radius === "undefined" ) ? 40 : radius;
    this.color = (color === "undefined") ? red : color;
    this.rotation = 0;
    this.index  = 0;
    this.angles = new angle(0,0.2);
}

Ball.prototype.draw = function(context,canvas){

    context.fillStyle = this.color;
    context.strokeStyle = "blue";
    context.rotate(this.rotation);
    context.beginPath();
        context.arc(this.origin.x,this.origin.y,this.radius,0,(Math.PI*2),true)
    context.closePath();
    context.fill();
    context.stroke();
    this.animate(context,canvas);
}

Ball.prototype.animate = function(context,canvas){
        if (this.angles.angle < 1){
context.clearRect(0,0,1000,1000);
        console.log("Animating ... ");  
        this.origin.x = this.origin.x + 10; 
        this.origin.y = this.origin.y + 10; 
        this.angles.angle = this.angles.angle + this.angles.speed;
        window.requestAnimationFrame(this.draw(context));



    }
}


        </script>
        <style>

            body {
                background-color: #bbb;
                }       
            #canvas {
                background-color: #fff;
            }
        </style>
    </head>

    <body>
        <canvas id="canvas" width="1000px" height="1000px">
            Your browser dows bot suppoet canvas

        </canvas>


    </body>
</html>

1 个答案:

答案 0 :(得分:1)

您对requestAnimationFrame()的调用未传递回调,它正在执行一个函数并传递其未定义的返回值。我建议你改变这个:

Ball.prototype.animate = function(context,canvas) {
    if (this.angles.angle < 1) {
        context.clearRect(0,0,1000,1000);
        console.log("Animating ... ");  
        this.origin.x = this.origin.x + 10; 
        this.origin.y = this.origin.y + 10; 
        this.angles.angle = this.angles.angle + this.angles.speed;
        window.requestAnimationFrame(this.draw(context));
    }
}

到此:

Ball.prototype.animate = function(context,canvas) {
    if (this.angles.angle < 1) {
        context.clearRect(0,0,1000,1000);
        console.log("Animating ... ");  
        this.origin.x = this.origin.x + 10; 
        this.origin.y = this.origin.y + 10; 
        this.angles.angle = this.angles.angle + this.angles.speed;
        var self = this;
        window.requestAnimationFrame(function() {self.draw(context)});
    }
}

以便将适当的回调函数传递给requestAnimationFrame()

现在您已经包含了所有代码,这是另一个问题。你不能这样做:

canvas = document.getElementById("canvas");  

在head标记的javascript中,因为DOM尚未加载,因此它不会找到该对象。只有在通过等待表示已加载DOM的事件或通过在<body>部分的所有DOM元素之后的每一端运行javascript来加载DOM时,您必须这样做。

然后,第三,您必须使用特定于浏览器的requestAnimationFrame形式,因为每个浏览器可能都有自己的前缀。我用了这段代码:

var reqestAnimationFrame = 
    window.requestAnimationFrame ||
    window.mozRequestAnimationFrame || 
    window.msRequestAnimationFrame ||
    window.webkitRequestAnimationFrame;

当我将你的脚本放入jsFiddle并进行上述更改时,我发现动画运行得如此之快以至于看不到它。您的代码需要向其添加时间元素,以便动画在特定时间段内运行。通常这是通过定义动画的持续时间来完成的,并且在每个动画步骤中,您可以根据持续时间的百分比来缩放动画的位置。

以下是使用requestAnimationFrame的基于时间的动画示例:http://jsfiddle.net/jfriend00/nRE7S/