日常平凡事情中会碰到须要完成一些存在动画的页面。这里对动画的完成学问做一个整顿。
页面动画的完成能够分为两类:CSS动画、Canvas动画、JavaScript动画。JavaScript动画没啥好讲的,这里就不整顿了。
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
能够经由历程canvas
DOM对象的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)
步骤5closePath
只管不要遗忘。缘由和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
是指图片截取的肇端位置。width
,height
是指图片截取的宽高。dx
,dy
是目的在Canvas中的肇端坐标。dWidth
,dHeight
用于掌握canvas绘制的图片的缩放大小。
图片变形
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调试面板。试用了下,功用太少,对定位题目并没什么软用。
所以,关于调试的题目,只能试用传统的设断点,并逐渐运转看结果举行调试。