-
Notifications
You must be signed in to change notification settings - Fork 11
canvas 实战 ‐ 头像组装、颜色选取
lemma edited this page Jul 28, 2023
·
1 revision
一句话描述,用
canvas.drawImage
实现头像拼接,图片增加装饰,获取图片点击处颜色等功能;
canvas、drawImage、 demo、头像拼接、颜色选取
在玩蛋仔派对的时候,觉得换肤很有意思。在逛开源社区的时候,看到了用 canvas.drawImage
实现同样效果的项目(gclx-official)。
继续逛下去发现有很多场景的实现原理都是相同的。
drawImage
可以将图片绘制到画布上面。
重载了三种函数入参,可以设置图片的宽高和对原始图片的裁剪。
//在画布上定位图像:
drawImage(image, dx, dy);
// 在画布上定位图像,并规定图像的宽度和高度:
drawImage(image, dx, dy, dWidth, dHeight);
//剪切图像,并在画布上定位被剪切的部分:
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
先创建一个 image 元素
const loadImage = (src: string) =>
new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = reject;
img.src = src;
});
在图片加载好以后,再调用 drawImage 函数,将图片绘制到画布中
ctx?.drawImage(item, 0, 0, 200, 200);
这样,一张图片就被画到画布上面了。
体验地址:头像拼接
如果要实现拼接头像的功能,就是将几张图片叠加绘制到画布上去。
核心代码就两行
- 加载需要的图片
- 将图片绘制到画布中
const imagesObj = await Promise.all(images.map(loadImage));
imagesObj.forEach((item) => {
ctx?.drawImage(item, 0, 0, 200, 200);
});
其他的就是一些细节的调整,比如发型要放到画布最下面;每次渲染的时候需要清理一下画布等。
功能描述:就是在节日的时候,可以在头像上增加一些节日的装饰,增加节日气氛。体验地址:节日气氛
主要还是将头像和装饰部分的图片按顺序绘制上去。
const images = [imageUrl, imgSelect].filter((i) => !!i);
const imagesObj = await Promise.all(images.map(loadImage));
imagesObj.forEach((item) => {
ctx?.drawImage(item, 0, 0, 200, 200);
});
功能描述:每次点击图片,背景色都会变成点击部分的颜色。截图:
getImageData
可以获取 canvas
某一个点的坐标值和颜色值。
function getColor(x: number, y: number) {
const imageData = ctx!.getImageData(x, y, 1, 1);
const pixel = imageData.data; // data: 类型为Uint8ClampedArray的一维数组,每四个数组元素代表了一个像素点的RGBA信息,每个元素数值介于0~255
const [r, g, b, aBefore] = pixel;
const a = Math.round(aBefore / 255);
const rgba = `rgba(${r}, ${g}, ${b}, ${a})`;
return {
rgba,
};
}
所以整个流程是这样子的:
- 将图片绘制到 canvas 上
- 注册 canvas 的 click 事件
- 当监听到
click
事件,进行计算,获取点击所在的点在 canvas 上的坐标(x,y) - 计算画布上坐标(x,y)的颜色值,将该值绘制到背景上
觉得有点意思就给个 star 吧。