那么我们用 Canvas 来画一个精灵球吧!

398 阅读2分钟

这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战

大家好,我是前端西瓜哥。今天很无聊,就用 Canvas 画个精灵球吧。

这个是完整版的在线 demo:codepen.io/F-star/pen/…

画个背景色

const canvas = document.querySelector('canvas');
canvas.width = 600;
canvas.height = 300;
const ctx = canvas.getContext('2d');

// 背景色
ctx.fillStyle = '#FFDE5C';
ctx.fillRect(0, 0, canvas.width, canvas.height);

// 调整坐标原点到画布中心,方便计算。
ctx.translate(canvas.width / 2, canvas.height / 2);

首先我们做一开始的准备工作。

获取 canvas 元素,设置好它的宽高,并拿到我们的 “画笔”:绘制上下文 ctx。

然后我们绘制一下背景色,搞了个黄色。

接着是将坐标的原点放到画布中心,方便后面设置坐标值,因为这个位置是我们要绘制的精灵球的圆心。

image-20220218232944032.png

使用裁剪限定绘制范围

const r = 100; // 球的半径
ctx.arc(0, 0, r, 0, Math.PI * 2);
ctx.clip();

然后是描绘出一个圆形的路径,并通过 ctx.clip() 设置好一个裁剪范围。之后的所有绘制内容只会在这个范围内显现,超出该范围的绘制会没有效果。

如果你用过 Photoshop,它的效果就类似 “剪贴蒙板”。

画个精灵球剪影

ctx.arc(0, 0, r, 0, Math.PI * 2);
ctx.fillStyle = '#f04'; // 红色
ctx.fill();

然后我们画一个圆形位于坐标原点上,半径大小为 100 的红色圆。

这个半径大一点也是无所谓的,超出的部分会因为设置了裁剪而不显示。

image-20220218232926022.png

画下半部分的白色

ctx.beginPath();
ctx.fillStyle = '#fff';
ctx.fillRect(-r, 0, r * 2, r);
ctx.fill();

与其用路径画个复杂的半圆,直接画一个矩形要方便些,反正超出圆的部分会被裁切。

这也是 Photoshop 等设计工具的 “图层蒙版” 广受欢迎的原因,因为不需要一点点擦干净超出范围的像素。

image-20220218233040170.png

画中间的粗黑线

const w = 10;
ctx.beginPath();
ctx.fillStyle = '#000';
ctx.fillRect(-r, - w / 2, r * 2, w);

同理,我们画的是一个被裁切的矩形。

这里的计算就会麻烦点,要计算左上角的点的位置,宽高分别为球的直径和线的宽度。

image-20220218233426772.png

中心的小黑圆和更小的白色圆

// 小黑圆
const smallBlackR = 30; // 半径
ctx.arc(0, 0, smallBlackR, 0, Math.PI * 2);
ctx.fillStyle = 'black';
ctx.fill();

// 小白圆
const smallWhiteR = 20; // 半径
ctx.beginPath();
ctx.arc(0, 0, smallWhiteR, 0, Math.PI * 2);
ctx.fillStyle = 'white';
ctx.fill();

image-20220218233756455.png

于是,一个没有新意的简约精灵球就画好了。感谢观看。