Junwen's home
  • ES6

    • ES6 Decorator
    • ES6核心特性
    • Promise&Generator
  • js原理

    • 简单实现bind、apply和call
    • 如何遍历一个dom tree
    • 实现函数currying
    • 实现一个event
    • 详解js的继承
    • 详解requestAnimationFrame
    • Canvas api详解
    • DOM事件
    • EventLoop详解
    • JavaScript的内存管理
    • JavaScript的运行机制
    • Math对象
    • new操作符都做了什么
    • create基本实现原理
    • Set、Map、WeakSet和WeakMap
    • web worker原理
    • WebGL教程(MDN)
  • jsInfoSeries

    • 简介
    • JavaScript基础知识
    • 基础知识2
    • 基础知识3
    • 基础知识4
  • 技巧

    • 5个js解构有趣用途
    • 如何使用set提高代码性能
    • cordova构建项目时的问题
    • js中轻松遍历对象属性的几种方式
  • 怎么写出更好的css
  • BFC详解
  • box-shadow详解
  • CSS小技巧
  • Grid布局详解
HTML
  • IP十问
  • http笔试
  • http协议
  • 浏览器原理
  • 浏览器缓存其实就这么一回事儿
  • 浏览器兼容性问题
  • 移动端开发兼容性适配
  • 前端性能优化
  • 前端如何进行seo优化
  • webpack

    • webpack HMR
    • webpack优化基本方法
  • leetcode题解

    • 两数之和
    • 判断整数是否为回文串
    • 无重复字符的最长子串
  • Js链表
  • JavaScript排序
  • React

    • 虚拟DOM原理理解
    • React Hook
    • 组件复用指南
  • Vue

    • Vue举一反三
面试题
读书笔记
GitHub (opens new window)

Syun0216

多读书多种树
  • ES6

    • ES6 Decorator
    • ES6核心特性
    • Promise&Generator
  • js原理

    • 简单实现bind、apply和call
    • 如何遍历一个dom tree
    • 实现函数currying
    • 实现一个event
    • 详解js的继承
    • 详解requestAnimationFrame
    • Canvas api详解
    • DOM事件
    • EventLoop详解
    • JavaScript的内存管理
    • JavaScript的运行机制
    • Math对象
    • new操作符都做了什么
    • create基本实现原理
    • Set、Map、WeakSet和WeakMap
    • web worker原理
    • WebGL教程(MDN)
  • jsInfoSeries

    • 简介
    • JavaScript基础知识
    • 基础知识2
    • 基础知识3
    • 基础知识4
  • 技巧

    • 5个js解构有趣用途
    • 如何使用set提高代码性能
    • cordova构建项目时的问题
    • js中轻松遍历对象属性的几种方式
  • 怎么写出更好的css
  • BFC详解
  • box-shadow详解
  • CSS小技巧
  • Grid布局详解
HTML
  • IP十问
  • http笔试
  • http协议
  • 浏览器原理
  • 浏览器缓存其实就这么一回事儿
  • 浏览器兼容性问题
  • 移动端开发兼容性适配
  • 前端性能优化
  • 前端如何进行seo优化
  • webpack

    • webpack HMR
    • webpack优化基本方法
  • leetcode题解

    • 两数之和
    • 判断整数是否为回文串
    • 无重复字符的最长子串
  • Js链表
  • JavaScript排序
  • React

    • 虚拟DOM原理理解
    • React Hook
    • 组件复用指南
  • Vue

    • Vue举一反三
面试题
读书笔记
GitHub (opens new window)
  • 白帽子讲web安全

    • HTML5安全
    • PHP安全
    • WebServer配置安全
    • Web框架安全
    • 互联网业务安全
    • 加密算法和随机数
    • 安全的开发流程
    • 安全运营
    • 应用层拒绝服攻击
    • 文件上传漏洞
    • 注入攻击
    • 点击劫持
    • 认证与会话管理
    • 访问控制
    • 跨站点请求伪造(CSRF)
    • 跨站脚本攻击
  • 深入react技术栈

    • chapter1
  • 高性能建站
  • 冴羽系列文章链接
  • books
junwen
2020-03-27

第一章 基础知识

# Canvas元素

var canvas = document.getElementById('canvas),
    context = canvas.getContext('2d');
    context.font = '38pt Arial';
    context.fillStyle = 'cornflowerblue';
    context.fillText('Hello Canvas', canvas.width/2,canvas.height/2);
    context.strokeText('Hello Canvas', canvas.width/2, canvas.heigth/2)
1
2
3
4
5
6
  • 使用document.getElementById()方法来获取指向canvas引用
  • 在canvas对象调用getContext('2d')获取绘图环境变量(2d必须小写)
  • 使用绘图环境对象在canvas元素上进行绘制
  • fillText()与strokeText()都需要三个参数

* 在设置Canvas的宽度与高度时不能使用px后缀

# canvas的元素大小与绘图表面大小

我们可以通过canvas元素的width与height属性设置,也可以通过css来设置。canvas元素实际上有两套尺寸,一个是元素本身的大小,另一个是元素绘图表面。

  • 设置width和height:同时改变元素和绘图表面大小
  • 设置css只会改变元素本身大小

* 使用css来修改元素大小,但又没有指定canvas元素的width与height,会导致两者的大小不符,浏览器进行缩放

# canvas元素的API

属性 描述 类型 取值范围 默认值
width 绘图表面的宽度,浏览器会把元素大小和绘图表面设置成一样大小,否则则进行缩放 非负整数 任意非负整数,不能以px结尾 300
height 绘图表面的高度 非负整数 同上 300
属性 描述
getContext() 返回该canvas元素相关的绘图环境
toDataURL(type, quality) 返回一个数据地址,可以设为img的src,第一个参数是图像类型(image/png...),第二个参数必须是0-1.0之间的double值,表示图像的质量
toBlob(callback, type, args...) 创建一个表示此canvas的图像文件blob,第一个是回调函数,浏览器会以一个指向blob的引用为参数,去调用回调。之后的参数同上。

# canvas元素的绘图环境

# CanvasRenderingContext2D对象所包含的属性

属性 描述
canvas 指向绘图环境所属的canvas对象,一般用于获取宽高
fillstyle 绘图环境填充操作所使用的颜色、渐变色或者图案
font fillText()或strokeText()方法所使用的字型
globalAlpha 全局透明设置(0-1.0)
globalCompsiteOperation 浏览器将某个物体绘制在其他物体之上时,采用的绘制方式
lineCap 绘制的端点 ['butt', 'round', 'square'] default is butt
lineWidth 线段屏幕像素宽度 (非负 非无穷) default: 1.0
lineJoin 两线相交的焦点 ['bevel', 'round', 'miter'] default is miter
shadowBlur 延伸阴影效果,值越高,阴影效果延伸越远 (非负且非无穷量的double)
shadowColor 使用何种颜色来绘制阴影
shadowOffsetX 以像素为单位,指定了阴影的效果的水平方向的偏移量
shadowOffsetY 以像素为单位,指定了阴影效果的垂直方向的偏移量
strokeStyle 对路径描边时所用的绘制风格
textAlign 文本的水平对齐方式
textBaseLine 文本的垂直对齐方式

# 3d绘图环境WebGl

# canvas状态的保存与恢复

使用Canvas Api提供的两个名为save()和restore()方法

属性 描述
save() 将当前canvas的状态推送到一个保存canvas状态的堆栈顶部
restore() 将canvas状态堆栈顶部的条目弹出

codepen-HelloCanvas (opens new window)

# 性能

  • 性能分析器(Profiler)
  • 时间轴工具(Timeline)
  • jsPerf

# 绘制一个时钟

  • html
<html>
  <head>
    <title>Canvas learning</title>
  </head>
  <body>
    <canvas id="canvas2" width="300" height="300"></canvas>
  </body>
</html>
1
2
3
4
5
6
7
8
  • js
let canvas2 = document.querySelector('#canvas2'),
    context2 = canvas2.getContext('2d'),
    FONT_HEIGHT = 15,
    MARGIN = 35,
    HAND_TRUNCATION = canvas.width/25,
    HOUR_HAND_TRUNCATION = canvas.width/10,
    NUMBERAL_SPACING = 20,
    RADIUS = canvas2.width/2 - MARGIN,
    HAND_RADIUS = RADIUS + NUMBERAL_SPACING;
function drawCircle() {
  context2.beginPath();     
  context2.arc(canvas2.width/2,canvas2.height/2,RADIUS,0,Math.PI*2,true);
  context2.stroke();
}

function drawNumbers() {
  let numberals = [1,2,3,4,5,6,7,8,9,10,11,12],
      angle=0,
      numberalWidth = 0;
  numberals.forEach(v => {
    angle = Math.PI/6 * (v-3);
    numberalWidth = context2.measureText(v).width;
    
    context2.fillText(v, canvas2.width/2 + Math.cos(angle)*HAND_RADIUS - numberalWidth/2,canvas2.height/2+Math.sin(angle)*HAND_RADIUS
 + FONT_HEIGHT/3);
  })
}

function drawCenter() { //绘制圆的中心点
  context2.beginPath();
  context2.arc(canvas2.width/2,canvas2.height/2,5,0,Math.PI*2,true);
  context2.fill();
}

function drawHand(loc, isHour) {
  let angle = (Math.PI*2)*(loc/60)-Math.PI/2,
      handRadius = isHour ? RADIUS - HAND_TRUNCATION - HOUR_HAND_TRUNCATION : RADIUS- HAND_TRUNCATION;
  context2.moveTo(canvas2.width/2, canvas2.height/2);
  context2.lineTo(canvas2.width/2+Math.cos(angle)*handRadius,canvas.height/2+Math.sin(angle)*handRadius);
  context2.stroke();
}

function drawHands() {
  // context2.moveTo(canvas2.width/2, canvas2.height/2);
  // context2.lineTo(0,0)
  // context2.stroke();
  let date = new Date,
      hour = date.getHours();
  hour = hour > 12 ? hour - 12 : hour;
  drawHand(hour*5+(date.getMinutes()/60)*5,true,0.5);
  drawHand(date.getMinutes(),false,0.5);
  drawHand(date.getSeconds(),false,0.2);
}

function drawClock() {
  context2.clearRect(0,0,canvas2.width,canvas2.height);
  drawCircle();
  drawCenter();
  drawHands();
  drawNumbers();
  
}
context.font = FONT_HEIGHT + 'px Arial';
loop = setInterval(drawClock, 1000)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  • 解析

# 事件处理

# 鼠标事件

canvas.onmousedown = function(e) {
  ...
}
// 或
cavas.addEventListener('mousedown', function(e) {
  ...
})
1
2
3
4
5
6
7

获取鼠标位置,距离canvas绘图表面位置

function windowToCanvas(canvas,x, y) {
  var bbox = canvas.getBoundingClientRect();
  return {
    x: x - bbox.left * (canvas.width / bbox.width),
    y: y - bbox.top * (canvas.height / bbox.height)
  }
}
canvas.onmousemove = function(e) {
  var loc = windowToCanvas(canvas, e.clientX, e.clientY);
  ...
}

// * (canvas.width / bbox.width) => 浏览器缩放比例 绘图表面大小/元素大小
1
2
3
4
5
6
7
8
9
10
11
12
13

# 键盘事件

键盘事件:

  • keydown
  • keypress
  • keyup

键值码标准化

# 在Canvas中使用HTML元素

尽管我们可以说Canvas是html5之中最棒的功能,在绝大多数,都会将一个或者多个canvas与其他html控件结合起来使用

# 打印Canvas内容

在默认情况下,尽管每个canvas对象其实都一副位图,但他并不是html的img元素,所以用户不能对其进行某些操作。但是canvas api提供了一个toDataURL()方法,该方法返回的引用指向了某个给定canvas元素的数据地址。这个地址可以将图片保存到本地

# 离屏canvas

# 基础数学知识简介

# 三角函数

# 角度与弧度

Canvas中所有与角有关的API,都需要以弧度(radian)的方式来指定该角的值。JS的Math.sin()、Math.cos()与Math.tan()函数都采用弧度值。

1弧度 = (π/180)*度
1度 = (180/π)*弧度
1
2

# 正弦、余弦与正切函数

cos(θ) = 邻边 / 斜边;
sin(θ) = 对边 / 斜边;
tan(θ) = 对边 / 邻边;
1
2
3

# 向量运算

二维向量都含有两个值:方向及大小。
在底部那个多边型中,即将与顶部多边形发生碰撞那条边,成为边向量

# 向量的大小

利用勾股定理来计算向量的大小

# 单位向量

单位向量的长度永远是单位1,它只是用来指示方向的向量

# 向量的加减法

图1-26 向量的加法就是将向量的两个分量分别相加即可,代码如下:

var vectorSum = new Vector();
vectorSum.x = vectorOne.x + vectorTwo.x;
vectorSum.y = vectorOne.y + vectorTwo.y;
1
2
3

# 两个向量的点积

首先请注意点积不是向量,我们把这种值叫做标量(scalar,也叫纯量);

点积为负的情况。

判断两个矢量的终点是不是大致指向同一个方向,通过计算这两个向量的点积可以精确做到这一点。

# 根据计量单位来推导等式

为了实现基于时间的运动效果,我们采用每秒移动的像素数作为计量移动速度的单位。因此,为了计算动画当前帧所移动的像素数,我们需要知道两个信息: 物体的移动速度每秒是多少像素,以及当前动画的帧速率是每帧持续多少毫秒

在Github上编辑此页 (opens new window)
上次更新: 3/22/2021, 3:47:15 AM
最近更新
01
如何打造全链路项目生命周期的统一交付平台
04-10
02
如何建立前端标准化研发流程
04-10
03
如何从0到1一步步成体系地搭建CI
04-10
更多文章>
Theme by Vdoing | Copyright © 2019-2021 Syun
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式