canvas 模拟地球绕太阳转动 月球绕地球转动

requestAnimationFrame,Web中写动画的另一种选择

HTML5/CSS3时代,我们要在web里做动画选择其实已经很多了:

你可以用CSS3的animattion+keyframes;

你也可以用css3的transition;

你还可以用通过在canvas上作图来实现动画,也可以借助jQuery动画相关的API方便地实现;

当然最原始的你还可以使用window.setTimout()或者window.setInterval()通过不断更新元素的状态位置等来实现动画,前提是画面的更新频率要达到每秒60次才能让肉眼看到流畅的动画效果。

现在又多了一种实现动画的方案,那就是还在草案当中的window.requestAnimationFrame()方法。

window.requestAnimationFrame方法

来看MDN上对其给出的诠释:
window.requestAnimationFrame() 将告知浏览器你马上要开始动画效果了,后者需要在下次动画前调用相应方法来更新画面。这个方法就是传递给window.requestAnimationFrame()的回调函数。

也可这个方法原理其实也就跟setTimeout/setInterval差不多,通过递归调用同一方法来不断更新画面以达到动起来的效果,但它优于setTimeout/setInterval的地方在于它是由浏览器专门为动画提供的API,在运行时浏览器会自动优化方法的调用,并且如果页面不是激活状态下的话,动画会自动暂停,有效节省了CPU开销。

基本语法

可以直接调用,也可以通过window来调用,接收一个函数作为回调,返回一个ID值,通过把这个ID值传给window.cancelAnimationFrame()可以取消该次动画。

window.requestAnimationFrame(move);//move为回调函数

arc()方法:

arc(x,y,radius,x1,y2,false) 六个参数 x,y 圆心的坐标 , radius 圆的半径,x1为其实弧度,y1为终止弧度,如果画圆 x1 = 0,y1 = 2*Math.PI, 最后一个参数画圆的方向,有两个值 false (顺时针)和 true (逆时针)。

clearRect() 方法:

clearRect(x,y,w,h) 四个参数 x,y 为要清除位置的起始坐标, w,h 为要清除的宽高

开始画圆

画太阳,地球,月球的过程都是用 canvas 画圆,因为它们除了 圆心坐标和半径不一样以为 ,其他过程都是一样的,所以我将画圆的方法封装起来,在画的时候给不同的参数来调用这个类

封装类

function Point(x,y){
this.x = x; //圆心的 X 坐标
this.y = y; //圆心的 Y 坐标
}

function Circle(origin,radius,speed){
this.origin = origin;  //圆心
this.radius = radius;  //半径
this.speed = speed;   //转动速度
this.draw = drawCircle; //画圆的方法
}

function drawCircle(){
con.beginPath();  //开始绘制
con.arc(this.origin.x,this.origin.y,this.radius,0,2*Math.PI,false); //绘制圆
con.stroke();   //绘制的框
con.closePath();  //绘制结束
}

画太阳,地球,月亮

这里只需要调用前面封装好的类,传入参数即可

//画太阳
var sun = new Circle(new Point(400,300),30,0);
sun.draw();
//画地球轨迹
var earthPath = new Circle(sun.origin,200,0);
earthPath.draw();
//画地球
var earth = new Circle(new Point(earthPath.origin.x + earthPath.radius, earthPath.origin.y),20,0);
earth.draw();
//画月亮轨迹
var moonPath = new Circle(earth.origin,80,0);
moonPath.draw();
//画月亮
var moon = new Circle(new Point(moonPath.origin.x + moonPath.radius, moonPath.origin.y),10,0);
moon.draw();

让地球和月亮转动起来

function move(){
    con.clearRect(0,0,canvas.width,canvas.height);


    sun.draw();
    earthPath.draw();
    moonPath.draw();
    earth.draw();
    moon.draw();

    earth.origin.x = earthPath.origin.x + earthPath.radius * Math.cos(earth.speed);
    earth.origin.y = earthPath.origin.y + earthPath.radius * Math.sin(earth.speed);
    earth.speed += 0.02;

    moon.origin.x = moonPath.origin.x + moonPath.radius * Math.cos(moon.speed);
    moon.origin.y = moonPath.origin.y + moonPath.radius * Math.sin(moon.speed);
    moon.speed += -0.05;

    window.requestAnimationFrame(move);
}
    move();

效果图:

画面虽然简单了点 ,但转动的效果还是可以看见的

这里写图片描述

完整代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            canvas {border: 1px solid black;}
        </style>
    </head>
    <body>
        <canvas id="myCanvas" width="800" height="600"></canvas>
    </body>
    <script type="text/javascript">
        var canvas = document.getElementById('myCanvas');
        var con = canvas.getContext('2d');


        function Point(x,y){
            this.x = x; //圆心的 X 坐标
            this.y = y; //圆心的 Y 坐标
        }

        function Circle(origin,radius,speed){
            this.origin = origin;  //圆心
            this.radius = radius;  //半径
            this.speed = speed;   //转动速度
            this.draw = drawCircle; //画圆的方法
        }

        function drawCircle(){
            con.beginPath();  //开始绘制
            con.arc(this.origin.x,this.origin.y,this.radius,0,2*Math.PI,false); //绘制圆
            con.stroke();   //绘制的框
            con.closePath();  //绘制结束
        }
        //画太阳
        var sun = new Circle(new Point(400,300),30,0);
        sun.draw();
        //画地球轨迹0
        var earthPath = new Circle(sun.origin,200,0);
        earthPath.draw();
        //画地球
        var earth = new Circle(new Point(earthPath.origin.x + earthPath.radius, earthPath.origin.y),20,0);
        earth.draw();
        //画月亮轨迹
        var moonPath = new Circle(earth.origin,80,0);
        moonPath.draw();
        //画月亮
        var moon = new Circle(new Point(moonPath.origin.x + moonPath.radius, moonPath.origin.y),10,0);
        moon.draw();

        function move(){
            con.clearRect(0,0,canvas.width,canvas.height);


            sun.draw();
            earthPath.draw();
            moonPath.draw();
            earth.draw();
            moon.draw();

            earth.origin.x = earthPath.origin.x + earthPath.radius * Math.cos(earth.speed);
            earth.origin.y = earthPath.origin.y + earthPath.radius * Math.sin(earth.speed);
            earth.speed += 0.02;

            moon.origin.x = moonPath.origin.x + moonPath.radius * Math.cos(moon.speed);
            moon.origin.y = moonPath.origin.y + moonPath.radius * Math.sin(moon.speed);
            moon.speed += -0.05;

            window.requestAnimationFrame(move);
        }
        move();

    </script>
</html>
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值