Я делаю 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);
}
}
Изображение, которое я использую, взято из здесь
Исправлено с помощью режима «осветления» для черных пикселей с заливкой фона, затем применен режим «затемнения» вместо «исходный» и все готово!
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();
}
Это лучший способ, который я нашел:
fillStyle
созданного контекста холста с цветом текста спрайта (Tint)globalAlpha
созданного контекста холста на непрозрачностьglobalAlpha
созданного контекста холста до 1 (по умолчанию)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);
}