canvas
初始化canvas
<canvas id="c" width="500" height="500"></canvas>
<script>
var c = document.querySelector("#c") // 获得画布组件
var ctx = c.getContext("2d") // 获得绘制上下文(笔触)
</script>
以下属性默认为 ctx 对象(笔触)的属性
如:ctx.fillStyle='#fff'
样式和阴影
- 笔触属性:
- fillStyle='#fff' 设置或返回用于填充绘画的颜色 渐变或模式
- strokeStyle='#fff' 设置或返回用于笔触的颜色 渐变或模式
- shadowColor='#fff' 设置或返回用于阴影的颜色
- shadowBlur=20 设置或返回用于阴影的模糊级别
- shadowOffsetX=20 设置或返回阴影距形状的水平偏移
- shadowOffsetY=20 设置或返回阴影距形状的垂直偏移
- 方法(举例)
/* 创建线性渐变 */
let lgra=ctx.createLinearGradient(x1,y1,x2,y2) // 渐变开始点x坐标,渐变开始点y坐标,渐变结束点x坐标,渐变结束点y坐标
lgra.addColorStop(0,"black") // 规定渐变对象中的在0位置时的颜色
lgra.addColorStop(0.5,"red") // 规定渐变对象中的在0.5(一半)位置时的颜色
lgra.addColorStop(1,"white") // 规定渐变对象中的在1(终点)位置时的颜色
ctx.fillStyle=lgra // 设置样式为lgra
ctx.fillRect(20,20,150,100) // 填充一个矩形
/* 创建放射状/环形的渐变 */
var rgra=ctx.createRadialGradient(x0,y0,r0,x1,y1,r1) // 渐变开始圆心x坐标,渐变开始圆心y坐标,渐变开始圆的半径,渐变结束圆心x坐标,渐变结束圆心y坐标,渐变结束圆的半径
rgra.addColorStop(0,"red") // 规定渐变对象中的在0位置时的颜色
rgra.addColorStop(1,"white") // 规定渐变对象中的在1(终点)位置时的颜色
ctx.fillStyle=rgra // 设置样式为rgra
ctx.fillRect(10,10,150,100) // 填充一个矩形
/* 在指定的方向上重复指定的元素 */
let pat=ctx.createPattern(img,"repeat") // img假设为一个图片dom,repeat repeat-x repeat-y no-repeat
ctx.rect(0,0,150,100) // 创建一个矩形
ctx.fillStyle=pat // 设置样式为pat
ctx.fill() // 填充矩形
线条样式
- lineCap="round" 设置或返回线条的结束端点样式
- butt(默认,平直),round(圆形线帽),square(正方形线帽)
- lineJoin="round" 设置或返回两条线相交时,所创建的拐角类型
- miter(默认,创建尖角),bevel(创建斜角),round(创建圆角)
- lineWidth=10 设置或返回当前的线条宽度
- miterLimit=5 设置或返回最大斜接长度
- 只有当lineJoin属性为"miter"时,miterLimit才有效
- 如果斜接长度超过miterLimit的值,边角会以lineJoin的"bevel"类型来显示
矩形
- rect(x,y,w,h) 定义矩形,(20,20,100,100)
- x(矩形左上角的x坐标),y(矩形左上角的y坐标),w(矩形的宽度,以像素计),h(矩形的高度,以像素计)
- fillRect(x,y,w,h) 绘制'被填充'的矩形,默认填充为黑色,参数同上
- strokeRect(x,y,w,h) 绘制矩形(无填充),参数同上
- clearRect(x,y,w,h) 清除指定矩形内的像素
路径
- fill() 填充定义的路径
- stroke() 绘制定义的路径
- beginPath() 起始一条路径,或重置当前路径
- moveTo(x,y) 把路径移动到画布中的指定点,不创建线条
- lineTo(x,y) 添加一个新点,然后在画布中创建从该点到最后指定点的线条
- closePath() 创建从当前点回到起始点的路径
- clip() 从原始画布剪切任意形状和尺寸的区域,只有被剪切区域内的内容是可见的
- quadraticCurveTo(cx,cy,x,y) 定义二次贝塞尔曲线
- cx(控制点的x坐标),cy(控制点的y坐标),x(结束点的x坐标),y(结束点的y坐标)
/* 绘制二次贝塞尔曲线 */
ctx.moveTo(20,20) // 开始点
ctx.quadraticCurveTo(20,100,200,20) // 定义曲线
ctx.stroke() // 绘制
- bezierCurveTo(cx1,cy1,cx2,cy2,x,y) 创建三次方贝塞尔曲线
- cx1(控制点1的x坐标),cy1(控制点1的y坐标),cx2(控制点2的x坐标),cy2(控制点2的y坐标),x(结束点的x坐标),y(结束点的y坐标)
- arc(x,y,r,sa,ea,c); 创建弧 圆
- x(圆心x坐标),y(圆心y坐标),r(半径),sa(起始点弧度),ea(结束点弧度),c(顺时针还是逆时针方向true逆时针false顺时针)
/* 绘制一个圆 */
ctx.arc(100,75,50,0,2*Math.PI) // 定义一个圆
ctx.stroke() // 绘制
- arcTo(x1,y1,x2,y2,r); 创建两切线之间的弧 曲线
- x1(顶点x坐标),y1(顶点y坐标),x2(切点2x坐标),y2(切点2y坐标),r(半径)
/* 绘制两切线之间的弧 */
ctx.moveTo(20,20) // 定义开始点
ctx.lineTo(100,20) // 定义线段1,确定切点1
ctx.arcTo(150,20,150,70,50) // 定义弧(顶点 切点2 半径)
ctx.lineTo(150,120) // 定义线段2
ctx.stroke() // 绘制
- isPointInPath(x,y) 如果指定的点位于当前路径中,则返回true,否则返回false
/* 判断点是否在矩形中 */
ctx.rect(20,20,150,100)
if(ctx.isPointInPath(20,50)){
ctx.stroke()
}
转换
- scale(x,y) 缩放当前绘图至更大或更小
/* 绘制矩形,放大到2倍,再次绘制矩形 */
ctx.strokeRect(5,5,25,15) // 画一个矩形
ctx.scale(2,2) // 放大画布
ctx.strokeRect(5,5,25,15) // 再画一个矩形
ctx.scale(-1,1) // 设置负数可以得到画布的镜像
- rotate(a) 旋转当前绘图,a(旋转弧度)
- translate(x,y) 平移当前画布,x(x轴平移量),y(y轴平移量)
/* 平移矩形 */
ctx.fillRect(10,10,100,50) // 填充一个矩形
ctx.translate(10,10) // 平移画布
ctx.fillRect(10,10,100,50) // 重新填充一个矩形
- transform(scaleX,skewX,skewY,scaleY,translateX,translateY) 变形当前画布
- scaleX(水平缩放),skewX(水平倾斜,x轴正方向逆时针度数的正弦值),skewY(垂直倾斜),scaleY(垂直缩放),translateX(水平移动),translateY(垂直移动)
/* 变形矩形 */
ctx.transform(1,0.5,-0.5,1,30,10)
ctx.fillStyle="red"
ctx.fillRect(0,0,250,100)
- setTransform(scaleX,skewX,skewY,scaleY,translateX,translateY) 重置当前画布.然后执行transform()
文本
- font="font-style font-variant font-weight font-size/line-height font-family *[caption icon menu message-box small-caption status-bar]" 设置或返回字体属性
- 参数解释
- font-style(字体样式,normal正常 italic斜体 *oblique斜体)
- font-variant(字体变体,normal *small-caps大写转小写)
- font-weight(字体粗细,normal bold加粗 100~900 *bolder加粗 *lighter正常)
- font-size/line-height(规定字号和行高,像素)
- font-family(字体样式)
- caption(使用标题控件的字体,比如按钮 下拉列表等)
- icon(使用用于标记图标的字体)
- menu(使用用于菜单中的字体,下拉列表和菜单列表)
- message-box(使用用于对话框中的字体)
- small-caption(使用用于标记小型控件的字体)
- status-bar(使用用于窗口状态栏中的字体)
/* 写文字 */
ctx.font="40px Arial"
ctx.fillText("Hello World",10,50)
- textAlign="start|end|center|left|right"; 设置或返回文本对齐方式
- start(默认 指定位置开始),end(指定位置结束),center(文本中心放置在指定位置),left(文本左对齐),right(文本右对齐)
- textBaseline="alphabetic|top|hanging|middle|ideographic|bottom"; 设置或返回当前文本基线
- alphabetic(默认 普通字母基线),top(em框顶端),hanging(悬挂基线),middle(em框正中),ideographic(表意基线),bottom(em框底端)
- fillText(text,x,y,maxWidth); 绘制"被填充的"文本
- text(输出的文本),x(绘制文本的x坐标),y(绘制文本的y坐标),*maxWidth(最大文本宽度 以像素计)
- strokeText(text,x,y,maxWidth); 绘制文本(无填充)
- measureText(text) 返回包含指定文本宽度的对象 text(要测量的文本)
/* 输出文本的宽度 */
ctx.font="30px Arial"
var txt="Hello World"
ctx.fillText("width:" + ctx.measureText(txt).width,10,50)
ctx.fillText(txt,10,100)
图像
- drawImage(img,[sx,sy,swidth,sheight],x,y,[width,height]) 向画布上绘制图像 画布或视频
- img(规定要使用的图像 画布或视频DOM),x(要放置图像的x坐标位置),y(要放置图像的y坐标位置)
- sx(剪切的x坐标位置),sy(剪切的y坐标位置),swidth(被剪切图像的宽度),sheight(被剪切图像的高度),width(绘制图像的宽度(伸展或缩小图像)),height(绘制图像的高度)
- createImageData(width,height |imageDate) 创建空白的ImageData对象
- width(ImageDate对象的宽,以像素计),height(ImageDate对象的高,以像素计),imageDate(创建与另一个ImageData对象尺寸相同的新ImageData对象,不会复制图像数据)
/* 创建100*100像素的ImageData对象 */
var imgData=ctx.createImageData(100,100)
for (var i=0;i<imgData.data.length;i+=4){
imgData.data[i+0]=255 // R
imgData.data[i+1]=0 // G
imgData.data[i+2]=0 // B
imgData.data[i+3]=255 // A (0-255 0表示透明 255表示完全可见)
} // i=0 时,把ImageData对象中的第一个像素变为红色
ctx.putImageData(imgData,10,10)
- getImageData(x,y,width,height) 返回ImageData对象 复制画布上指定的矩形像素数据
- x(开始复制左上角x坐标),y(左上角y坐标),width(要复制矩形区域宽度),height(要复制矩形区域高度)
/* 复制画布上的一个矩形 */
ctx.fillStyle="green"
ctx.fillRect(10,10,50,50)
function copy(){
var imgData=ctx.getImageData(10,10,50,50)
ctx.putImageData(imgData,10,70)
}
- putImageData(imgData,x,y,[dirtyX,dirtyY,dirtyWidth,dirtyHeight]) 把图像数据(ImageData对象)放在画布上
- imgData(ImageData对象),x(左上角的x坐标 以像素计),y(左上角的y坐标 以像素计)
- dirtyX(控制ImageData对象x属性),dirtyY(ImageData对象y属性),dirtyWidth(ImageData对象width属性),dirtyHeight(ImageData对象height属性)
- imageData.width 返回ImageData对象的宽度
- imageData.height 返回ImageData对象的高度
- imageData.data 返回一个数组,包含ImageData对象的color/alpha数据
合成
- globalAlpha=number; 设置或返回当前绘图的alpha(透明值),number(0 全透明~1 不透明 之间)
- globalCompositeOperation="source-over"; 设置或返回新图像如何绘制到已有的图像上
- 可用的取值:
- source-over 默认 新图像显示在原图像上方
- source-atop 显示在原图像上方 位于原图像外的部分不可见
- source-in 显示在原图像上方 只有原图像内的部分会显示 原图像是透明的
- source-out 只会显示原图像之外部分 原图像是透明的
- destination-over 新图像显示在原图像下方
- destination-atop 新图像之外的原图像部分不会被显示
- destination-in 新图像内的原图像部分会显示 新图像是透明的
- destination-out 新图像外的原图像部分会显示 新图像是透明的
- lighter 显示原图像和新图像 重合部分颜色混合
- copy 显示新图像 忽略原图像
- xor 使用异或操作对新图像与原图像进行组合 重合区域不显示
其他
canvas 为 canvas标签的DOM对象
- save() 保存当前的画布状态
- restore() 回滚到之前保存的画布状态
- canvas.getContext(contextID) 返回一个用于在画布上绘图的环境 getContext("2d")
- canvas.toDataURL(type,encoderOptions) 将canvas导出为base64格式的图片
- type(图片格式 默认image/png,image/jpeg,image/webp)
- encoderOptions(在指定图片格式为image/jpeg或image/webp的情况下,可以从0到1的区间内选择图片的质量 如果超出取值范围 将会使用默认值0.92)
- canvas.createEvent(type) 创建事件对象
canvas应用例子
canvas压缩图片
function compressImg(img){
//创建画板
let canvas=document.createElement('canvas')
let ctx=canvas.getContext('2d')
//获取图片参数
let initSize=img.src.length
let width=img.width
let height=img.height
// 如果图片大于200万像素,计算压缩比并将大小压至400万以下
let ratio=(width*height)/2000000
if (ratio>1) {
ratio=Math.sqrt(ratio)
width/=ratio
height/=ratio
}else{
ratio=1
}
canvas.width=width
canvas.height=height
// 铺底色
ctx.fillStyle='#fff'
ctx.drawImage(img,0,0,width,height)
// 进行最小压缩
let ndata = canvas.toDataURL('image/jpeg')
return ndata;
}