HTML5 Canvas 真香!刀剑神域 HP Bar 第二弹

从此踏上了一条 Canvas 的不归路,正是这样折腾,选项卡再一次刷炸浏览器,Chrome 又一次挤爆内存…… 这次,用 Canvas 可能是最大程度地复刻了 TV 截图中的血量条吧,比起拿 CSS 来写完美得多,CSS 拿来做这个太脑残。所以,“Canvas 真香!”,“只是搞这个,头有点凉”。这篇文章的内容可能算是入门 Canvas 的粗略知识汇总。

其实,你可以选择阅读:MDN 文档 / w3schools / Google

下面是我折腾一下午的收获:

创建 Canvas

Given this <canvas> element:

1
<canvas id="canvas"></canvas>

… you can get a reference to the canvas element within the CanvasRenderingContext2D by using the canvas property:

1
2
3
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
ctx.canvas // HTMLCanvasElement

参考:MDN 文档

画一个矩形

直接 strokeRect()

1
2
ctx.strokeStyle = 'blue'; // 蓝色的笔
ctx.strokeRect(10, 10, 100, 100);

或者,使用 lineTo()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ctx.strokeStyle = '#00';
ctx.fillStyle = '#9f9'
ctx.lineWidth = 4;
ctx.beginPath();
ctx.moveTo(30,30);
ctx.lineTo(230,30);
ctx.lineTo(230,200);
ctx.lineTo(30,200);
ctx.lineTo(30,30);
ctx.stroke();

ctx.beginPath();
ctx.moveTo(300,30);
ctx.lineTo(500,30);
ctx.lineTo(500,200);
ctx.lineTo(300,200);
ctx.lineTo(300,30);
ctx.fill();

参考:lineTo() - MDN 文档

lineCap 和 lineJoin

lineCap

Draw a line with rounded end caps:

1
2
3
4
5
6
7
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.lineCap = "round";
ctx.moveTo(20, 20);
ctx.lineTo(200, 20);
ctx.stroke();

lineJoin

Create a rounded corner when the two lines meet:

1
2
3
4
5
6
7
8
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.lineJoin = "round";
ctx.moveTo(20, 20);
ctx.lineTo(100, 50);
ctx.lineTo(20, 100);
ctx.stroke();

参考:w3schools

铺满屏幕

1
2
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

引用外部资源

在绘制引用了外部资源的内容前,需要预先加载完成这些资源,Canvas 才能正常绘制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
let canvas = document.querySelector('canvas');
var ctx = canvas.getContext('2d');
canvas.width = window.innerWidth; // 铺满屏幕
canvas.height = window.innerHeight;

// 加载字体
(new FontFace('SAOUI', 'url(./font/SAOUI.otf)')).load().then((font) => {
document.fonts.add(font);
});

// 加载背景
let bg = new Image();
bg.src = "./img/bg.jpg";

// 加载图标
var flashIcon = new Image();
flashIcon.src = './img/flash.svg';

// 页面加载完毕后执行
window.onload = function () {
draw();
}
1
2
3
4
function draw() {
ctx.fillStyle = ctx.createPattern(bg, "no-repeat"); // '#03A9F4'; // 设置背景图片
ctx.fillRect(0, 0, canvas.width, canvas.width/bg.width * bg.height); // 填充图片,图片自适应高度
}

参考:StackoverFlow

绘制图片

1
ctx.drawImage(flashIcon, x, y, 20, 20);

参考:MDN 文档

渐变色

1
2
3
4
5
6
7
8
let bgColor = ctx.createLinearGradient(x, 0, x+bgW, 0);
bgColor.addColorStop(0, 'rgba(255, 255, 255, 0.40)');
bgColor.addColorStop(0.3, 'rgba(255, 255, 255, 0.40)');
bgColor.addColorStop(1, 'rgba(255, 255, 255, 0.06)');

//...
ctx.fillStyle = bgColor;
ctx.fill();

参考:MDN 文档

绘制文字

1
2
3
4
5
6
7
8
9
10
11
12
13
// 绘制文字
function putText(text, x, y, size, color) {
let f = ctx.font, s = ctx.fillStyle, a = ctx.textAlign, b = ctx.textBaseline;
ctx.font = `${size || 18}px SAOUI`;
ctx.fillStyle = color || '#FFF';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(text, x, y);
ctx.font = f;
ctx.fillStyle = s;
ctx.textAlign = a;
ctx.textBaseline = b;
}

参考:MDN 文档

阴影

1
2
3
4
5
6
7
8
9
10
11
12
ctx.shadowColor = "black";
ctx.shadowBlur = 6;
ctx.shadowOffsetX = 6;
ctx.shadowOffsetY = 6;
ctx.shadowColor = "orange";
ctx.strokeRect(25, 25, 200, 200);
ctx.shadowColor = "green";
ctx.strokeRect(50, 50, 200, 200);
ctx.shadowColor = "blue";
ctx.strokeRect(75, 75, 200, 200);
ctx.shadowColor = "red";
ctx.strokeRect(100, 100, 200, 200);

参考:w3resource

高斯模糊 Blur

1
2
3
ctx.filter = 'blur(4px)';
ctx.font = '48px serif';
ctx.fillText('Hello world', 50, 100);

参考:MDN 文档

放大缩小

1
ctx.scale(2, 2) // Doubles size of anything draw to canvas.

参考:MDN 文档

Transform

1
2
3
4
5
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

ctx.transform(1, .2, .8, 1, 0, 0);
ctx.fillRect(0, 0, 100, 100);

参考:Canvas transform浅析 / MDN 文档

绘制圆角

HTML canvas arcTo() Method:

The arcTo() method creates an arc/curve between two tangents on the canvas.

Tip: Use the stroke() method to actually draw the arc on the canvas.

1
context.arcTo(x1,y1,x2,y2,r);

参考:w3schools

绘制圆角矩形

1
2
3
4
5
6
7
8
9
10
11
12
CanvasRenderingContext2D.prototype.roundRect = function (x, y, w, h, r) {
if (w < 2 * r) {r = w / 2;}
if (h < 2 * r){ r = h / 2;}
this.beginPath();
this.moveTo(x+r, y);
this.arcTo(x+w, y, x+w, y+h, r);
this.arcTo(x+w, y+h, x, y+h, r);
this.arcTo(x, y+h, x, y, r);
this.arcTo(x, y, x+w, y, r);
this.closePath();
return this;
}

参考:CSDN

坐标变换

改变原点:

1
void ctx.translate(x, y);

The translate() method adds a translation transformation to the current matrix by moving the canvas and its origin x units horizontally and y units vertically on the grid.

参考:cnblogs

清空画布

1
void ctx.clearRect(x, y, width, height);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');

// Draw yellow background
ctx.beginPath();
ctx.fillStyle = '#ff6';
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Draw blue triangle
ctx.beginPath();
ctx.fillStyle = 'blue';
ctx.moveTo(20, 20);
ctx.lineTo(180, 20);
ctx.lineTo(130, 130);
ctx.closePath();
ctx.fill();

// Clear part of the canvas
ctx.clearRect(10, 10, 120, 100);

参考:MDN 文档 / CSDN

HP Bar 成品

和 TV 截图比较:

几乎算得上完美!

传送到 GitHub 查看代码 / 查看 DEMO

最后

感叹一句 ——— “Canvas 真香!”

对了,在找资料的时候看到了个骚东西,hhhh:

这时立刻就会想到那些年代久远的广告(笑死

通过 Wayback Machine 你可以找到那些有趣的黑历史,例如:

本站文章除注明转载外均为原创,未经允许不要转载哇. ヾ(゚ー゚ヾ) http://qwqaq.com/db974054.html
分享到