网站首页 » 前端开发 » HTML5 » Canvas 动画之来回运动的小圆
上一篇:
下一篇:

Canvas 动画之来回运动的小圆

正如标题所说的,本文是要实现一个无限循环运动(直线运动)的小圆。通过本文你可以学到在 Canvas 中最基本的动画制作。这个动画有如下特点:

  • 无限循环运动(上下来回运动)
  • 随机速度
  • 随机加速度
  • 随机的圆大小
  • 随机的圆初始位置

好了,废话不多说,我们真接来看代码,没有代码解决不了的问题:

超简单的HTML (index.html)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas 动画之来回运动的小圆-云库前端</title>
    <style>
    *{
       margin: 0;
       padding: 0;
     }
     html,
     body{
        width: 100%;
        height: 100%;
     }
     canvas{
          display: block;
          background: #000;
     }
     </style>
</head>
<body>
<script src="index.js"></script>
</body>
</html>
JavaScript 代码(index.js)
/*
* @Author: 朝夕熊
* @Date:   2017-10-23 18:27:45
* @Last Modified by:   朝夕熊
* @Last Modified time: 2017-10-23 22:26:25
*/

var stateW = document.body.offsetWidth,
    stateH = document.body.offsetHeight;
var ifr = document.createElement("canvas");
var ifrW = ifr.width = stateW,
    ifrH = ifr.height = stateH;
var ctx = ifr.getContext("2d");
    document.body.appendChild(ifr);

window.onresize = function(){ // 改变窗口在时,重置画布大小
    stateW = document.body.offsetWidth;
    stateH = document.body.offsetHeight;
    ifrW = ifr.width = stateW;
    ifrH = ifr.height = stateH;
}

function Circle(){
    this.a = ramdomNumber(1,10); // 随机生成一个加速度
    this.t = ramdomNumber(2,4);; // 随机生成一个运动时间
    this.mile = 0; // 运动的距离
    this.size = ramdomNumber(3,100); // 随机生成圆半径
    this.x = ramdomNumber(0,ifrW); // 随机生成圆心 x 坐标
    this.y = 0;
    this.timer = null; // 定时器
}

Circle.prototype.render = function(){
var _this = this; // 保存 this 指向;
this.timer = setInterval(animate,30);
    function animate(){
        _this.mile = 0.5*_this.a*Math.pow(_this.t,2); // 匀速直线运动的公式
        ctx.clearRect(0,0,ifrW,ifrH); // 清空画布
        _this.y += _this.mile ; // 求出圆心y轴坐标

        if( _this.y > ifrH - _this.size){ // 如果运动到画布底部
            _this.y = ifrH - _this.size;
            _this.a = -_this.a; // 改变运动方向
        }
        if(_this.y<_this.size){ // 如果回到画布顶部位置
            _this.y = _this.size;
            _this.a = -_this.a; // 改变运动方向
        }
        ctx.fillStyle = "#fff";
        ctx.beginPath(); // 这个一定要加
        ctx.arc(_this.x,_this.y,_this.size,0,2*Math.PI);
        ctx.closePath(); // 这个一定要加
        ctx.fill();
    }
}

function ramdomNumber(min, max){
    return Math.random()*(max-min)+min;
}

// 创建一个运动对象
var iCircle = new Circle();
iCircle.render();

代码的相关位置都会有注解,让你一看一个准。在线 DEMO:http://yunkus.com/demo/canvas/canvas-infinite-uniform-motion-circle/

在这个例子中,你可以通过刷新页面的方式来查看随机生成的不同效果。

虽然效果做出来的,但美中不足的是这个圆的动画看起来有很明显的卡顿现象,不流畅。所以我们需要对上面的代码进行改进我们不用定时了,我们使用 window.requestAnimationFrame(fn) 方法。代码如下:

完美 (index.html)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Canvas 动画之来回运动的小圆顺滑版-云库前端</title>
     <style>
*{
    margin: 0;
    padding: 0;
}
html,body{
    width: 100%;
    height: 100%;
}
canvas{
    display: block;
    background: #000;
}
     </style>
</head>
<body>
<script src="index.js"></script>
<script>
var stateW = document.body.offsetWidth,
    stateH = document.body.offsetHeight;

var ifr = document.createElement("canvas");
var ifrW = ifr.width = stateW,
    ifrH = ifr.height = stateH;
    var ctx = ifr.getContext("2d");
    document.body.appendChild(ifr);

    var iSnow = new Snow({
        ifrW:ifrW
    });
    iSnow.render(ctx);

move();
function move() {
    if(iSnow.y>ifrH-iSnow.size){
        iSnow.y = ifrH-iSnow.size;
        iSnow.speed = -iSnow.speed;
    }
    if(iSnow.y<iSnow.size){
        iSnow.y = iSnow.size;
        iSnow.speed = -iSnow.speed;
    }
    window.requestAnimationFrame(move);
    ctx.clearRect(0,0,ifrW,ifrH);
    iSnow.y+=iSnow.speed;
    iSnow.render(ctx);
}

</script>
</body>
</html>
JavaScript代码 (index.js)
/*
* @Author: 朝夕熊
* @Date:   2017-10-23 18:27:45
* @Last Modified by:   朝夕熊
* @Last Modified time: 2017-10-30 21:35:17
*/
function Snow(option){
    this.speed = ramdomNumber(1,10); // 随机生成一个加速度
    this.size = ramdomNumber(3,100); // 随机生成圆半径
    this.x = ramdomNumber(0,option.ifrW); // 随机生成圆心 x 坐标
    this.y = 0;
}

Snow.prototype.render = function(ctx){
ctx.fillStyle = "#fff";
ctx.beginPath(); // 这个一定要加
ctx.arc(this.x,this.y,this.size,0,2*Math.PI);
ctx.closePath(); // 这个一定要加
ctx.fill();
}

function ramdomNumber(min, max){
    return Math.random()*(max-min)+min;
}

在线 DEMO:http://yunkus.com/demo/canvas/canvas-infinite-uniform-motion-circle/index2.html,代码改动有点大,但万变不离其宗。

下面列出一些比较常见的运动。

碰撞运动:http://yunkus.com/demo/canvas/canvas-infinite-uniform-motion-circle/index3.html

自由落体运动:http://yunkus.com/demo/canvas/canvas-infinite-uniform-motion-circle/index4.html

  • 微信扫一扫,赏我

  • 支付宝扫一扫,赏我

声明

原创文章,不经本站同意,不得以任何形式转载,如有不便,请多多包涵!

本文永久链接:http://yunkus.com/canvas-infinite-uniform-motion-circle/

发表评论

电子邮件地址不会被公开。 必填项已用*标注

评论 END