关于html5:canvas学习

55次阅读

共计 7106 个字符,预计需要花费 18 分钟才能阅读完成。

canvas 学习

canvas 长处

  1. html5 提出的新标签,可用于游戏
  2. 轻量级画布,能够间接应用 js 做解决,不需减少额定插件,性能好,不卡顿,在手机中也很晦涩

canvas 毛病

  • 绘制图形,一旦绘制胜利,便将其像素化即 canvas 无奈在次失去这个图形,将其批改
  • 解决:canvas 图形的挪动,必须依照清屏 > 更新 > 渲染的逻辑进行

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

根本应用

  1. 创立画布:
<canvas height="200" width="400" id="myCanvas">
  以后浏览器版本不反对,请降级浏览器
</canvas>

通过 heightwidth间接设置宽高(无需单位),也能够通过 css 设置,然而会失真
id 属性用来惟一定位画布

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

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

  1. 基于画布绘图:坐标原点在左上角
// 填充
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. 动画实现的根底:
ctx.clearRect(0,0,canvas.width,canvas.height) // 动画会用到的属性 - 清屏

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

  1. 设置全屏画布
 canvas.width = document.documentElement.clientWidth-30 ; // 减 30 是为了消去滚动条,能够不减
 canvas.height = document.documentElement.clientHeight -30 ;
  1. 任意方向
this.dx = parseInt(Math.random()*10)-5
this.dy = parseInt(Math.random()*10)-5

动画学习

  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;                    // 对右边间隔清零
    })
  1. 以面向对象的思维实现动画
  • 在函数原型对象上筹备好各个参数
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)

动画案例

炫彩小球案例

    const ballArr = [] ; // 创立一个存储实例的数组
    function Ball(x,y,r){
        this.x = x ; // 设置 x 轴坐标
        this.y = y ; // 设置 y 轴右边
        this.r = r ; // 设置小圆半径
        this.color = getRandom() ; // 设置小圆色彩 -- 随机 y
        this.dx = parseInt(Math.random()*10)-5 ; // 设置 x 轴行经方向
        this.dy = parseInt(Math.random()*10)-5 ; // 设置 y 轴行经方向
        ballArr.push(this) ; // 将生成的小球存到数组中
    }
    // 渲染小球 -- 创立一个图形,并对其渲染
    Ball.prototype.render = function () {ctx.beginPath()
        ctx.arc(this.x,this.y,this.r,0,Math.PI*2,false)
        ctx.fillStyle = this.color
        ctx.fill()}
    // 设置鼠标监听事件 -- 鼠标挪动时监创立小球
    canvas.addEventListener("mousemove",function (event) {new Ball(event.offsetX,event.offsetY,30)
    })
    // 小球的挪动方向及挪动时的变动 -- 减小
    Ball.prototype.updata = function () {
      this.x += this.dx;
      this.y += this.dy;
      this.r -= 0.1
        if (this.r < 0){ // 判断半径小于零时,执行删除指令,将其在数组中删除
            this.remove();}
    }
    // 当半径小于肯定水平时,执行将其删除
    Ball.prototype.remove = function () {for (let i = 0 ; i < ballArr.length ; i++){if (ballArr[i] == this){ballArr.splice(i,1)
            }
        }
    }
    // 定时器进行动画渲染和更新
    setInterval(function () {ctx.clearRect(0,0,canvas.width,canvas.height)
        for (let i = 0 ; i < ballArr.length; i++){ballArr[i].updata()
            if (ballArr[i]){ballArr[i].render()}
        }
    },10)
    // 随机生成色彩
    function getRandom() {let allTypeArr = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]
        let color = "#"
        for (let i = 0 ; i < 6 ; i++){let random = parseInt(Math.random()*allTypeArr.length)
            color += allTypeArr[random]
        }
        return color
    }

小球连线案例

    let canvas = document.getElementById("myCanvas")
    let ctx = canvas.getContext("2d")
    // 设置全屏宽度
    canvas.width = document.documentElement.clientWidth-30
    canvas.height = document.documentElement.clientHeight -30
    function Ball() {
        // 设置小球呈现点 -- 任意
        this.x = parseInt(Math.random() * canvas.width)
        this.y = parseInt(Math.random() * canvas.height)
        this.r = 10
        this.color = getRandom()
        // 设置小球行驶方向 - 任意
        this.dx = parseInt(Math.random()*10)-5
        this.dy = parseInt(Math.random()*10)-5
        // 存储生成的小球
        ballArr.push(this)
        // 记录本人在数组中的值
        this.index = ballArr.length-1;
    }
    // 小球行驶方向 -- 跟新
    Ball.prototype.update = function () {
        this.x += this.dx;
        this.y += this.dy;
        if (this.x < this.r || this.x > canvas.width-this.r){this.dx = -this.dx;}
        if (this.y < this.r || this.y > canvas.height-this.r){this.dy = -this.dy;}
    }
    // 小球渲染
    Ball.prototype.render = function () {ctx.beginPath()
        ctx.globalAlpha = 1 // 透明度
        // 画小球
        ctx.arc(this.x,this.y,this.r,0,Math.PI*2,false)
        ctx.fillStyle = this.color;
        ctx.fill()
        // 划线
        for (let i = this.index ; i < ballArr.length ; i++){if (Math.abs(ballArr[i].x-this.x)<150 && Math.abs(ballArr[i].y - this.y) < 150){ctx.strokeStyle = getRandom();
                ctx.beginPath();
                ctx.globalAlpha = 10/Math.sqrt(Math.pow(ballArr[i].x-this.x ,2)+Math.pow(ballArr[i].y -this.y,2))// 连线小球间的通明的问题
                ctx.moveTo(this.x,this.y);
                ctx.lineTo(ballArr[i].x,ballArr[i].y)
                ctx.closePath()
                ctx.stroke()}
        }
    }

    let ballArr = []
    for (let i = 0 ; i < 30 ; i++){new Ball()
    }
    setInterval(function () {ctx.clearRect(0,0,canvas.width,canvas.height)
        for (let i = 0 ; i < ballArr.length ; i++){ballArr[i].update()
            ballArr[i].render();}
    })
    function getRandom() {let allTypeArr = ["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"]
        let color = "#"
        for (let i = 0 ; i < 6 ; i++){let random = parseInt(Math.random()*allTypeArr.length)
            color += allTypeArr[random]
        }
        return color
    }

正文完
 0