Canvas基础

183 阅读9分钟

Canvas基础

  • H5新标签,在页面上绘制图形用的(简称画布)
  • canvas只是一个容器,用js脚本来控制他

填充和边框

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 填充的样式
  cvs.fillStyle()
  // 笔触颜色(边框颜色)
  cvs.strokeStyle()
  // 边框宽度
  cvs.lineWidth()
  // 绘制图形有两种方式
  cvs.fill() // 填充
  cvs.stroke() // 边框
</script>

画布坐标

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 开始一个新的路径
  cvs.beginPath()
  // 坐标是以画布为基准,距离画布上边的距离是y坐标值,距离画布左边的距离是x坐标值
  // 绘制线条
  // 如果没有moveTo就把上一个挨着的lineTo当作起始点坐标
  // 假如第一个不是moveTo,而是lineTo,那么lineTo为起始点坐标
  cvs.moveTo(x,y) // 起始点的坐标
  cvs.lineTo(x,y) // 结束点的坐标
  // 关闭当前路径,自动闭合,从结束坐标值到起始坐标值字动连接
  cvs.closePath()
</script>

绘制线条

以边框的形式显示

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 坐标是以画布为基准,距离画布上边的距离是y坐标值,距离画布左边的距离是x坐标值
  // 绘制线条
  cvs.beginPath()
  cvs.moveTo(50, 50)
  cvs.lineTo(150, 50)
  cvs.closePath()
  cvs.strokeStyle = "#c60023"
  cvs.lineWidth=20
  // 以边框的形式显示
  cvs.stroke()
</script>

绘制三角形

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 坐标是以画布为基准,距离画布上边的距离是y坐标值,距离画布左边的距离是x坐标值
  // 绘制线条
  cvs.beginPath()
  cvs.moveTo(80, 120)
  cvs.lineTo(80, 240)
  cvs.lineTo(200, 240)
  cvs.closePath()
  cvs.strokeStyle = "#c60023"
  cvs.lineWidth=10
  // 以边框的形式显示
  cvs.stroke()
</script>

线条交汇样式

  • lineJoin

    • 设置线条交汇处的样式 有三个属性:圆角round 斜接bevel 尖角miter
  • lineCap

    • 设置线条两端点的样式 有三个属性:butt(默认平) round圆角 square(方角)

设置线条两端点的样式

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 坐标是以画布为基准,距离画布上边的距离是y坐标值,距离画布左边的距离是x坐标值
  // 绘制线条
  cvs.beginPath()
  // 设置线条两端点的样式 有三个属性:butt(默认平) round圆角  square(方角)
  cvs.lineCap = "round"
  cvs.moveTo(50, 50)
  cvs.lineTo(250, 50)
  // cvs.closePath() // 加上这句话则没有端点设置的效果
  cvs.strokeStyle = "#c60023"
  cvs.lineWidth=10
  // 以边框的形式显示
  cvs.stroke()
</script>

设置线条交汇处的样式

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 坐标是以画布为基准,距离画布上边的距离是y坐标值,距离画布左边的距离是x坐标值
  // 绘制线条
  cvs.beginPath()
  // 设置线条交汇处的样式 有三个属性:圆角round 斜接bevel  尖角miter
  cvs.lineJoin  = "round"
  cvs.moveTo(200, 100)
  cvs.lineTo(100, 250)
  cvs.lineTo(300, 250)
  cvs.closePath() 
  cvs.strokeStyle = "#c60023"
  cvs.lineWidth=10
  // 以边框的形式显示
  cvs.stroke()
</script>

绘制圆

  • 圆:Math.PI*2
  • 半圆:Math.PI
  • 四分之一圆:Math.PI/2
<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 坐标是以画布为基准,距离画布上边的距离是y坐标值,距离画布左边的距离是x坐标值
  // 绘制线条
  cvs.beginPath()

  /*
  * cvs.arc(x,y,r,sAngle,eAngle,n)
  * x:圆心的x坐标值
  * y:圆心的y坐标值
  * r:半径
  * sAngle:开始的角度
  * eAngle:结束的角度
  * n:顺时针还是逆时针 false:顺时针(默认值) true:逆时针 
  */
  cvs.arc(150,150,100,0,Math.PI*2,false)
  cvs.closePath() 
  cvs.strokeStyle = "#c60023"
  cvs.lineWidth = 10
  // 以边框的形式显示
  cvs.stroke()
</script>

填充圆

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 坐标是以画布为基准,距离画布上边的距离是y坐标值,距离画布左边的距离是x坐标值
  // 绘制线条
  cvs.beginPath()

  /*
  * cvs.arc(x,y,r,sAngle,eAngle,n)
  * x:圆心的x坐标值
  * y:圆心的y坐标值
  * r:半径
  * sAngle:开始的角度
  * eAngle:结束的角度
  * n:顺时针还是逆时针 false:顺时针(默认值) true:逆时针 
  */
  cvs.fillStyle = "orange"
  cvs.arc(150, 150, 100, 0, Math.PI * 2, false)
  cvs.closePath()
  cvs.fill()

</script>

外层包裹圆

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 坐标是以画布为基准,距离画布上边的距离是y坐标值,距离画布左边的距离是x坐标值
  // 绘制线条
  cvs.beginPath()

  /*
  * cvs.arc(x,y,r,sAngle,eAngle,n)
  * x:圆心的x坐标值
  * y:圆心的y坐标值
  * r:半径
  * sAngle:开始的角度
  * eAngle:结束的角度
  * n:顺时针还是逆时针 false:顺时针(默认值) true:逆时针 
  */
  cvs.fillStyle = "orange"
  cvs.arc(200, 200, 40, 0, Math.PI * 2, false)
  cvs.closePath()
  cvs.fill()
  // 外层包裹
  cvs.strokeStyle="#c60018"
  cvs.lineWidth=40
  cvs.beginPath()
  cvs.arc(200, 200, 60, 0, Math.PI * 2, false)
  cvs.closePath()
  cvs.stroke()

</script>

注意:每次调用fill()的时候,如果不用closePath()进行闭合,则会把当次路径的起始点,结束点分别连接,填充整个闭合部分。

所以每次路径结束,要记得关闭当前路径

渐变

线性渐变

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 线性渐变
  /**
   * cvs.createLinearGradient(x1,y1,x2,y2)
   * x1:渐变开始的x坐标值
   * y1:渐变开始的y坐标值
   * x2:渐变结束的x坐标值
   * y2:渐变结束的y坐标值 纵向渐变则改变y值,横向渐变则改变x值
  */
  var clg = cvs.createLinearGradient(0,0,0,200,200)
  /*
  * clg.addColorStop(n,color)
  * n:渐变的偏移量 0-1之间的小数
  * color:颜色
  */
  clg.addColorStop(0,"#c60023")
  clg.addColorStop(0.25,"yellow")
  clg.addColorStop(0.5,"#c81")
  clg.addColorStop(0.75,"#c9c9")
  clg.addColorStop(1,"#282")
  // 将渐变绘制到矩形
  cvs.fillStyle =clg
  cvs.fillRect(0,0,200,200)

</script>

径向渐变

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 径向渐变,也叫发散型渐变
  /**
   * cvs.createRadialGradient(x1,y1,r1,x2,y2,r2)
   * x1:发散渐变开始中心的x坐标值
   * y1:发散渐变开始中心的y坐标值
   * r1:发散渐变开始的半径
   * x2:发散渐变结束中心的x坐标值
   * y2:发散渐变结束中心的y坐标值
   * r2:发散渐变结束的半径
  */
  var clg = cvs.createRadialGradient(200, 200, 200, 200, 200, 10)
  clg.addColorStop(0,"#c60023")
  clg.addColorStop(0.5,"#c81")
  clg.addColorStop(1,"#282")
  // 将渐变绘制到矩形
  cvs.fillStyle = clg
  cvs.fillRect(100, 100, 200, 200)

</script>

阴影

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 阴影
  cvs.shadowOffsetX = 10 // 阴影横向偏移量(默认值是0)
  cvs.shadowOffsetY = 10 // 阴影纵向偏移量(默认值是0)
  cvs.shadowColor = "rgba(0,0,0,0.5)" // 阴影颜色(默认值是黑色)
  cvs.shadowBlur = 10 // 阴影模糊度(默认值是0,值越大越模糊)
  cvs.fillStyle="orange"
  cvs.fillRect(100,100,100,100)

绘制文本

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 绘制文本
  cvs.font = "40px Arial" // 设置字体大小 字体类型
  // 水平对齐方式(属性值:start end center right)
  cvs.textAlign = "center"
  // 垂直对齐方式(属性值:top middle hanging alphabetic ideographic bottom)
  cvs.textBaseline = "middle"
  // 计算文本的长度
  var text = "你好"
  var width = cvs.measureText(text).width
  // 填充文字 cvs.fillText(文本, x坐标值, y坐标值)
  cvs.fillStyle = "red"
  cvs.fillText("你好"+width, 100, 100)
  // 绘制文字轮廓 cvs.strokeText(文本, x坐标值, y坐标值)
  cvs.strokeText("你好", 100, 100)
</script>

渐变文本fillText填充

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 渐变
  var clg = cvs.createLinearGradient(0,0,0,500)
  clg.addColorStop(0,"#c60023")
  clg.addColorStop(0.25,"yellow")
  clg.addColorStop(0.5,"#c81")
  clg.addColorStop(0.75,"#c9c9")
  clg.addColorStop(1,"#282")
  cvs.fillStyle = clg
  cvs.shadowOffsetX = 10 // 阴影横向偏移量(默认值是0)
  cvs.shadowOffsetY = 10 // 阴影纵向偏移量(默认值是0)
  cvs.shadowColor = "rgba(0,0,0,0.5)" // 阴影颜色(默认值是黑色)
  cvs.shadowBlur = 10 // 阴影模糊度(默认值是0,值越大越模糊)
  cvs.font = "30px 微软雅黑"
  cvs.textAlign = "center"
  cvs.textBaseline = "middle"
  cvs.fillText("我是文字",300,250)
</script>

渐变文本strokeText填充

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 渐变
  var clg = cvs.createLinearGradient(0, 250, 350, 350)
  clg.addColorStop(0, "blue")
  clg.addColorStop(0.25, "yellow")
  clg.addColorStop(0.5, "#c81")
  clg.addColorStop(0.75, "pink")
  clg.addColorStop(1, "#282")
  cvs.strokeStyle = clg
  cvs.font="40px Arial"
  cvs.strokeText("我是文字", 20, 230)
</script>

绘图

根据参数不同分为绘制图片和剪裁图片的效果

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 绘图
  /**
   * drawImage如果是五个参数,就是绘制图片
   * drawImage(img, 图片左上角的x坐标值, 图片左上角的y坐标值, 绘制图片的宽度, 绘制图片的高度)
   * img可以是放在dom中的真实图片,可以动态创建,也可以获取页面上的
   * 
  */
  /**
   * drawImage如果是九个参数,就是裁剪图片
   * drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)
   * sx,sy 表示图片中裁剪的左上角起点坐标
   * sw,sh 表示裁剪的宽高
   * dx,dy 表示绘制出来放在canvas的起点坐标
   * dw,dh 表示绘制出来的宽高
   * 
  */
  cvs.drawImage(img, 0, 0, 100, 100)
</script>

平移、缩放、旋转

平移、缩放、旋转都是对原始坐标进行操作的

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")

  // 平移、缩放、旋转都是对原始坐标进行操作的

  // 平移
  /**
   * cvs.translate(x, y)
   * x: 水平方向平移的距离
  */
  cvs.translate(100, 100)

  // 缩放
  /**
   * cvs.scale(x, y)
   * x: 水平方向缩放的倍数
   * y: 垂直方向缩放的倍数
  */
  cvs.scale(1.5, 1.5)

  /**
   * cvs.rotate(angle)
   * angle: 旋转的角度
  */
  // 旋转
  cvs.rotate(100)

  cvs.fillStyle = "red"
  cvs.fillRect(0, 0, 100, 100)
</script>

图形组合

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 图形组合
  /**
   * cvs.globalCompositeOperation = "type"
   * type: 图形组合的类型
   *   source-over: 在原来的图上绘制新图(默认值)
   *   source-in: 取两个图形的交集(新图在上,颜色就是新图的颜色)
   *   source-out: 取两个图形的差集(显示新图,非交集部分)
   *   source-atop: 显示旧图和交集部分,交集是新图的颜色
   *   destination-over: 在新图上绘制原来的图
   *   destination-in: 取两个图形的交集(旧图在上,显示的是旧图的颜色)
   *   destination-out: 显示的旧图非交集部分
   *   destination-atop: 显示新图和交集部分,交集是旧图的颜色
   *   lighter: 全部显示新旧图,交集是二者颜色的叠加
   *   xor: 显示全部非交集部分
   *   copy: 只显示新图
   * 
  */

  cvs.fillStyle = "gold"
  cvs.fillRect(100, 100, 100, 100)
  cvs.globalCompositeOperation = "xor"
  cvs.fillStyle = "skyblue"
  cvs.fillRect(120, 120, 100, 100)
  
</script>

动画

<body>
  <canvas id="draw" width="600" height="500" style="border:1px solid #ccc"></canvas>
</body>
<script>
  // 获取canvas标签
  var draw = document.getElementById("draw")
  // 设置绘制环境为平面图
  var cvs = draw.getContext("2d")
  // 图形
  var img = new Image()
  img.src = "./img/1.jpg"
  img.onload = function () {
    var width = this.width
    var height = this.height
    var i = 0
    window.setInterval(function () {
      // 清除画布
      cvs.clearRect(0, 0, draw.width, draw.height)
      cvs.drawImage(img, 0, 0, i*width, height, 0, 0, draw.width, draw.height)
      if(i == 9){
        i= 0
      }
      else{
        i++
      }
    },100)
  }

</script>