canvas 基本使用 原创

xjj_xnkl
发布于 2022-5-31 17:10
浏览
0收藏

canvas

  1. 基本用法
     <canvas width="300" height="300"></canvas>
    

    canvas 看起来和 img 元素非常相似,唯一不同的就是它没有 srcalt 属性,实际上 canvas 标签上只 widthheight 这两个可选属性(没有设置两个属性时,画布默认是 300 * 150 的大小)。如果使用 css 定义大小,绘制图形时会自适应它的框架尺寸(当 css 尺寸与原始画布不一致时,会出现扭曲,导致绘制的图形模糊)。

    img 标签不同的时,canvas 元素需要结束标签 </canvas> 。如果结束标签不存在,则文档的其余部分会被认为是替代内容,将不会显示出来。

  2. 绘制基本形状
    栅格

    在我们开始画图之前,我们需要了解一下画布栅格(canvas grid)以及坐标空间。上一页中的HTML模板中有个宽 300 像素, 高 300 像素的 canvas 元素。如右图所示,canvas 元素默认被网格所覆盖。通常来说网格中的一个单元相当于 canvas 元素中的一像素。栅格的起点为左上角(0, 0)。所有元素的位置都相对于原点定位。所以图中蓝色方形左上角的坐标为距离左边(X轴)x 像素,距离上边(Y轴)y 像素

    canvas 基本使用-鸿蒙开发者社区

    矩形
     const canvas = document.querySelector('.canvas')
     const ctx = canvas.getContext('2d')
     
     // 绘制一个填充的矩形 fillRect(x, y, width, height)
     // x: 矩形起始点的 x 轴坐标,y: 矩形起始点的 y 轴坐标。
     // width: 矩形的宽度, height: 矩形的高度。
     ctx.fillRect(0, 0, 100, 100)
     ctx.fill()
     // 绘制一个矩形的边框 strokeRect(x, y, width, height),参数说明同上
     ctx.strokeRect(200, 200, 100, 100)
     ctx.stroke()
    
     // 绘制一个矩形的边框 rect(x, y, width, height),参数说明同上
     ctx.beginPath()
     ctx.rect(100, 100, 50, 50)
     ctx.stroke()
    
     // 绘制一个矩形的边框
     ctx.beginPath()
     ctx.rect(150, 150, 50, 50)
     ctx.fill()
    

    例子输出如下图所示

    canvas 基本使用-鸿蒙开发者社区

    路径

    图形的基本元素是路径。路径是通过不同颜色和宽度的线段或曲线相连形成的不同形状的点的集合。一个路径,甚至一个子路径,都是闭合的。使用路径绘制图形需要一些额外的步骤:

    1. 创建路径起始点 beginPath()
    2. 使用画图命令去画出路径 moveTo() 或者 lineTo
    3. 路径封闭 closePath()
    4. 通过描边或填充路径区域来渲染图形 stroke() 或者 fill()
     const canvas = document.querySelector('.canvas')
     const ctx = canvas.getContext('2d')
     
     // beginPath() 新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。
     ctx.beginPath() 
     // moveTo(x, y) 将一个新的子路径的起始点移动到(x,y)坐标
     ctx.moveTo(0, 0)
     // lineTo(x, y) 使用直线连接子路径的终点到x,y坐标
     ctx.lineTo(300, 300)
     // stroke() 根据当前的画线样式,绘制当前或已经存在的路径的方法
     ctx.stroke()
     // closePath() 从当前点到起始点绘制一条直线,
     //如果图形已经是封闭的或者只有一个点,那么此方法不会做任何操作。
     ctx.closePath()
    

    例子输出如下图所示

    canvas 基本使用-鸿蒙开发者社区

    绘制三角形
     const canvas = document.querySelector('.canvas')
     const ctx = canvas.getContext('2d') 
     
     // 绘制一个填充的三角形
     // fill() 填充当前或已存在的路径,带参数的不做介绍
     // 当使用 fill() 时,图形会自动闭合路径,所以不需要 closePath 闭合
     ctx.beginPath()
     ctx.moveTo(0, 0)
     ctx.lineTo(300, 75)
     ctx.lineTo(0, 150)
     ctx.fill()
    
     // 绘制一个三角形边框
     ctx.beginPath()
     ctx.moveTo(0, 150)
     ctx.lineTo(300, 225)
     ctx.lineTo(0,300)
     // stroke() 不会自动闭合路径, 需要 closePath 闭合
     ctx.closePath()
     ctx.stroke()
    

    例子输出如下图所示

    canvas 基本使用-鸿蒙开发者社区

    圆弧

    ​ 绘制圆弧或者圆,我们使用 arc() 方法。当然可以使用 arcTo() ,不过这个的实现并不是那么的可靠,所以我们这里不作介绍。

     const canvas = document.querySelector('.canvas')
     const ctx = canvas.getContext('2d') 
    
     // arc(x, y, radius, startAngle, endAngle, anticlockwise),
     // 圆弧路径的圆心在 (x, y) 位置,半径为 r ,根据anticlockwise (默认为顺时针)
     // 指定的方向从 startAngle 开始绘制,到 endAngle 结束。
     // 绘制圆弧 0 - 90° 顺时针,
     // anticlockwise 可选,可选的Boolean值 ,如果为 true,逆时针绘制圆弧,反之,顺时针绘制
     // strokeStyle 绘制图形颜色或者样式的
     ctx.beginPath()
     ctx.arc(150, 150, 50, 0 ,Math.PI / 2 )
     ctx.strokeStyle = "red"
     ctx.stroke()
    
     // 绘制圆弧 0 - 90° 逆时针
     ctx.beginPath()
     ctx.arc(150, 150, 70, 0 ,Math.PI / 2, true )
     ctx.strokeStyle = "yellow"
     ctx.stroke()
    
     // 绘制圆
     ctx.beginPath()
     ctx.arc(150, 150, 100, 0 , Math.PI * 2)
     ctx.strokeStyle = "#3498db"
     ctx.stroke()
    

    例子输出如下图所示

    canvas 基本使用-鸿蒙开发者社区

    二次贝塞尔曲线及三次贝塞尔曲线

    ​ 二次贝塞尔曲线 ,quadraticCurveTo(cp1x,cp1y,x,y) , 其中参数 cp1x cp1y 是控制点的坐标,x 和 y 是终点坐标

    ​ 三次贝塞尔曲线, bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y) ,其中参数 cp1x,cp1y为控制点一,cp2x, cp2y为控制点二,x, y为结束点。
    canvas 基本使用-鸿蒙开发者社区

    const canvas = document.querySelector('.canvas')
    const ctx = canvas.getContext('2d') 
    
    // 绘制一个矩形边框
    ctx.strokeRect(0, 0, 300, 300)
   
    // 控制点 1 (200, 30)
    ctx.beginPath()
    ctx.arc(200, 30, 5, 0, Math.PI * 2)
    ctx.fill()
   
    // 控制点 2 (30, 200)
    ctx.beginPath()
    ctx.arc(30, 200, 5, 0, Math.PI * 2)
    ctx.fill()
   
    ctx.beginPath()
    ctx.moveTo(30, 200)
    ctx.quadraticCurveTo(30, 30, 200, 30)
    ctx.stroke()
   
    // 控制点 1 (20, 260)
    ctx.beginPath()
    ctx.arc(20, 260, 5, 0, Math.PI * 2)
    ctx.fillStyle = "red"
    ctx.fill()
   
    // 控制点 2 (200, 260)
    ctx.beginPath()
    ctx.arc(200, 260, 5, 0, Math.PI * 2)
    ctx.fillStyle = "red"
    ctx.fill()
   
    ctx.beginPath()
    ctx.moveTo(20, 180)
    ctx.bezierCurveTo(20, 260, 200, 260, 200, 180)
    ctx.strokeStyle = "red"
    ctx.stroke()

例子输出如下图所示
canvas 基本使用-鸿蒙开发者社区

  1. 颜色和样式
    色彩 Colors

    ​ 到目前为止,我们只看到过绘制内容的方法。如果我们想要给图形上色,有两个重要的属性可以做到: fillStylestrokeStyle

    ​ 一旦设置了 strokeStyle 或者 fillStyle 的值,那么这个新值就会成为新绘制的图形的默认值。如果你要给每个图形上不同的颜色,你需要重新设置 fillStylestrokeStyle 的值。

    color 可以是表示 css 颜色值的字符串,渐变对象或者图案对象。我们迟些再回头探讨渐变和图案对象。默认情况下,线条和填充颜色都是黑色( CSS 颜色值 #000000)。

     const canvas = document.querySelector('.canvas')
     const ctx = canvas.getContext('2d') 
     // fillStyle = color 设置图形的填充颜色
     // strokeStyle = color 设置图形轮廓的颜色
     // 这些 fillStyle 的值均为 '橙色'
     // ctx.fillStyle = "orange";
     // ctx.fillStyle = "#ffa500";
     // ctx.fillStyle = "rgb(255,165,0)";
     // ctx.fillStyle = "rgba(255,165,0,1)"; 
     const rectArray = new Array(10).fill(0)
    
     // 绘制 10 * 10 个矩形
     rectArray.forEach((row, rowIndex) => {
       rectArray.forEach((col, colIndex) => {
         ctx.fillStyle = `rgb(${255 - 42 * rowIndex},${255 - 42 * colIndex}, 0 )`
         ctx.fillRect(rowIndex * 30, colIndex * 30, 30, 30)
         ctx.fill()
       })
     })
    

    例子输出如下图所示

    canvas 基本使用-鸿蒙开发者社区

    线型

    可以通过一系列属性来设置线的样式。常用几个属性 :

    1. 设置线条宽度 : lineWidth = value, value描述线段宽度的数字。 0、 负数、 Infinity和 NaN 会被忽略

    2. 设置线条末端样式 : lineCap = type , 可取值 :

    3. butt : 线段末端以方形结束

    4. round : 线段末端以圆形结束

    5. ``square` : 线段末端以方形结束,但是增加了一个宽度和线段相同,高度是线段厚度一半的矩形区域

    6. 设定线条与线条间接合处的样式 : lineJoin = type ,可取值(这里不做演示) :

      1. bevel : 通过填充一个额外的,圆心在相连部分末端的扇形,绘制拐角的形状。 圆角的半径是线段的宽度
      2. round : 在相连部分的末端填充一个额外的以三角形为底的区域, 每个部分都有各自独立的矩形拐角
      3. miter : 通过延伸相连部分的外边缘,使其相交于一点,形成一个额外的菱形区域。这个设置可以通过 miterLimit 属性看到效果。
       const canvas = document.querySelector('.canvas')
       const ctx = canvas.getContext('2d')
       const lineCapArray = [
              	{ type: 'butt', width: 10, color: 'red' },
              	{ type: 'round', width: 10, color: 'black' },
              	{ type: 'square', width: 10, color: 'blue' }
            	]
      
       // 绘制基线
       ctx.strokeStyle = '#2ecc71'
       ctx.lineWidth = 2
       ctx.beginPath()
       ctx.moveTo(50, 0)
       ctx.lineTo(50, 250)
       ctx.stroke()
       ctx.beginPath()
       ctx.moveTo(250, 0)
       ctx.lineTo(250, 250)
       ctx.stroke()
      
       lineCapArray.forEach(({ type, width, color }, index) => {
         ctx.beginPath()
         ctx.moveTo(50, (index + 1) * 50)
         ctx.lineTo(250, (index + 1) * 50)
         ctx.lineWidth = width
         ctx.lineCap = type
         ctx.strokeStyle = color
         ctx.stroke()
       })
      

      例子输出如下图所示

    canvas 基本使用-鸿蒙开发者社区

    渐变颜色

    ​ 就好像一般的绘图软件一样,我们可以用线性或者径向的渐变来填充或描边。我们用下面的方法新建一个 canvasGradient 对象,并且赋给图形的 fillStylestrokeStyle 属性。创建出 canvasGradient 对象后,我们就可以用 addColorStop 方法给它上色了。

    ​ 线性渐变 : createLinearGradient(x1, y1, x2, y2) , 此方法接受 4 个参数,表示渐变的起点 (x1,y1) 与终点 (x2,y2)。

    ​ 线性渐变 : createRadialGradient(x1, y1, r1, x2, y2, r2) , 方法接受 6 个参数,前三个定义一个以 (x1,y1) 为原点,半径为 r1 的圆,后三个参数则定义另一个以 (x2,y2) 为原点,半径为 r2 的圆。

     const canvas = document.querySelector('.canvas')
     const ctx = canvas.getContext('2d')
     const lGradient = ctx.createLinearGradient(0, 0, 100, 100)
     lGradient.addColorStop(0, 'red')
     lGradient.addColorStop(1, 'blue')
    
     const rGradient = ctx.createRadialGradient(250, 250, 20, 250, 250, 30)
     rGradient.addColorStop(0, 'red')
     rGradient.addColorStop(1, 'blue')
    
     ctx.fillStyle = lGradient
     ctx.fillRect(0, 0, 100, 100)
    
     ctx.fillStyle = rGradient
     ctx.fillRect(200, 200, 100, 100)
    

    例子输出如下图所示

    canvas 基本使用-鸿蒙开发者社区

  2. 绘制文本

    在指定的位置填充指定的文本,绘制的最大宽度是可选的。fillText(text, x, y [, maxWidth])
    在指定的位置填充指定的文本边框,绘制的最大宽度是可选的。strokeText(text, x, y [, maxWidth])

 const canvas = document.querySelector('.canvas')
 const ctx = canvas.getContext('2d')

 // 符合CSS font 语法的DOMString 字符串。默认字体是 10px sans-serif
 ctx.font = '50px 宋体'
 // 描述绘制文本时,文本的对齐方式的属性
 // ctx.textAlign = "left" || "right" || "center" || "start" || "end";
 ctx.textAlign = 'center'
 // ctx.textBaseline = "top" || "hanging" || "middle" || "alphabetic" || "ideographic" || "bottom"
 // 绘制文本时,当前文本基线的属性
 ctx.textBaseline = 'middle'
 // ctx.direction = "ltr" || "rtl" || "inherit"
 // 制文本时,描述当前文本方向的属性
 // ctx.direction = "ltr"
 ctx.fillText('fill', 150, 100)
 ctx.strokeText('stroke', 150, 200)

例子输出如下图所示
canvas 基本使用-鸿蒙开发者社区

end …

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
分类
已于2022-5-31 17:10:57修改
3
收藏
回复
举报
3条回复
按时间正序
/
按时间倒序
xjj前端妹_雅
xjj前端妹_雅

常用画布 赞一个~

回复
2022-5-31 18:16:52
xjjFeRookie
xjjFeRookie

可以,快速入门 canvas 不错!

1
回复
2022-5-31 21:19:07
xjj_snntH
xjj_snntH

学到了

1
回复
2022-6-1 08:45:30
回复
    相关推荐