为 Spritefonts 提供 canvas2d 图像色调
Providing canvas2d image tint for Spritefonts
我正在做 Spritefonts,目前正在 WebGL 上为它实现色调!
但在 canvas2d 上,我尝试通过 ctx.globalCompositeOperation
进行操作,但它显示以下内容
如你所见,黑色像素也被填充...
这是我的代码...
var size = 32;
var x = 200;
var y = 200;
var spacing = 0;
for (var i = 0; i < txt.length; i++) {
var q = fonts[0].info[txt[i]];
ctx.save();
if (q) ctx.drawImage(fonts[0].src, q.x, q.y, q.w, q.h, x + (spacing || 0) + (i * size), y, size, size);
ctx.globalCompositeOperation = "source-in";
ctx.fillStyle = "green";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();
}
当尝试使用“变暗”模式时,它会正确填充但也会填充背景(我不想要这个...)
我也试过 ctx.getImageData()
和 ctx.putImageData()
但字母没有显示
var size = 32;
var x = 200;
var y = 200;
var spacing = 0;
for (var i = 0; i < txt.length; i++) {
var q = fonts[0].info[txt[i]];
if (q) {
ctx.drawImage(fonts[0].src, q.x, q.y, q.w, q.h, x + (spacing || 0) + (i * size), y, size, size);
f = ctx.getImageData(x + (spacing || 0) + (i * size), y, size, size);
for (var i = 0; i < f.data.length; i += 4) {
f.data[i + 0] = 100;
f.data[i + 1] = 100;
f.data[i + 2] = 255;
f.data[i + 3] = 255;
}
ctx.putImageData(f, x + (spacing || 0) + (i * size), y, 0, 0, size, size);
}
}
我使用的图片来自here
通过对填充背景的黑色像素使用“变亮”模式进行修复,然后应用“变暗”模式而不是“源输入”,全部完成!
var size = 32;
var x = 200;
var y = 200;
var spacing = 0;
for (var i = 0; i < txt.length; i++) {
var q = fonts[0].info[txt[i]];
ctx.save();
ctx.globalCompositeOperation = "lighten";
ctx.fillStyle = ctx.canvas.style.backgroundColor;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
if (q) ctx.drawImage(fonts[0].src, q.x, q.y, q.w, q.h, x + (spacing || 0) + (i * size), y, size, size);
ctx.globalCompositeOperation = "darken";
ctx.fillStyle = "green";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.restore();
}
这是我发现的更好的方法:
- 使用符合 spritefont 图像尺寸的尺寸创建 canvas
- 在创建的 canvas
中保存上下文状态
- 为创建的 canvas 上下文设置
fillStyle
spritefont 文本颜色(色调)
- 将创建的 canvas 上下文的
globalAlpha
设置为不透明度
- 使用 spritefont 文本颜色(色调)填充创建的 canvas 背景
- 在创建的 canvas 上下文中应用“destination-atop”复合模式
- 将创建的 canvas 上下文的
globalAlpha
重置为 1(默认)
- 将 spritefont 图像绘制到创建的 canvas
- 恢复创建的上下文状态canvas
- 然后,让默认的 canvas 上下文(不是创建的)从 spritefont 图像中绘制字符,所以我们让它绘制我们创建的 canvas 的一部分(注意 spritefont 图像填充所有创建的 canvas)
- 完成!
var size = 32;
var x = 200;
var y = 200;
var spacing = 0;
var opacity = 0.8;
var color = "green";
for (var i = 0; i < txt.length; i++) {
var q = fonts[0].info[txt[i]];
var c = document.createElement("canvas").getContext("2d");
c.canvas.width = fonts[0].src.width;
c.canvas.height = fonts[0].src.height;
c.save();
c.fillStyle = color;
c.globalAlpha = opacity || 0.8;
c.fillRect(0, 0, c.canvas.width, c.canvas.height);
c.globalCompositeOperation = "destination-atop";
c.globalAlpha = 1;
c.drawImage(fonts[0].src, 0, 0);
c.restore();
if (q) ctx.drawImage(c.canvas, q.x, q.y, q.w, q.h, x + (i * (size + spacing)), y, size, size);
}
我正在做 Spritefonts,目前正在 WebGL 上为它实现色调!
但在 canvas2d 上,我尝试通过 ctx.globalCompositeOperation
进行操作,但它显示以下内容
如你所见,黑色像素也被填充...
这是我的代码...
var size = 32;
var x = 200;
var y = 200;
var spacing = 0;
for (var i = 0; i < txt.length; i++) {
var q = fonts[0].info[txt[i]];
ctx.save();
if (q) ctx.drawImage(fonts[0].src, q.x, q.y, q.w, q.h, x + (spacing || 0) + (i * size), y, size, size);
ctx.globalCompositeOperation = "source-in";
ctx.fillStyle = "green";
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.restore();
}
当尝试使用“变暗”模式时,它会正确填充但也会填充背景(我不想要这个...)
我也试过 ctx.getImageData()
和 ctx.putImageData()
但字母没有显示
var size = 32;
var x = 200;
var y = 200;
var spacing = 0;
for (var i = 0; i < txt.length; i++) {
var q = fonts[0].info[txt[i]];
if (q) {
ctx.drawImage(fonts[0].src, q.x, q.y, q.w, q.h, x + (spacing || 0) + (i * size), y, size, size);
f = ctx.getImageData(x + (spacing || 0) + (i * size), y, size, size);
for (var i = 0; i < f.data.length; i += 4) {
f.data[i + 0] = 100;
f.data[i + 1] = 100;
f.data[i + 2] = 255;
f.data[i + 3] = 255;
}
ctx.putImageData(f, x + (spacing || 0) + (i * size), y, 0, 0, size, size);
}
}
我使用的图片来自here
通过对填充背景的黑色像素使用“变亮”模式进行修复,然后应用“变暗”模式而不是“源输入”,全部完成!
var size = 32;
var x = 200;
var y = 200;
var spacing = 0;
for (var i = 0; i < txt.length; i++) {
var q = fonts[0].info[txt[i]];
ctx.save();
ctx.globalCompositeOperation = "lighten";
ctx.fillStyle = ctx.canvas.style.backgroundColor;
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
if (q) ctx.drawImage(fonts[0].src, q.x, q.y, q.w, q.h, x + (spacing || 0) + (i * size), y, size, size);
ctx.globalCompositeOperation = "darken";
ctx.fillStyle = "green";
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.restore();
}
这是我发现的更好的方法:
- 使用符合 spritefont 图像尺寸的尺寸创建 canvas
- 在创建的 canvas 中保存上下文状态
- 为创建的 canvas 上下文设置
fillStyle
spritefont 文本颜色(色调) - 将创建的 canvas 上下文的
globalAlpha
设置为不透明度 - 使用 spritefont 文本颜色(色调)填充创建的 canvas 背景
- 在创建的 canvas 上下文中应用“destination-atop”复合模式
- 将创建的 canvas 上下文的
globalAlpha
重置为 1(默认) - 将 spritefont 图像绘制到创建的 canvas
- 恢复创建的上下文状态canvas
- 然后,让默认的 canvas 上下文(不是创建的)从 spritefont 图像中绘制字符,所以我们让它绘制我们创建的 canvas 的一部分(注意 spritefont 图像填充所有创建的 canvas)
- 完成!
var size = 32;
var x = 200;
var y = 200;
var spacing = 0;
var opacity = 0.8;
var color = "green";
for (var i = 0; i < txt.length; i++) {
var q = fonts[0].info[txt[i]];
var c = document.createElement("canvas").getContext("2d");
c.canvas.width = fonts[0].src.width;
c.canvas.height = fonts[0].src.height;
c.save();
c.fillStyle = color;
c.globalAlpha = opacity || 0.8;
c.fillRect(0, 0, c.canvas.width, c.canvas.height);
c.globalCompositeOperation = "destination-atop";
c.globalAlpha = 1;
c.drawImage(fonts[0].src, 0, 0);
c.restore();
if (q) ctx.drawImage(c.canvas, q.x, q.y, q.w, q.h, x + (i * (size + spacing)), y, size, size);
}