css动画 css3中提供了一个属性 transition,用来实现css样式的平滑变化。举个例子:
.box { width: 100px; height: 100px; background: red; transition: width 1s;}.box:hover { width: 300px;}
当鼠标hover到 .box元素时,元素会在1s内逐渐的将宽度变化到300px。
具体效果可以去 这里查看。
使用 transition可以实现较为简单的动画。如果需要实现比较复杂的动画,可以使用 amination来实现。举个例子:
@keyframes cssamination { 0% {background: red; transform: skew(0deg);} 25% {background: yellow; transform: skew(-20deg);} 50% {background: blue; transform: skew(0deg);} 75% {background: green; transform: skew(20deg);} 100% {background: red; transform: skew(0deg);}}.amin { animation: cssamination 1s infinite ease;}
在上的例子中,首先由 keyframes定义一个动画叫做: cssanimation。在 cssanimation中定义了动画过程中关键的5帧。每一帧都设置了当前帧的样式特征。然后在 .amin节点上设置了动画属性 animation,并将其设为前面定义的动画 cssanimation,每一次动画1秒, infinite表示无限循环, ease表示缓动方式,两个关键帧之间的变化是 ease方式逐步变化的。
具体效果可以到 这里查看
animation的缓动函数有很多类型的值,有一个值比较特别就是 step[n[, start | end]]。 step的效果是将 keyframes中的每一个关键帧之间的切换并不是逐步变化的,而是到达某一关键帧后直接变化成新的关键帧样式,并保持不变,直到下一关键帧。所以使用 step可以实现css3的帧动画。写法如下:
@keyframes cssframeamination { 0% {background-position: 0 0;} 25% {background-position: -100px 0;} 50% {background-position: -200px 0;} 75% {background-position: -300px 0;} 100% {background-position: -400px 0;}}.amin-frame { background: url(./sprite.png) 0 0 no-repeat; animation: cssframeamination 1s infinite step(5, start);}
在上面的例子中,设置动画 cssframeamination,其中每一关键帧都是精灵动画图片的一帧图片。然后在 animation中设置 animation-timing-function为 step(5, start)表示动画分5帧。
有关css3动画相关的知识细节可以去 这里了解。
canvas canvas是一个html标签,用于提供给脚本进行画图图形的绘制。 canvas的绘制主要由 canvasrenderingcontext2d的实例来进行绘制。 canvasrenderingcontext2d可以通过 canvasdom对象的 getcontext获得,代码如下:
const canvas = document.getelementbyid('canvas');const ctx = canvas.getcontext('2d');
getcontext的参数是指在画布上绘制的类型,’2d’表示绘制二维图形。目前三维还没有实现,所以参数只支持’2d’。
绘制图形 canvas的上下文提供了众多的绘制方法。当你绘制一个图形时,基本思路是这样的:
调用 save方法保存之前的样式状态
调用 beginpath表示开始设置路径
调用 fillstyle, strokestyle等对接下来的路径进行样式设置
调用 moveto, lineto, rect, arc等设置路径
调用 closepath闭合路径
调用 fill或者 stroke对路径进行绘制
调用 restore恢复之前保存的样式状态
上面过程中的 save和 restore的作用是将已经设置的样式进行保存和恢复。当存在多个图形时,前面的样式如果不恢复为默认样式,会影响到第二个图形的样式。使用 save和 restore可以保证每一个图形在绘制开始时,都是默认的样式。当然,你也可以不调用 save和 restore,而是通过将前面已经设置过的所有样式进行逐个的还原。
save可以保存的样式类型有:
当前应用的变形(即移动,旋转和缩放)
strokestyle, fillstyle, globalalpha, linewidth, linecap, linejoin, miterlimit, shadowoffsetx, shadowoffsety, shadowblur, shadowcolor, globalcompositeoperation 的值
当前的裁切路径(clipping path)
步骤5 closepath尽量不要忘记。原因和 save, restore类似,如果忘记调用 closepath就会导致前后图形间多绘制一根线。
我写了一个时钟的例子: github
下面对各类接口做了一个整理
样式设置
接口名 接口描述
颜色
fillstyle 图形填充颜色
strokestyle 图形轮廓颜色
globalalpha 图形全局透明度
阴影
shadowoffsetx, shadowoffsety 阴影方向
shadowblur 设定阴影的模糊程度
shadowcolor 阴影的颜色值
线型
linewidth 线条宽度(int)
linecap 线条末端样式(butt: 平直; round: 添加半圆; square: 添加方形)
linejoin 设置线条间的接合处(bevel: 斜角; round: 圆角; miter: 尖角)
miterlimit 两线相交时尖角最大长度(linejoin:miter时生效,过长不显示)
getlinedash 返回当前虚线样式(数组)
setlinedash 设置虚线样式(数组)
linedashoffset 设置虚线样式起始偏移量
渐变
createlineargradient(x1, y1, x2, y2) 线性渐变
createradialgradient(x1, y1, r1, x2, y2, r2) 圆渐变, 渐变反向是从圆心向外发散
gradient.addcolorstop(position, color) 对生成的gradient对象添加结束颜色。position是中间过程,取值0~1
图案样式
createpattern(imageorcanvas, type) 创建图片填充对象。image必须是已加载完毕的;type: repeat, repeat-x, repeat-y, no-repeat
路径 接口名 描述
moveto(x, y) 移动路径绘制的起始点
beginpath() 新建一条路径
closepath() 闭合路径
lineto(x, y) 从开始位置绘制路径到目标位置
rect(x, y, width, height) 绘制矩形路径
arc(x, y, radius, startangle, endangle, anticlockwise) 绘制圆弧:x,y为圆心;radius为半径;startangle,endangle为起止位置;anticlockwise为反向(顺时针,逆时针)
arcto(x1, y1, x2, y2, radius) 绘制圆弧,并连接控制点
quadraticcurveto(cp1x, cp1y, x, y) x,y为结束点; cp1x,xp1y为控制点
beziercurveto(cp1x, cp1y, cp2x, cp2y, x, y) x,y为结束点;cp1x,cp1y为控制点1; cp2x,cp2y为控制点2
clip() 裁剪区域,区域外的不会发生绘制
绘制 接口名 描述
fillrect(x, y, width, height) 绘制填充矩形,等同于rect(); fill();
strokerect(x, y, width, height) 绘制矩形边框。等同于rect(); stroke()
fill() 填充路径的内容区域
stroke() 通过路径线条绘制图形轮廓
清除 接口名 描述
clearrect(x, y, width, height) 清除指定矩形区域
文字 接口名 描述
font 设置文字样式,同css的font
textalign 对其方式
textbaseline 基线对其
direction 文本方向
filltext(text, x, y [, maxwidth]) 绘制文字填充内容
stroketext(text, x, y [, maxwidth]) 绘制文字边框内容
measuretext(text) 返回文本的信息
样式保存 接口名 描述
save() 保存当前样式
restore() 恢复之前保存样式
绘制图片 canvas虽然可以绘制图形,但是最常用的应该是绘制图片。图片的绘制和图形的绘制类似。
canvas使用接口 drawimage()进行接口绘制,接口定义如下:
drawimage(image, x, y, width, height, dx, dy, dwidth, dheight);
其中的参数定义如下:
image可以使htmlimageelement, htmlvideoelement(video元素的某一帧), htmlcanvaselement, imagebitmap。
x, y是目标在canvas中的起始坐标。
width, height用于控制canvas绘制的图片的缩放大小。
dx, dy是指图片截取的起始位置。
dwidth, dheight是指图片截取的宽高。
图片变形 canvas还可以和css一样对图形进行变形转化。接口列表如下:
接口名字 描述
translate(x, y) 偏移。x,y是偏移量
rotate(angle) 旋转角度,顺时针
scale(x, y) 缩放。x, y分别是横轴,纵轴的缩放比例
transform(m11, m12, m21, m22, dx, dy) 变形矩阵转化
图形重叠处理 前面的例子中,当两个图形重叠后,都是由后面绘制的图形覆盖住前面绘制的图形。有时候需要改变这种情况。这种时候就可以使用 globalcompositeoperation来进行设置(还可以用来遮盖,清除某些区域)。具体参数可以去 这里查看
globalcompositeoperation: type
动画实现 使用上面的接口可以在canvas上绘制图片,但是都是固定的。当我们不断的对canvas进行重绘时,就可以达到动画的而效果。
动画的帧率达到60帧每秒时,也就是16ms没帧时,动画过程是流畅的。所以我们要对动画过程的绘制进行控制。有三个方法可以进行控制:
setinterval。设置每16ms执行一次绘制过程。但是该方法存在一个问题,开始运行绘制函数的时间点可能处于某一帧的快结束时间点。这个时候绘制过程需要小于16ms才可以达到流畅。
settimeout。和 setinterval类似。
requestanimationframe。该方法会在浏览器每一次绘制结束后调用一次。使用该方法可以很好的避免 setinterval和 settimeout出现的运行绘制函数时间不在每一帧开始的时间点。
canvas性能 创建一个离屏canvas, 预先对复杂图形进行绘制。
避免浮点数的坐标点, 使用math.floor()对坐标取整。
不要使用 drawimage去缩放图片。
使用多canvas绘制复杂场景。
使用css设置大背景图。
canvas调试 查了很多资料,发现chrome 44版本之前是有canvas调试功能的,但是chrome 44之后,将canvas调试功能去除了,并以扩展接口的方式提供功能。找了很久没有找到调试canvas的扩展。另外,firefox有提供专门的canvas调试面板。试用了下,功能太少,对定位问题并没什么软用。所以,关于调试的问题,只能试用传统的设断点,并逐步运行看效果进行调试。
