1、新建画布
canvas 首先是空白的,咱们首先设置 canvas 的宽高,并找到 渲染上下文
<body>
<!-- 新建 canvas 元素 -->
<canvas id="canvas"></canvas>
</body>
window.onload = () => {
// 获取 canvasDom
const canvas = document.getElementById("canvas");
// 手动设置宽高
canvas.width = 800;
canvas.height = 800;
// 获取上下文
const ctx = canvas.getContext("2d");
};
2、绘制边框
此时页面曾经能够看到画布了,咱们能够更显著的一些绘制一个边框
window.onload = () => {
.....
// 获取 canvas 上下文
const ctx = canvas.getContext("2d");
// 绘制边框
renderBorder(ctx);
};
function renderBorder(ctx) {
// 首先获取画布的宽高
const width = ctx.canvas.width;
const height = ctx.canvas.height;
ctx.beginPath(); // 开始一个新的门路
ctx.moveTo(0, 0); // 将门路的起始点挪动到左上角
ctx.lineTo(width, 0); // 应用直线连贯到右上角(并不绘制)ctx.lineTo(width, height); // ... 右下角
ctx.lineTo(0, height); // ... 左下角
ctx.closePath(); // 完结一个新的门路
ctx.stroke(); // 绘制以后已知门路}
3、绘制球
此时咱们曾经能够看到边框了,首先须要新建一个“球”对象,球对象有如下一些属性, 再实现如何绘制这个“球”对象,这里波及到 canvas 绘制圆弧门路的办法,比拟非凡的这里是弧度
void ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);
x:圆弧中心点 x 轴坐标
y: 圆弧中心点 y 轴坐标
radius:半径
startAngle:圆弧起始点
endAngle:圆弧完结点
anticlockwis(可选):Boolean 类型,如果为 true,则逆时针方向绘制,反之,顺时针方向绘制
window.onload = () => {
.....
// 绘制球
let ball = {
x: 0, // 以后 x 轴坐标
y: 0, // 以后 y 轴坐标
radius: 10, // 半径
g: 0.1, // 重力加速度
vx: 8, // x 轴挪动速度
vy: 4, // y 轴挪动速度
color: "blue", // 色彩
};
renderBall(ctx, ball);
};
// 绘制一个球
function renderBall(ctx, ball) {
const x = ball.x + ball.radius; // 圆弧核心(圆心)的 x 轴坐标。const y = ball.y + ball.radius; // 圆弧核心(圆心)的 y 轴坐标。const radius = ball.radius; // 半径
const startAngle = 0; // 圆弧的起始点
const endAngle = 2 * Math.PI; // 圆弧的完结点
ctx.beginPath(); // 开始一个新的门路
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.closePath(); // 完结一个新的门路
ctx.fillStyle = ball.color; // 色彩
ctx.fill(); // 填充}
4、让球动起来
这是咱们曾经绘制了一个球,接下来依据球在 x 轴与 y 轴上的速度挪动起来,并给 y 轴加上重力加速度,这里须要留神的是每次绘制都须要从新革除一下画布,canvas 动画实质就是每次都革除一遍画布从新绘画
window.onload = () => {
// .....
let ball = {
x: 0, // 以后 x 轴坐标
y: 0, // 以后 y 轴坐标
radius: 10, // 半径
g: 0.1, // 重力加速度
vx: 8, // x 轴挪动速度
vy: 4, // y 轴挪动速度
color: "blue", // 色彩
};
setInterval(() => {
// 先将之前绘制的擦除
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// 绘制边框
renderBorder(ctx);
// 绘制球
renderBall(ctx, ball);
ball = updateBall(ball);
}, 20);
}
// 更新 ball
function updateBall(ball) {
ball.x += ball.vx;
ball.y += ball.vy;
ball.vy += ball.g;
return ball;
}
5、优化
当初小球曾经能够动起来了, 再优化一下 updateBall 函数,实在一点,例如当小球调到边框的时候能够反弹回来,且每次反弹都会让加速度变慢
function updateBall(ctx, ball) {
const width = ctx.canvas.width;
const height = ctx.canvas.height;
ball.x += ball.vx;
ball.y += ball.vy;
ball.vy += ball.g;
if (ball.y + ball.radius >= height) {
ball.y = height - ball.radius;
ball.vy = -ball.vy * 0.5;
}
if (ball.y + ball.radius <= 0) {
ball.y = 0 - ball.radius;
ball.vy = -ball.vy * 0.5;
}
if (ball.x + ball.radius >= width) {
ball.x = width - ball.radius;
ball.vx = -ball.vx * 0.5;
}
if (ball.x + ball.radius <= 0) {
ball.x = 0 - ball.radius;
ball.vx = -ball.vx * 0.5;
}
return ball;
}
整体代码
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Canvas 小球 </title>
</head>
<body>
<!-- 新建 canvas 元素 -->
<canvas id="canvas"></canvas>
</body>
<script>
window.onload = () => {
// 获取 canvasDom
const canvas = document.getElementById("canvas");
// 手动设置宽高
canvas.width = 800;
canvas.height = 800;
// 获取 canvas 上下文
const ctx = canvas.getContext("2d");
let ball = {
x: 0, // 以后 x 轴坐标
y: 0, // 以后 y 轴坐标
radius: 10, // 半径
g: 0.1, // 重力加速度
vx: 8, // x 轴挪动速度
vy: 4, // y 轴挪动速度
color: "blue", // 色彩
};
setInterval(() => {
// 先将之前绘制的擦除
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
// 绘制边框
renderBorder(ctx);
// 绘制球
renderBall(ctx, ball);
ball = updateBall(ctx, ball);
}, 20);
};
// 绘制边框
function renderBorder(ctx) {
// 首先获取画布的宽高
const width = ctx.canvas.width;
const height = ctx.canvas.height;
ctx.beginPath(); // 开始一个新的门路
ctx.moveTo(0, 0); // 将门路的起始点挪动到左上角
ctx.lineTo(width, 0); // 应用直线连贯到右上角(并不绘制)ctx.lineTo(width, height); // ... 右下角
ctx.lineTo(0, height); // ... 左下角
ctx.closePath(); // 完结一个新的门路
ctx.stroke(); // 绘制以后已知门路}
// 绘制一个球
function renderBall(ctx, ball) {
const x = ball.x + ball.radius; // 圆弧核心(圆心)的 x 轴坐标。const y = ball.y + ball.radius; // 圆弧核心(圆心)的 y 轴坐标。const radius = ball.radius; // 半径
const startAngle = 0; // 圆弧的起始点
const endAngle = 2 * Math.PI; // 圆弧的完结点
ctx.beginPath(); // 开始一个新的门路
ctx.arc(x, y, radius, startAngle, endAngle);
ctx.closePath(); // 完结一个新的门路
ctx.fillStyle = ball.color; // 色彩
ctx.fill(); // 填充}
// 更新 ball
function updateBall(ctx, ball) {
const width = ctx.canvas.width;
const height = ctx.canvas.height;
ball.x += ball.vx;
ball.y += ball.vy;
ball.vy += ball.g;
if (ball.y + ball.radius >= height) {
ball.y = height - ball.radius;
ball.vy = -ball.vy * 0.5;
}
if (ball.y + ball.radius <= 0) {
ball.y = 0 - ball.radius;
ball.vy = -ball.vy * 0.5;
}
if (ball.x + ball.radius >= width) {
ball.x = width - ball.radius;
ball.vx = -ball.vx * 0.5;
}
if (ball.x + ball.radius <= 0) {
ball.x = 0 - ball.radius;
ball.vx = -ball.vx * 0.5;
}
return ball;
}
</script>
</html>
参考文档
[百度百科:弧度](
https://baike.baidu.com/item/…
[MDN:canvas](
https://developer.mozilla.org…
[慕课网:liuyubobobo 老师的 canvas 教程](
https://www.imooc.com/learn/133)