canvas

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;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 要在画布上绘制图形,首先要取得绘图上下文。使用 getContext()方法可以获取对绘图上下文的引用。对于平面图...
    ThunderChen阅读 3,961评论 0 0
  • canvas元素的基础知识 在页面上放置一个canvas元素,就相当于在页面上放置了一块画布,可以在其中进行图形的...
    oWSQo阅读 13,478评论 0 19
  • Canvas绘图 HTML5 的 canvas 元素使用 JavaScript 在网页上绘制图像。 画布是一个矩形...
    shanruopeng阅读 18,483评论 2 14
  • 1 Canvas接口元素定义 1.1 getContext()方法 为了在canvas上绘制,你必须先得到一个画布...
    Kevin_Junbaozi阅读 5,163评论 1 2
  • 线条样式 绘制直线,第五章知识简单回顾 lineWidth 设置或返回当前的线条宽度,单位为像素 lineCap ...
    Zd_silent阅读 3,375评论 0 0