H5新增 —— canvas 画布
1、canvas的基础 画基本图形
canvas 有两个发展方向:
- 数据可视化
- 游戏开发
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#canvas {
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
const canvas = document.getElementById("canvas")
const ctx = canvas.getContext("2d");
//画一个填充矩形
ctx.fillRect(100, 100, 200, 100);
// ------------------------------------
//画一个描边矩形
ctx.strokeRect(0, 0, 100, 100)
// ----------------画线段----------------
//开始绘画路径
ctx.beginPath();
//把画笔移动到指定的位置
ctx.moveTo(100, 100)
//画笔画线的指定位置。可以是多个
ctx.lineTo(200, 200)
ctx.lineTo(180, 10)
ctx.lineTo(10, 150)
ctx.lineTo(130, 400)
//设置描边的颜色
ctx.strokeStyle = "green"
//闭合路径实现多边形
ctx.closePath()
//描边的宽度
ctx.lineWidth = 10
//画线
ctx.stroke()
//填充颜色
ctx.fillStyle = "red"
//填充
ctx.fill()
// -----------------------画圆-------------------------
// ctx.arc(x, y, r, startAngle, endAngle, boolean)
// x , y: 圆心坐标 r 圆的半径 startAngle, endAngle 圆的起点和终点(单位数弧度) boolean : 顺时针false和逆时针true
// 弧度 和角度的换算 2 * Math.PI = 360° Math.PI / 180 = 1°
ctx.arc(100, 100, 50, 0, 2 * Math.PI, false)
ctx.strokeStyle = "red"
ctx.fillStyle = "green"
ctx.stroke()
ctx.fill()
</script>
</body>
</html>
2、用cavans实现动画基本效果
实现原理:
canvas 实现动画的原理:
1. 需要通过 计时器 实现动画, 画一次删一次
2. 通过计时器实现,画一次覆盖一层遮罩层
canvas 清空画布: ctx.clearRect(x, y, width, height)
计时器时间 16.7ms 原理:
电脑的刷新频率: 1秒钟 刷新 60次 1000ms = 60次 1000ms / 60 = 1次
<style>
//设置canvas的基本样式,方便查看画布的位置
#canvas{
border:1px solid red;
}
</style>
<canvas id="canvas" width="500" height="500"></canvas>
动画实现 1 画一次删除一次
const ctx = document.getElementById('canvas').getContext('2d')
ctx.beginPath();
ctx.fillStyle = 'red'
ctx.arc(10, 250, 20, 0, Math.PI * 2)
ctx.fill()
// ctx.clearRect(0, 0, 500, 500)
let x = 10;
let timer = setInterval(() => {
ctx.clearRect(0, 0, 500, 500)
ctx.beginPath();
ctx.fillStyle = 'orange'
ctx.arc(x, 250, 20, 0, Math.PI * 2)
ctx.fill()
x += 10;
}, 16.7)
动画原理实现2 通过覆盖遮罩层实现
let time = setInterval(() => {
ctx.beginPath();
ctx.fillStyle = 'rgba(255, 255, 255, 0.2)';
ctx.fillRect(0, 0, 500, 500)
ctx.beginPath();
ctx.fillStyle = 'green';
ctx.arc(x, 250, 10, 0, Math.PI *2)
ctx.fill()
x += 10;
}, 16.7)
3、弹球运动
<style>
#canvas{
border:1px solid red;
}
</style>
<canvas id="canvas" width="600" height="600"></canvas>
js部分
<script>
const ctx = document.getElementById('canvas').getContext('2d')
ctx.arc(200, 100, 10, 0 , Math.PI * 2);
ctx.fill()
// 随机数
function random(a, b){
return Math.floor( Math.random() * (b - a + 1) + a)
}
// 让小球运动起来
let x = 200, y = 100;
// 圆心坐标的改变计量
let speedX = random(-5, 5);
let speedY = random(-5, 5);
let time = setInterval( () => {
ctx.clearRect(0, 0, 600, 600);
ctx.beginPath();
ctx.arc(x, y, 10, 0 , Math.PI * 2);
ctx.fill()
// 改变圆心坐标
x = x + speedX;
y = y + speedY;
// 判断小球是否碰壁
if(x <= 10){
speedX = -speedX
}
if(x >= 590){
speedX = -speedX
}
if(y <= 10){
speedY = -speedY
}
if(y >= 590){
speedY = -speedY
}
}, 16.7)
</script>
canvas实现百分比动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
canvas {
border: 1px solid red;
}
</style>
</head>
<body>
<canvas id="canvas" width="500" height="500"></canvas>
<script>
const ctx = document.getElementById('canvas').getContext('2d')
// 画一个圆环
function circle() {
ctx.beginPath()
ctx.arc(250, 250, 100, 0, Math.PI * 2);
ctx.strokeStyle = '#000'
ctx.lineWidth = '50'
ctx.stroke()
}
// 显示百分比 弧线
function precent(n) {
console.log(n);
ctx.beginPath();
// ctx.arc(250, 250, 100, Math.PI / 2, Math.PI);
// 起点和终点的弧度值 圆 :弧度 2 * Math.PI , 均分为100分 n 代表具体的份数
ctx.arc(250, 250, 100, Math.PI / 2, Math.PI / 2 + Math.PI * 2 / 100 * n );
ctx.lineWidth = '50'
ctx.strokeStyle = 'red'
ctx.stroke()
}
// 绘制文字 文字分两种:描边的文字 strokeText(), 实体的文字fillText()
// ctx.beginPath()
function text(n) {
ctx.beginPath()
ctx.font = '50px 微软雅黑'
// ctx.lineWidth = '2'
// ctx.strokeText('25%', 100, 100)
ctx.fillStyle = 'red'
ctx.fillText(`${n.toFixed(2)}%`, 100, 100)
}
let speed = 0.1;
let rad = Math.PI * 2 / 100
let time = setInterval(() => {
ctx.clearRect(0, 0, 500, 500)
// ctx.beginPath()
circle();
precent(speed)
text(speed)
// 满足条件 清除计时器
if(speed >= 90){
clearInterval(time)
}
speed += 0.1
}, 16.7)
</script>
</body>
</html>