js 动画
动画
过去想要实现动画都是使用定时器,但是定时器的精度不高,可能导致动画播放不平滑。为了使计时精确,便是用requestAnimationFrame(func).并且这个函数还可以有一个参数,它的类型是DOMHighResTimeStamp,表示开始执行回调函数的时刻。
没执行一次requestAnimationFrame(func),他就会执行一次回调函数。但是这并不是一定的,如果调用太快他会自动进行合并。可以认为有一个任务队列,调用这个函数将它插入这个队列中,但是如果队列中有这个函数就不会插入。
function updateProgress(time) |
- window.cancelAnimationFrame(ID): 前面一个函数的返回值是一个ID,
canvas
<canvas>
元素创建一个画布。创建它时至少要提供width和height属性,否则不会显示。开始标签和结束标签中的内容是不支持<canvas>
时提示的内容。
<canvas id="drawing" width="200" height="200">A drawing of something</canvas>
想要在canvas上进行绘图,首先要获得绘图上下文,使用getContext("2d")
可以获得2D图形绘图对象。
let drawing = document.getElementById("drawing"); |
可以使用toDateURL(type)
获得<canvas>
上的图像,参数为图片的类型。let drawing = document.getElementById("image/png");
if(drawing.getContext)
{
let imgURI = drawing.toDataURL("image/png");
let image = document.createElement("img");
imge.src = imgURI;
document.body.appendChild(image);
}
2D绘图
属性:
- width:
- height: 画布的长宽,默认是在画布的左上角,其他的坐标值都根据该点计算
- fillStyle: 填充样式,gradient是渐变
- strokeStyle: 边框样式
- context.font: 以css语法决定的字体样式,例如
10px Arial
- textAlign: 对齐方式,可以为start、end、left、right、center。推荐使用start和end,不使用left和right
- textBaseLine: 指定文本的基线,可以为top、bottom、hanging、middle、alphabetic、ideographic。top表示y坐标在文本顶部,bottom表示y坐标在文本底部
- shadowColor: css颜色值
- shadowOffsetX: 阴影相对于路径的x坐标偏移量,默认是0
- shodowOffsetY:
- showdowBlur: 阴影的模糊量
- globalAlpha: 透明度
- globalCompositionOperation: 图像合成模式
绘制矩形:
- fillRect(x, y, w, h): 填充矩形,填充的样式由fillStyle决定
- strokeRect(x, y, w, h):
- clearRect(x, y, w, h):
例如:let drawing = document.getElementById("drawing");
if(drawing.getContext)
{
let context = drawing.getContext("2d");
context.fillStyle = "#ff0000";
context.fillRect(10, 10, 50, 50);
context.fillStyle = "rgba(0, 0, 255, 0.5)";
context.fillRect(30, 30, 50, 50);
}
绘制路径
路径由多个点组成,可以闭合也可以不闭合,可以利用它绘制各种复杂的图形。
首先调用context.beginPath()表示开始绘制,然后再调用下列方法进行绘制(只是描点,并没有真正开始绘制,还需要运行绘制完成操作才可以进行绘制)
- arc(x, y, radius, startAngle, endAngle, counterclockwise): 以(x, y)为中心,radius为半径绘制一条弧形。counterclockwise表示是否逆时针开始(默认是顺时针)
- arcTo(x1, y1, x2, y2, radius): 从(x1, y1)到(x2, y2)绘制一条半径为raidus的弧
- bezierCurveTo(c1x, c1y, c2x,c2y, x, y): 绘制一条以(c1x, c1y)和(c2x, c2y)为控制点,从上一点到(x, y)的弧线(三次贝塞尔曲线) 结果为
let drawing = document.getElementById("drawing_canvas");
if (drawing.getContext)
{
let ctx = drawing.getContext("2d");
ctx.beginPath();
ctx.moveTo(20, 20);
ctx.bezierCurveTo(20, 100, 200, 100, 200, 20);
ctx.stroke();
} - lineTo(x, y): 从上一点到(x, y)绘制直线
- moveTo(x, y): 画笔移动到(x, y)
- quadraticCurveTo(cx, cy, x, y): 以(cx, cy)为控制点,绘制一条虫上一点到(x, y)的弧线(二次贝塞尔曲线)
- rect(x, y, width, height):
- isPointInPath(x, y): 检测点是否在路径中
绘制完成之后的操作函数
- closePath(): 绘制前面所有的线和一条道起点的线
- fill(): 填充路径
- stroke(): 绘制路径,使用这个函数才会真正在画面上有显示
- clip(): 创建一个剪切区域
绘制文本
- fillText(str, x, y, maxpexel): 以(x, y)为基准点开始绘制str,最大像素为maxpexel。他会使用fillstyle属性
- strokeText(str, x, y, maxpexel): 参数含义和上面相同
- measureText(): 获得一个文本属性对象,目前这个对象只有width一个属性
例如:context.font = "bold 14px Arial";
context.textAlign = "center";
context.textBaseLine = "middle";
context.fillText("12", 100, 20);
//使用measureText限制最大宽度 |
变换
可以对图像进行缩放,平移,旋转等操作
- rotate(angle): 以原点为中心旋转angle角度
- scale(scalex, scaley): 进行缩放,x乘以scalex,y乘以scaley
let drawing = document.getElementById("drawing_canvas");
if (drawing.getContext)
{
let ctx = drawing.getContext("2d");
ctx.beginPath();
ctx.scale(1, 0.5);
ctx.strokeRect(0, 0, 100, 100);//一个正方形
ctx.stroke();
} - translate(x, y): 把坐标原点移动到(x, y)主要是为了配合rotate使用
- transform(m1_1, m1_2, m2_1, m2_2, dx, dy): 综合缩放旋转和移动,具体可看
渐变
- createLinearGradient(x1, y1, x2, y2): 创建从(x1, y1)到(x2, y2)的渐变对象
- createRadialGradient(x, y, radius, dstx, dsty, dstr): 放射性渐变,六个参数控制两个圆,第一个是内部圆,第二个是外部圆。
获得渐变对象之后,可以使用addColorStop()方法创建色标.并且这个对象可以赋值给fillStyle和strokeStyle
- gradient.addColorStop(loc, color): loc是0-1范围的值,color是颜色
例如:let drawing = document.getElementById("drawing_canvas");
if (drawing.getContext)
{
let ctx = drawing.getContext("2d");
let gradient = ctx.createLinearGradient(30, 30, 70, 70);
gradient.addColorStop(0, "white");
gradient.addColorStop(1, "black");
ctx.fillStyle = gradient;
ctx.fillRect(50, 50, 50, 50);
}
正常情况下应该一半黑一半白,但是这里几乎都是黑色,因为渐变的范围是(30, 30)到(70, 70),到了矩形部分已经快渐变完了,因此显示都是黑色。因此为了显示比较好的渐变要渐变范围和图形范围相适应。
图像处理
- drawImage(image, x, y, w, h, dstx, dsty, dstw, dsth): x,y,w,h是原图像的截取区域,dstx…是绘图区域中的一部分。
- createPattern(img, repeat): 第一个参数时一个
<img>
元素,第二个参数是重复方式,有repeat、repeat-x、repeat-y和no-repeat
let image = document.images[0]; |
- getImageData(x, y, w, h): 获得区域内的图像数据,返回的对象中有width、height、data三个属性。
- putImageData(data, x, y): 将imageData对象放到(x, y)起点处
data属性表示像素,它是一个一维数组,前四个表示第一个像素的r,g,b,a。let data = imageData.data;
let red = data[0];
let green = datat[1];
let blue = data[2];
let alpha = data[3];
let red2 = data[4];
globalCompositionOperation是多个形状之间如何融合。各属性具体讲解