美文网首页HTML5 Canvasweb前端相关ios开发
手把手教你canvas动画(汉堡图标动画一)

手把手教你canvas动画(汉堡图标动画一)

作者: merjiezo | 来源:发表于2016-03-24 20:51 被阅读858次

动画效果如下图:

汉堡图标动画

先附上源码:

html端:

<canvas>你的浏览器暂且不支持canvas</canvas>



css端:

.canvas {

    position: relative;

    left: 50%;

    top: 50px;

    transform: translateX(-300px);

    background-color: #FFF;

    border: 2px solid #AAA;

    border-radius: 5px;

}


js端:

(function() {

var canvas      = document.getElementById('canvasTeach'),

context      = canvas.getContext('2d'),

canvasWidth  = canvas.width,

canvasHeight = canvas.height,

lineLength  = 40,

middleLineX  = canvasHeight/2,

middleLineY  = canvasHeight/2,

velocity    = 0,

a            = 0.05,

circleA      = 0.00124,

circleV      = 0,

circlePI    = 0,

upLine      = canvasHeight/2 - 40,

downLine    = canvasHeight/2 + 40,

Switch      = 0;

context.lineCap  = 'round';

context.lineJoin = 'round';

context.strokeStyle = '#AAA';

window.onload = function() {

drawTheLine();

}

function drawTheLine() {

context.clearRect(0, 0, canvasWidth, canvasHeight);

context.lineCap = 'round';

context.strokeStyle = '#AAA';

context.lineWidth = 10;

context.beginPath();

context.moveTo(canvasWidth/2 - lineLength, canvasHeight/2 - 40);

context.lineTo(canvasWidth/2 + lineLength, upLine);

context.stroke();

context.beginPath();

context.moveTo(canvasWidth/2 - lineLength, canvasHeight/2 + 40);

context.lineTo(canvasWidth/2 + lineLength, downLine);

context.stroke();

context.beginPath();

context.moveTo(canvasWidth/2 - lineLength, middleLineX);

context.lineTo(canvasWidth/2 + lineLength, middleLineY);

context.stroke();

context.beginPath();

context.arc(canvasHeight/2,canvasHeight/2,87,0,-Math.PI*circlePI,true);

context.stroke();

}

context.canvas.onmousedown = function(e) {

if (Switch == 0) {

update();

Switch = 1;

} else {

turnAround();

Switch = 0;

}

}

function update() {

if (middleLineX != canvasHeight/2 - 40) {

middleLineX -= 2;

middleLineY -= 2;

context.clearRect(200, 140, 210, 150);

drawTheLine();

setTimeout(update, 1000/120);

} else {

if (upLine < canvasHeight/2 + 40) {

if (upLine <= canvasHeight/2) {

velocity += a;

circleV  += circleA;

} else {

velocity -= a;

circleV  -= circleA;

}

upLine += velocity;

middleLineY += velocity;

downLine -= velocity;

circlePI += circleV;

drawTheLine();

setTimeout(update, 1000/120);

} else {

return;

}

}

}

function turnAround() {

if (upLine > canvasHeight/2 - 39.9) {

if (upLine >= canvasHeight/2) {

velocity += a;

circleV  += circleA;

} else {

velocity -= a;

circleV  -= circleA;

}

upLine -= velocity;

middleLineY -= velocity;

downLine += velocity;

circlePI -= circleV;

drawTheLine();

setTimeout(turnAround, 1000/120);

} else {

context.clearRect(200, 140, 210, 150);

if (middleLineX < canvasHeight/2) {

middleLineX += 2;

middleLineY += 2;

drawTheLine();

setTimeout(turnAround, 1000/120);

} else {

return;

}

}

}

})();


首先介绍一下这个动画(附图):

动画开始 开始中间的线段先往上 与第一个重合后开始画外面的圆,所有的动画都是先快后慢 最后的效果图


css和html没什么好说的,主要介绍js端的代码:

首先是变量的定义:

canvas变量具体定位到html内对应的画布元素

context为图形上下文,这边选取2d渲染


canvas的对象

由于canvas是一个对象,有这几个对应的属性会用到

canvas.width              //画布宽度

canvas.height            //画布宽度

context图形上下文对象

context有以下有一些对象:

lineCap    //线段连接时的样式(默认butt),这边使用round

lineJoin    //线段连接时的样式(默认Miter),这边使用round

strokeStyle(线段颜色  例:#FFF)


用到的函数

drawTheLine函数(划线函数,时间线发生变化的时候按照规律调用)

update函数(变成叉的时候调用)

turnAround函数(返回成汉堡图标的时候调用)

onmousedown监听下面有一个匿名函数,内的代码代表开关的常用代码,当变成叉时使用update,当返回成汉堡图标的时候调用turnAround


canvas动画核心(帧动画)

介绍一下什么是帧动画:

      和拍电影的原理是一样的,动画都是由图片组成,每秒24张图片在人眼就可以看到流畅的动画了,那帧动画用的就是这个规则,我这边设置的调用比较多,达到每秒120帧,那这个动画在人眼看来就是一个很流畅的动画了。


那说了这么多,如何做到每秒120帧呐?

其实很简单,javascript给我们提供了一些制作帧动画的时间调用函数,这边就介绍两个我认为比较有代表的函数。

setTimeout( function ,ms);    //例子:setTimeout(update, 1000/120);

内置两个参数

第一个就是调用什么函数,可以是自身,可以是其他的函数,具体受自己的控制。

第二个参数是两次调用间隔的时间,每秒调用120次就是这么来的,由于以微秒计算,因此为1000/120

setInterval( function, ms)    //其实和上面的很像,但是这个函数一般作为循环动画使用

第一步:画画

那作为我们的第一步就是画画了!

canvas的画布给我们提供了按照路径画画,因此上下文这个概念变得尤为重要,上下文就代表着上一步是什么,当你需要进行下一步操作的时候,浏览器就会看你的上一步是什么,再根据你上一步运动到的位置连线(可以是直线,可以是曲线,看你具体调用了什么函数),这边有可能形容的有点抽象,我们现在就尝试着画一条直线来解释一下吧!

context.beginPath()    //方法开始一条路径,或重置当前的路径

context.stroke()        //方法会实际地绘制出通过 moveTo() 和 lineTo() 方法定义的路径。默认颜色是黑色

moveTo(width, heigth)//移动到位置

看到这边还是很糊涂啊!什么鬼!这些是什么!你在逗我!

这么说大家就理解了!

把浏览器看作一个画家

画家在画一根线之后就需要先做准备,那就调用beginPath()方法,当作一定的准备之后,他需要移动到某一个位置开始下笔,就会调用moveTo方法,参数分别代表了坐标系的x轴和y轴,然后他画了一条直线到了某个位置,就是lineTo()方法,到这边之后,他发现自己肚子饿了,不想画了,就调用stroke()方法结束这一笔

以上就是画家画一条线的过程,怎么样,是不是形象了很多!

因此,画一条线就变成了:

context.beginPath();

context.moveTo(110, 110);

context.lineTo(190, 110);

context.stroke();

所以下面我们就可以完成三条线的绘制,怎么样,是不是很简单!

下一章介绍动画

相关文章

网友评论

  • Airing:代码可以用代码块包起来,可读性更好。
    '''JavaScript
    //Codes
    '''
    merjiezo:@Airing 嗯!我的第二篇就标起来啦

本文标题:手把手教你canvas动画(汉堡图标动画一)

本文链接:https://www.haomeiwen.com/subject/hnmrlttx.html