canvas

 

canvas优点

  1. html5提出的新标签,可用于游戏
  2. 轻量级画布,可以直接使用js做处理,不需增加额外插件,性能好,不卡顿,在手机中也很流畅

canvas缺点

  • 绘制图形,一旦绘制成功,便将其像素化,即canvas无法再次得到这个图形,将其修改
  • 解决:canvas图形的移动,必须按照清屏 > 更新 > 渲染的逻辑进行

版本兼容问题:不兼容IE6、7、8,可通过在标签里边写入提示文字,来做区分,兼容的浏览器不会显示提示文字

基本使用

  1. 创建画布:

    <canvas height="200" width="400" id="canvas">
      当前浏览器版本不支持,请升级浏览器
    </canvas>
    
    • 通过heightwidth直接设置宽高(无需单位),也可以通过css设置,但是会失真
    • id属性用来唯一定位画布
  2. 获取画布:

    const canvas = document.getElementById("canvas") // 获取画布
    const ctx = canvas.getContext("2d") // 设置画布环境
    

    所有的图像绘制都基于canvas.getContext("2d")进行设置,和canvas标签无关

  3. 常用api
    • 矩形
      • rect():创建矩形
        • 四个参数:x位置、y位置、宽、高
        • 落笔与起笔
          • beginPath():落笔
          • closePath():起笔
          • 使用rect()绘制前,先调用beginPath()进行落笔,绘制完成后再调用closePath()进行起笔
        • 调用仅创建,无显示效果,需要配合对应绘制方案
          • fill():填充当前绘图
          • stroke():绘制当前路径
      • fillRect():绘制矩形(填充)
        • 四个参数:x位置、y位置、宽、高
      • strokeRect():绘制矩形(无填充)
        • 四个参数:x位置、y位置、宽、高
      • clearRect():在给定的矩形内清除指定的像素
        • 四个参数:x位置、y位置、宽、高
      • arc():创建弧/曲线(用于创建圆形或部分圆)
        • 五个参数:圆心x、圆心y、半径、开始的角度、结束的角度、逆时针还是顺时针
        • 创建弧/曲线(用于创建圆形或部分圆)
        • 需要对创建的圆进行绘制
      • arcTo() 创建两切线之间的弧/曲线
        • 五个参数:点1x、点1y、点2x、点2y、半径
    • 线
      • moveTo():把路径移动到画布中的指定点,不创建线条
        • 俩参数:x位置、y位置
      • lineTo():添加一个新点,创建从该点到最后指定点的线条
        • 俩参数:x位置、y位置
    • 绘制形式
      • fill():填充当前绘图
      • stroke():绘制已定义的路径
    • 绘制起落
      • beginPath():起始一条路径,或重置当前路径
      • closePath():创建从当前点回到起始点的路径
    • 贝塞尔曲线
      • quadraticCurveTo():创建二次贝塞尔曲线
        • 四个参数:点1x、点1y、点2x、点2y
      • bezierCurveTo():创建三次方贝塞尔曲线
          • 六个参数:点1x、点1y、点2x、点2y、点3x、点3y
    • 样式
      • fillStyle:设置或返回用于填充绘画的颜色、渐变或模式
      • strokeStyle:设置或返回用于笔触的颜色、渐变或模式
      • createLinearGradient():创建线性渐变(用在画布内容上)
        • 四个参数(针对于画布):起点x、起点y、终点x、终点y
      • createRadialGradient():创建放射状/环形/径向的渐变(用在画布内容上)
        • 六个参数:内圆圆心x、内圆圆心y、内圆半径、外圆圆心x、外圆圆心y、外圆半径
      • addColorStop():规定渐变对象中的颜色和停止位置
        • 两个参数:比例、颜色
      // 线性渐变
      let linearGradient = ctx.createLinearGradient(0,0,200,200)
      linearGradient.addColorStop(0, 'red')
      linearGradient.addColorStop(0.3, 'blue')
      linearGradient.addColorStop(1, '#222222')
      ctx.fillStyle = linearGradient
      // 径向渐变
      let radiaGradient = ctx.createRadialGradient(300,200,0,300,200,100)
      radiaGradient.addColorStop(0, 'red')
      radiaGradient.addColorStop(0.3, 'blue')
      radiaGradient.addColorStop(1, '#222222')
      ctx.fillStyle = radiaGradient
      
    主要方法 描述
    AppleScript applescript
    save() 保存当前环境的状态
    restore() 返回之前保存过的路径状态和属性
    createEvent()  
    getContext() 返回一个对象,指出访问绘图功能必要的API
    toDataURL() 返回canvas图像的URL
    主要属性 描述
    shadowColor 设置或返回用于阴影的颜色
    shadowBlur 设置或返回用于阴影的模糊级别
    shadowOffsetX 设置或返回阴影距形状的水平距离
    shadowOffsetY 设置或返回阴影距形状的垂直距离
    方法 描述
    createPattern() 在指定的方向上重复指定的元素
    线条属性 描述
    lineCap 设置或返回线条的结束端点样式
    lineJoin 设置或返回两条线相交时,所创建的拐角类型
    lineWidth 设置或返回当前的线条宽度
    miterLimit 设置或返回最大斜接长度
    路径方法 描述
    clip() 从原始画布剪切任意形状和尺寸的区域
    isPointInPath() 如果指定的点位于当前路径中,返回布尔值
    转换方法 描述
    scale() 缩放当前绘图至更大或更小
    rotate() 旋转当前绘图
    translate() 重新映射画布上的 (0,0) 位置
    transform() 替换绘图的当前转换矩阵
    setTransform() 将当前转换重置为单位矩阵。然后运行 transform()
    文本属性及方法 描述
    font 设置或返回文本内容的当前字体属性
    textAlign 设置或返回文本内容的当前对齐方式
    textBaseline 设置或返回在绘制文本时使用的当前文本基线
    fillText() 在画布上绘制”被填充的”文本
    strokeText() 在画布上绘制文本(无填充)
    measureText() 返回包含指定文本宽度的对象
    图像属性及方法 描述
    width 返回 ImageData 对象的宽度
    height 返回 ImageData 对象的高度
    data 返回一个对象,其包含指定的 ImageData 对象的图像数据
    globalAlpha 设置或返回绘图的当前 alpha 或透明值
    globalCompositeOperation 设置或返回新图像如何绘制到已有的图像上
    createImageData() 创建新的、空白的 ImageData 对象
    getImageData() 返回 ImageData 对象,该对象为画布上指定的矩形复制像素数据
    putImageData() 把图像数据(从指定的 ImageData 对象)放回画布上
    drawImage() 向画布上绘制图像、画布或视频 chrome不支持
  4. 基于画布绘图: 坐标原点在左上角

    // 填充
    ctx.fillStyle='red' // 设置颜色
    ctx.fillRect(100,200,300,400) // 绘制图像
    // 绘制
    ctx.strokeStyle = "grend"
    ctx.strokeRect(left,120,100,100)
    // 路径
    ctx.beginPath() // 创建一个路径
    ctx.moveTo(100,200)// 设置绘制初始点
    ctx.lineTo(200,300)// 绘制路径
    ctx.lineTo(180,360)
    ctx.lineTo(80,380)
    ctx.lineTo(140,330)
    ctx.closePath()// 封闭路径
    ctx.strokeStyle = "yellow"// 对已绘制路径进行渲染颜色
    ctx.stroke()            // 绘制出路径
    // 圆弧
    ctx.beginPath()
    ctx.arc(100,100,80,0,4,false)
    // 直线
    ctx.globalAlpha = 0.3 // 直线的透明的,零到一之间
    ctx.lineWidth = 3 // 设置线的粗细
    ctx.lineCap = "butt" // 设置未封闭直线两端的样式
    ctx.lineJoin = "miter" // 设置直线的折点处的样式
    ctx.setLineDash = ([1,2,3,4]) // 设置虚线的直线线段样式
    ctx.strokeRect(20,20,100,100) // 以上边的虚线构成矩形
    ctx.lineDashOffset = 2 // 向左偏移2
    // 绘制文本
    ctx.textAlign="center" // 居中对齐
    ctx.strokeText("你好吖", 0, 100); // 在指定位置绘制内容
    // 线性渐变
    let lnear = ctx.createLinearGradinent(0,0,100,100) // 渐变方向
    lnear.addColorStop(0,"red") // 设置对应比例的颜色
    ctx.fillStyle = lnear // 将对应颜色渲染出来
    // 阴影
    ctx.shadowOffsetX = 2 // 阴影的x方向偏移为2
    ctx.shadowOffsetY = 2 // 阴影的y方向偏移为2
    ctx.shadowBlur = 10 // 阴影的模糊度为10
    ctx.shadowColor = "red" // 阴影的颜色为红色
    // 图片
    let image = new Image() // 实例化图片对象
    image.src = "图片地址" // 给实例赋地址
    image.onload = function(){ // 监听图片加载事件
        ctx.drawImage(image,1,2,3,4,5,6,7,8) // 从图片1,2处开始切取宽为3,高为4的切片,放   在画布的5,6处,设置宽为7,高为8
    }
       
    
  • 填充
    • ctx.fillStyle="color":绘制图形填充颜色
    • ctx.fillRect(x轴,y轴,width,height):绘制填充矩形
  • 绘制
    • ctx.strokeStyle = "color":绘制边框的颜色
    • ctx.strokeRect(x轴,y轴,width,height):绘制空心矩形
  • 路径
    • ctx.beginPath():创建路径表示将绘制不规则图形
    • ctx.moveTo(x,y):创建绘制路径的起点位置
    • ctx.lineTo(x,y):创建第二个点及所有点的坐标,按照顺序依次连接
    • ctx.closePath():绘制完路径后,用最后一个点的位置连接起点,形成封闭图形
    • ctx.strokeStyle = "yellow":对已绘制路径进行渲染颜色
    • ctx.fillStyle="color":或者对已绘制路径进行填充渲染颜色
    • ctx.stroke(): 实例化路径
    • ctx.fill(): 实例化填充路径
  • 圆弧
    • ctx.arc(x,y,redius,starAngle,endAngle,anticlockwise):绘制圆弧 - 填充
    • x、y:表示圆心位置
    • redius:表示半径
    • startAngle:表示开始开始位置(单位为3.14即Π,一个弧度),
    • endAngle:表示结束位置(单位也是Π)
    • anticlockwise:表示方向(false为顺时针,true表示逆时针)
  • 直线
    • ctx.globalAlpha = 0.3:绘制直线的透明的,范围在0-1之间
    • ctx.lineWidth = number:设置直线的粗细,无单位,默认为一
    • ctx.lineCap = "butt":设置线暴露端的样式,可选值(“butt”,”round”,”square”), ‘square’两端会延长宽度的一半
    • ctx.lineJoin = "miter":设置两线交接处的样式,可选值(“rund”,”bevel”,”miter”)
    • ctx.setLineDash = ([数组]):接收一个数字数组,数组里边的数值及顺序代表虚线的长度比, 数组里边至少两个参数
    • ctx.strokeRect(x,y,width,height):构型,使用上边虚线线段
    • ctx.lineDashOffset = 2:设置虚线起始偏移量
  • 绘制文本
    • ctx.textAlign="center":设置文本在绘制范围内对齐方式
    • ctx.strokeText("文本内容", x, y);:x、y:表示绘制的起点位置
  • 线性渐变
    • let lnear = ctx.createLinearGradinent(x1,y1,x2,y2):x1、y1:表示绘制起点;x2、 y2:表示绘制终点
    • lnear.addColorStop(num,"color"):num:是0-1之间的值,多个,按比例划分各段颜色; color:对应端的颜色
    • ctx.fillStyle = lnear :渲染对应颜色
  • 径向渐变
    • ctx.createRadialGradient(x1,y1,r1,x2,y2,r2):x1、y1、r1:开始圆形的参数,x2、y2、 r2:结束圆形的参数
  • 阴影
    • ctx.shadowOffsetX = num :阴影方向 – x轴
    • ctx.shadowOffsetY = num :阴影方向 – y轴
    • ctx.shadowBlur = num :阴影模糊度
    • ctx.shadowColor = "color" :阴影颜色
  • 图片
    • let image = new Image():创建图片
    • image.src = "图片地址":引入图片地址
    • image.onload = function(){}:图片加载完成后立即执行
    • ctx.drawImage(image,e,f,j,h,a,b,c,d):写于onload事件里边,可以写两个参数,四个参 数,八个参数
      • a、b:表示图片的初始位置,即x轴、y轴的位置
      • c、d:表示图片的宽高
      • e、f:表示切取图片的起点
      • j、h:表示切片的宽高
      • 当只有两个或四个参数时,取a、b、c、d

动画学习

  1. 简单的动画实现

        let canvas = document.getElementById("myCanvas")
        let ctx = canvas.getContext("2d")
        ctx.fillStyle='red'
        let left = 100                                    // 初始左边距离位置
        setInterval(()=>{
            ctx.clearRect(0,0,canvas.width,canvas.height) // 清屏
            left++;                                       // 距离左边的距离 
            ctx.fillRect(left,100,100,100)                // 重复绘制
            left>600?left = -100:left;                    // 对左边距离清零
        })
    
  2. 以面向对象的思想完成动画

    • 在函数原型对象上准备好各个参数

       function rects(x,y,w,h,color) {// 初始状态
             this.x = x;
             this.y = y;
             this.w = w;
             this.h = h;
             this.color = color;
           }
           // 在原型上设置方法
           // 更新
           rects.prototype.updata = function () {
             this.x++
           }
           // 渲染
           rects.prototype.render = function () {
               ctx.fillStyle = this.color;
               ctx.fillRect(this.x,this.y,this.w,this.h);
           }
      
    • 实例化对象

       let r1 = new rects(100,30,50,50,"red")
      
    • 动画过程

       setInterval(()=>{
               // 清屏
               ctx.clearRect(0,0,canvas.width,canvas.height)
               r1.updata();
               r1.render()
           },10)
      
    • 清屏

       ctx.clearRect(0,0,canvas.width,canvas.height) // 动画会用到的属性 - 清屏
      

      ctx.clearRect(x,y,width,height):x、y代表开始清除的位置,width、height代表清除的宽度 和高度

    • 设置全屏画布

         canvas.width = document.documentElement.clientWidth-30 ; // 减30是为了消去滚动条,可以不减
         canvas.height = document.documentElement.clientHeight -30 ;
      
    • 任意方向

       this.dx = parseInt(Math.random()*10)-5
       this.dy = parseInt(Math.random()*10)-5