Skip to content

Latest commit

 

History

History
612 lines (441 loc) · 23.3 KB

canvas 笔记.md

File metadata and controls

612 lines (441 loc) · 23.3 KB

canvas 笔记

发表于 2021-02-12|更新于 2021-08-24|前端

字数总计:2.6k|阅读时长:10 分钟 | 阅读量:920

canvas 笔记

canvas 教程

一。概述

长久以来,web 上的动画都是 Flash。比如动画广告、游戏等等,基本上都是 F1ash 实现的。Flash 是有缺点的,比如需要安装 Adobe Flash Player, 漏洞多,重量比较大。卡顿和不流畅等等

1.1 简介

HTML5 提出了一个新的 canvas 标签,彻底颠覆了 Flash 的主导地位。无论是广告、游戏都可以使用 canvas 实现了,Canvas 是一个轻量级的画布,我们使用 Canvas 进行 JavaScript 的编程,不需要增加额外的插件,性能也很好,不卡顿,在手机中也很流畅

二。基本使用

HTML
<canvas width="400" height="500" id="mycanvas">
       当前浏览器版本不支持,请升级浏览器
</canvas>

canvas 的标签属性只有两个,width 和 height.。表示的是 canvas 画布的宽度和高度。注意 canvas 的 width 和 height 不要用 css 的样式来设置,如果使用 css 的样式来设置,画布会失真,会变形 标签对儿里面的文字是用来提示低版本浏览器 (IE6/7/8)

方法 / 属性 描述
getContext() 得到画布上下文,上下文有两个,2d 的上下文和 3d 的上下文
fillStyle 设置颜色
fillRect(x,y,width,height) 方法绘制 “已填色” 的矩形。默认的填充颜色是黑色。

三.canvas 的编程思想

3.1 像素化

我们使用 canvas 绘制了一个图形,一旦绘制成功了,canvas 就像素化了他们。 canvas 没有能力,从画布上再次得到这个图形,也就是说我们没有能力去修改已经在画布上的内容。这个就是 canvas 比较轻量的原因,Flash 重的原因之一就有它可以通过对应的 api 得到已经上 “画布” 的内容然后再次绘制,如果我们想要让这个 canvas 图形移动,必须按照清屏 - 更新 - 渲染的逻辑进行编程,总之就是重新再画一次

3.2 动画思想

清屏 - 更新 - 渲染,这个思想就可以为 canvas 的动画思想

JAVASCRIPT
var canvas=document.getElementById("mycanvas");
var ctx=canvas.getContext("2d")
ctx.fillStyle="blue"
// 设置信号量
var left=10;
setInterval(()=>{
    //清除画布
    ctx.clearRect(0,0,700,600)
    // 更新信号量
    left++;
    ctx.fillRect(left,left,100,100)
    if(left==700){
        left=10
    }
},4)

实际上,动画的生存就是相关静态画面连续插放了,这个就是动画的过程。我们把每一次绘制的静态画面叫做 " 一帧 ",时间的间隔 (定时器的间隔) 就表示的是帧的间隔

3.3 面向对象实现 canvas 动画

因为 canvas 不能得到已经上屏的对象,所以我们要维持对象的状态。在 canvas 动画中,我们都使用面向对象来进行编程,因为我们可以使用面向对象的方式来维持 canvas 需要的属性和状态

JAVASCRIPT
// 获取画布
var can = document.getElementById("can")
var ctx = can.getContext("2d");
// 绘制方法
function Rect(x, y, w, h, color) {
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
    this.color = color
}
// 更新方法
Rect.prototype.update = function () {
    this.x++;
}
// 渲染
Rect.prototype.render = function () {
    // 设置颜色
    ctx.fillStyle = this.color;
    // 渲染
    ctx.fillRect(this.x, this.y, this.w, this.h);
}
// 实例化
var r1 = new Rect(100, 100, 50, 50, "#91d5ff")
// 动画过程
setInterval(() => {
    //清屏
    ctx.clearRect(0, 0, can.width, can.height)
    //更新
    r1.update()
    // 渲染
    r1.render()
}, 5)

动画过程在主定时器里面,每一帧都会调动实例的更新和渲染方法

四. canvas 绘制功能

方法 / 属性 描述
fillStyle 设置填充颜色
fillRect(x,y,width,height) 方法绘制 “已填色” 的矩形。默认的填充颜色是黑色。
strokeStyle 设置边框颜色
strokeRect(x,y,width,height) 方法绘制矩形边框。默认的填充颜色是黑色。
clearRect(x,y,width,height) 清除画布内容
globalAlpha 设置透明度 0-1

4.1 绘制路径

JAVASCRIPT
// 创建路径
ctx.beginPath()
// 移动绘制点
ctx.moveTo(100,100)
// 描述行进路径
ctx.lineTo(200,300);
ctx.lineTo(300,230);
ctx.lineTo(440,290);
ctx.lineTo(380,50);
// 封闭路径
ctx.closePath()
// 设置颜色
ctx.strokeStyle="#91d5ff"
// 绘制不规则图形
ctx.stroke()
// 填充不规则图形
ctx.fill()

绘制路径图

4.2 绘制圆弧

JAVASCRIPT
arc(x, y, radius, startAngle, endAngle, anticlockwise)
  • x,y 为绘制圆弧所在圆上的圆心坐标。
  • radius 为半径。
  • startAngle 以及 endAngle 参数用弧度定义了开始以及结束的弧度。这些都是以 x 轴为基准。
  • 参数 anticlockwise 为一个布尔值。为 true 时,是逆时针方向,否则顺时针方向。

注意:arc() 函数中表示角的单位是弧度,不是角度。角度与弧度的 js 表达式:

弧度 =(Math.PI/180)* 角度。

JAVASCRIPT
// 创建路径
ctx.beginPath();
// 圆周长 2π 2*3.14≈7 2*Math.PI
ctx.arc(200,200,100,0,2*Math.PI,false)
//  ctx.arc(200,200,100,0,0.3,false)
// 绘制
ctx.stroke()

canvas 实现鼠标跟随炫彩小球

canvas 实现炫彩小球弹弹

4.3 线型

我们可以利用 lineWidth 设置线的粗细,属性值必须是数字,默认是 1.0。没有单位

JAVASCRIPT
ctx.beginPath();
ctx.moveTo(100,150)
ctx.lineTo(200,200)
ctx.lineTo(300,50)
ctx.lineWidth=10
ctx.stroke()

线型教程

4.4 文本

JAVASCRIPT
// 设置文字
ctx.font="30px 宋体"
// 设置文字对齐方式
ctx.textAlign="start"
ctx.fillText("Hello Canvas",100,100)

4.5 渐变

  • 线型渐变
JAVASCRIPT
// 渐变
var linear=ctx.createLinearGradient(0, 0, 200, 200);
linear.addColorStop(0,"red");
linear.addColorStop(0.5,"#91d5ff");
linear.addColorStop(0.8,"#ffec3d");
linear.addColorStop(1,"blue")
ctx.fillStyle=linear
ctx.fillRect(10,10,200,100)

4.6 阴影

JAVASCRIPT
// 阴影
ctx.shadowOffsetX=10 // 左右偏移
ctx.shadowOffsetY=10 // 上下偏移
ctx.shadowBlur=3; // 模糊度
ctx.shadowColor="red"; // 颜色
// 设置文字
ctx.font="30px 宋体"
ctx.fillText("Hello Canvas",100,100)

五。图片使用

JAVASCRIPT
 // 创建image元素
var img=new Image();
// 设置src地址
img.src="https://tva3.sinaimg.cn/large/006djwNZgy1gmqxcekdm8j31hc0u0dln.jpg"
// 必须在onload 之后绘制图片
img.onload=function(){
    ctx.drawImage(img,100,100,200,100)
}
  • 4 个参数
JAVASCRIPT
drawImage(img,x,y,width,height)

kfdjhgfkd9856745

JAVASCRIPT
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
  1. 前 4 个参数指的是你在图片中设置切片的宽度和高度,以及切片位置
  2. 后 4 个参数指的是切片在画布上的位置和切片的宽度和高度

image-20210213111523157

六。资源管理器

JAVASCRIPT
 // 游戏类
function Game() {
    this.dom = document.querySelector("canvas");
    this.ctx = this.dom.getContext("2d");

    // 添加属性,保存需要的图片地址
    this.R = {
        "01": "https://tvax3.sinaimg.cn/large/006djwNZgy1gkyvxt1exaj33y8280b2c.jpg",
        "02": "https://tva1.sinaimg.cn/large/006djwNZgy1gkyzq80yobj31hc0u0n4r.jpg",
        "03": "https://tva3.sinaimg.cn/large/006djwNZgy1gmqxcekdm8j31hc0u0dln.jpg",
        "04": "https://tva4.sinaimg.cn/large/006djwNZgy1gmqxee8qo6j31hc0u0qcr.jpg"
    }
    // 获取资源图片的总数
    var allAmount = Object.keys(this.R).length
    // 计数器
    var count = 0
    // 遍历对象获取每一个地址
    for (k in this.R) {
        var src = this.R[k]
        // 创建图片
        this.R[k] = new Image()
        // 设置图片地址
        this.R[k].src = src;
        // 判断图片是否加载完成
        var self = this
        this.R[k].onload = function () {
            // 计数
            count++;
            // 清屏
            self.ctx.clearRect(0, 0, 600, 500)
            self.ctx.font = "16px Arial"
            // 设置资源加载文案
            self.ctx.fillText("图片已加载:" + count + "/" + allAmount, 10, 50)
        }
    }

}
console.log(new Game());

七。变形

7.1 概述

save()

保存画布 (canvas) 的所有状态

restore()

save 和 restore 方法是用来保存和恢复 canvas 状态的,都没有参数。Canvas 的状态就是当前画面应用的所有样式和变形的一个快照。

Canvas 状态存储在栈中,每当 save() 方法被调用后,当前的状态就被推送到栈中保存。一个绘画状态包括:

你可以调用任意多次 save 方法。每一次调用 restore 方法,上一个保存的状态就从栈中弹出,所有设定都恢复。

7.2 translate

  • translate 和 CSS3 的 translate 属性一样也是发挥着空间平移作用
JAVASCRIPT
// 保存
ctx.save();
ctx.translate(50,50)
ctx.fillRect(0,0,120,120)
// 恢复
ctx.restore()
// 渲染位置是没有存档之前的位置
ctx.fillRect(0,200,120,120)

image-20210213124807029

  • 变形实际上都是将整个画布进行的变形,所以如果一旦变形操作多了,画布将变得不可控
  • 如果使用到变形,一定记住下面的规律:变形之前要先备份,将世界和平的状态进行备份,然后再变形,变形完毕后一定要恢复到世界和平的样子,不要影响下一次的操作

7.3 rotate

JAVASCRIPT
// 保存
ctx.save();
ctx.translate(200,100)
ctx.rotate(1)
ctx.fillRect(0,0,120,120)
// 恢复
ctx.restore()
// 渲染位置是没有存档之前的位置
ctx.fillRect(0,200,120,120)
rotate(angle)

这个方法只接受一个参数:旋转的角度 (angle),它是顺时针方向的,以弧度为单位的值。

旋转的中心点始终是 canvas 的原点,如果要改变它,我们需要用到 translate 方法。

7.4 scale

JAVASCRIPT
ctx.save();
ctx.translate(200,100)
ctx.scale(0.6,0.6)
ctx.fillRect(0,0,120,120)
// 恢复
ctx.restore()
// 渲染位置是没有存档之前的位置
ctx.fillRect(0,200,120,120)

scale 方法可以缩放画布的水平和垂直的单位。两个参数都是实数,可以为负数,x 为水平缩放因子,y 为垂直缩放因子,如果比 1 小,会缩小图形, 如果比 1 大会放大图形。默认值为 1, 为实际大小。

最后一个方法允许对变形矩阵直接修改。

JAVASCRIPT
transform(a, b, c, d, e, f)
// 如果任意一个参数是`Infinity`,变形矩阵也必须被标记为无限大,否则会抛出异常。

这个函数的参数各自代表如下:

  • a(m11) 水平方向的缩放
  • b(m12) 竖直方向的倾斜偏移
  • c(m21) 水平方向的倾斜偏移
  • d(m22) 竖直方向的缩放
  • e(dx) 水平方向的移动
  • f(dy) 竖直方向的移动

八。合成

  • 合成其实就是我们常见的蒙板状态,本质就是如何进行压盖,如何进行显示
JAVASCRIPT
ctx.fillStyle="#91d5ff"
ctx.fillRect(100,100,100,100)
ctx.fillStyle="#ffc069"
ctx.beginPath()
ctx.arc(200,200,60,0,7,false)
ctx.fill()

image-20210213190925696

JAVASCRIPT
ctx.globalCompositeOperation="destination-over"

image-20210213191252885

文章作者: 橘子味雪糕

文章链接: https://liuxianl.com/2021/02/12/%E5%89%8D%E7%AB%AF/canvas/

版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 橘子味雪糕

前端动画

cover of previous post上一篇Vue 3 学习笔记

cover of next post下一篇SassScript

相关推荐

cover 2021-02-10CSS 动画

cover 2020-12-21ES6:promise、async 的理解

cover 2021-08-0549 个常用 JavaScript 方法封装

cover 2021-07-09正则

cover 2021-02-11SassScript


评论

提交

2 评论

img

Anonymous Chrome 91.0.4472.124 Windows 10.0

2021-07-04回复

哇,这做的也太漂亮了吧 thumb

img

前端小菜鸡 Chrome 88.0.4324.190 Windows 10.0

2021-03-07回复

膜拜大佬 想要微信联系方式

img

橘子味雪糕 Edge 89.0.774.54 Windows 10.0

2021-03-17回复

@前端小菜鸡 , 不好意思啊 才看到 在关于页面有二维码

Powered By Valine v1.4.14

avatar

橘子味雪糕

竟然选择了远方,便只顾风雨兼程

文章17

标签14

分类8

Follow Me

公告

更换域名 https://liuxianl.com/

2021-08-30 MON☀️ 29 *C💧 84%

22:13:18

36.18.174.210HangzhouPM

那年今日

A.D.2010印度尼西亚锡纳朋火山沉睡 400 年后再次爆发

A.D.1619日本大名岛津义弘逝世

A.D.1785民族英雄林则徐出生

A.D.1797英国作家玛丽・雪莱出生

A.D.1871英国物理学家卢瑟福出生

A.D.1929中国现代农民运动领袖彭湃逝世

A.D.1930“股神” 沃伦・巴菲特出生

A.D.1935法国作家巴比塞逝世

A.D.1940电子的发现者汤姆生在英格兰剑桥逝世

A.D.1956毛泽东发表 “球籍论”

A.D.1958中国第一座原子反应堆回旋加速器开始运转

A.D.1972世界足球先生帕维尔・内德维德出生

A.D.1982苏联发射核动力海洋监视卫星

A.D.1990中国史学家钱穆逝世

A.D.1998中国兴建首条跨海铁路

A.D.2010印度尼西亚锡纳朋火山沉睡 400 年后再次爆发

A.D.1619日本大名岛津义弘逝世

目录

  1. \1. canvas 笔记
    1. 1.1. 一。概述
      1. 1.1.1. 1.1 简介
    2. 1.2. 二。基本使用
    3. 1.3. 三.canvas 的编程思想
      1. 1.3.1. 3.1 像素化
      2. 1.3.2. 3.2 动画思想
      3. 1.3.3. 3.3 面向对象实现 canvas 动画
    4. 1.4. 四. canvas 绘制功能
      1. 1.4.1. 4.1 绘制路径
      2. 1.4.2. 4.2 绘制圆弧
      3. 1.4.3. 4.3 线型
      4. 1.4.4. 4.4 文本
      5. 1.4.5. 4.5 渐变
      6. 1.4.6. 4.6 阴影
    5. 1.5. 五。图片使用
    6. 1.6. 六。资源管理器
    7. 1.7. 七。变形
      1. 1.7.1. 7.1 概述
      2. 1.7.2. 7.2 translate
      3. 1.7.3. 7.3 rotate
      4. 1.7.4. 7.4 scale
      5. 1.7.5. 7.5 Transforms
    8. 1.8. 八。合成

最新文章

49个常用JavaScript方法封装

49 个常用 JavaScript 方法封装2021-08-05

正则

正则2021-07-09

Vue 3 学习笔记

Vue 3 学习笔记2021-05-05

canvas 笔记

canvas 笔记2021-02-12

SassScript

SassScript2021-02-11

©2019 - 2021 By 橘子味雪糕

A world that knows nothing will surprise you if you go on img湘 ICP 备 20001832 号 - 3 本网站由img 提供 CDN 加速服务