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;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,036评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,046评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,411评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,622评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,661评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,521评论 1 304
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,288评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,200评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,644评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,837评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,953评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,673评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,281评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,889评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,011评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,119评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,901评论 2 355

推荐阅读更多精彩内容

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