在 canvas 上绘制像素并使用多个符号读取位置和颜色?
Draw pixels on canvas and read position and colors with a number of symbols?
我正在尝试在网站上为客户显示小像素图像。
虽然我现在取得了工作成果,但这并不是我想要的可靠解决方案。
我想知道对于纯 JavaScript 甚至 CSS.
的绘图过程是否有更好或更舒适的方法
我脑子里已经有了一个想法,这个想法似乎是我任务最舒适的解决方案,但经过一些尝试后,我仍然不确定如何正确处理它:
是否可以通过读取绘图信息-位置和颜色-
来绘制像素点
来自许多符号(类似于下面黄色框中的符号映射)并使用每个符号引用'#rrggbbaa'中的颜色值并使用额外的符号(如点或逗号)控制 canvas 上的位置?
//~ 1 ................
//~ 2 ................
//~ 3 ....B€2€M€2€....
//~ 4 ..JJJJeeeennnn..
//~ 5 .fff§§§§iiii333.
//~ 6 ..xkxk....ikik..
let pp = ((s = '.dcanvas', A = document.querySelector(s), ctx = A.getContext('2d'),
id = ctx.createImageData(1, 1)) => (x, y, r, g, b, a) => (id.data.set([r, g, b, a]),
ctx.putImageData(id, x, y), A))()
//create points at y3, start at x5
pp(5, 3, 86, 212, 157, 250) //~ B #45D38C
pp(6, 3, 255, 111, 1, 250) //~ € #FF6F00
pp(7, 3, 75, 184, 136, 250) //~ 2 #4BB888
pp(8, 3, 255, 111, 1, 250) //~ € #FF6F00
pp(9, 3, 67, 164, 122, 250) //~ M #43A47A
pp(10, 3, 255, 111, 1, 250) //~ € #FF6F00
pp(11, 3, 75, 184, 136, 250) //~ 2 #4BB888
pp(12, 3, 255, 111, 1, 250) //~ € #FF6F00
//create points at y4, start at x3
pp(3, 4, 195, 69, 149, 250) //~ J #C34595
pp(4, 4, 195, 69, 149, 250) //~ J #C34595
pp(5, 4, 195, 69, 149, 250) //~ J #C34595
pp(6, 4, 195, 69, 149, 250) //~ J #C34595
pp(7, 4, 205, 88, 162, 250) //~ e #CD58A2
pp(8, 4, 205, 88, 162, 250) //~ e #CD58A2
pp(9, 4, 205, 88, 162, 250) //~ e #CD58A2
pp(10, 4, 205, 88, 162, 250) //~ e #CD58A2
pp(11, 4, 232, 104, 185, 250) //~ n #E868B9
pp(12, 4, 232, 104, 185, 250) //~ n #E868B9
pp(13, 4, 232, 104, 185, 250) //~ n #E868B9
pp(14, 4, 232, 104, 185, 250) //~ n #E868B9
//create points at y5, start at x2
pp(2, 5, 88, 222, 217, 250) //~ f #58DED9
pp(3, 5, 88, 222, 217, 250) //~ f #58DED9
pp(4, 5, 88, 222, 217, 250) //~ f #58DED9
pp(5, 5, 170, 170, 170, 250) //~ § #AAAAAA
pp(6, 5, 170, 170, 170, 250) //~ § #AAAAAA
pp(7, 5, 170, 170, 170, 250) //~ § #AAAAAA
pp(8, 5, 170, 170, 170, 250) //~ § #AAAAAA
pp(9, 5, 165, 222, 133, 250) //~ i #A5DE85
pp(10, 5, 165, 222, 133, 250) //~ i #A5DE85
pp(11, 5, 165, 222, 133, 250) //~ i #A5DE85
pp(12, 5, 165, 222, 133, 250) //~ i #A5DE85
pp(13, 5, 95, 181, 181, 250) //~ 3 #5FB5B5
pp(14, 5, 95, 181, 181, 250) //~ 3 #5FB5B5
pp(15, 5, 95, 181, 181, 250) //~ 3 #5FB5B5
//create points at y6, start at x3
pp(3, 6, 11, 122, 229, 250) // ~ x #0B7AE5
pp(4, 6, 232, 199, 17, 250) // ~ k #E8C711
pp(5, 6, 11, 122, 229, 250) // ~ x #0B7AE5
pp(6, 6, 232, 199, 17, 250) // ~ k #E8C711
// ~ .
// ~ .
// ~ .
// ~ .
pp(11, 6, 165, 222, 133, 250) // ~ i #A5DE85
pp(12, 6, 232, 199, 17, 250) // ~ k #E8C711
pp(13, 6, 165, 222, 133, 250) // ~ i #A5DE85
pp(14, 6, 232, 199, 17, 250) // ~ k #E8C711
//color reader
let A = rp(50, 80);
<canvas class="dcanvas" width=48 height=48 style="background: #383838">
有很多可能的解决方案,但这里有一个。创建一个 array of your pixel data, and a map 你的颜色。然后遍历你的像素,一个一个输出。
const pixels = [
'................',
'................',
'....B€2€M€2€....',
'..JJJJeeeennnn..',
'.fff§§§§iiii333.',
'..xkxk....ikik..',
];
const colors = new Map([
['B', '#45D38C'],
['€', '#FF6F00'],
['2', '#4BB888'],
['M', '#43A47A'],
['J', '#C34595'],
['e', '#CD58A2'],
['n', '#E868B9'],
['f', '#58DED9'],
['§', '#AAAAAA'],
['i', '#A5DE85'],
['3', '#5FB5B5'],
['x', '#0B7AE5'],
['k', '#E8C711'],
['i', '#A5DE85'],
]);
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
pixels.forEach((row, y) => {
row.split('').forEach((pixel, x) => {
if (colors.has(pixel)) {
ctx.fillStyle = colors.get(pixel);
ctx.fillRect(x, y, 1, 1);
}
});
});
<canvas id="canvas" width=48 height=48 style="background: #383838">
更快的选择:
您可能已经猜到了,如果要绘制很多像素,您会希望使用 ImageData
对象。 (它会比简单的 fillRect()
方法更快。)You'll also need to convert your hex values to RGB. 以下是您可以这样做的方法:
const pixels = [
'................',
'................',
'....B€2€M€2€....',
'..JJJJeeeennnn..',
'.fff§§§§iiii333.',
'..xkxk....ikik..',
];
const colors = new Map([
['B', '#45D38C'],
['€', '#FF6F00'],
['2', '#4BB888'],
['M', '#43A47A'],
['J', '#C34595'],
['e', '#CD58A2'],
['n', '#E868B9'],
['f', '#58DED9'],
['§', '#AAAAAA'],
['i', '#A5DE85'],
['3', '#5FB5B5'],
['x', '#0B7AE5'],
['k', '#E8C711'],
['i', '#A5DE85'],
]);
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const imageData = ctx.createImageData(canvas.width, canvas.height);
pixels.forEach((row, y) => {
row.split('').forEach((pixel, x) => {
const hex = colors.get(pixel);
if (hex) {
const px = x * 4;
const py = y * canvas.width * 4;
const rgb = hexToRgb(hex);
imageData.data[py + px + 0] = rgb[0]; // R value
imageData.data[py + px + 1] = rgb[1]; // G value
imageData.data[py + px + 2] = rgb[2]; // B value
imageData.data[py + px + 3] = 255; // A value
}
});
});
ctx.putImageData(imageData, 0, 0);
function hexToRgb(hex) {
hex = hex.replace('#', '');
const bigint = parseInt(hex, 16);
const r = (bigint >> 16) & 255;
const g = (bigint >> 8) & 255;
const b = bigint & 255;
return [r, g, b];
}
<canvas id="canvas" width=48 height=48 style="background: #383838">
我正在尝试在网站上为客户显示小像素图像。
虽然我现在取得了工作成果,但这并不是我想要的可靠解决方案。
我想知道对于纯 JavaScript 甚至 CSS.
的绘图过程是否有更好或更舒适的方法
我脑子里已经有了一个想法,这个想法似乎是我任务最舒适的解决方案,但经过一些尝试后,我仍然不确定如何正确处理它:
是否可以通过读取绘图信息-位置和颜色-
来绘制像素点
来自许多符号(类似于下面黄色框中的符号映射)并使用每个符号引用'#rrggbbaa'中的颜色值并使用额外的符号(如点或逗号)控制 canvas 上的位置?
//~ 1 ................ //~ 2 ................ //~ 3 ....B€2€M€2€.... //~ 4 ..JJJJeeeennnn.. //~ 5 .fff§§§§iiii333. //~ 6 ..xkxk....ikik..
let pp = ((s = '.dcanvas', A = document.querySelector(s), ctx = A.getContext('2d'),
id = ctx.createImageData(1, 1)) => (x, y, r, g, b, a) => (id.data.set([r, g, b, a]),
ctx.putImageData(id, x, y), A))()
//create points at y3, start at x5
pp(5, 3, 86, 212, 157, 250) //~ B #45D38C
pp(6, 3, 255, 111, 1, 250) //~ € #FF6F00
pp(7, 3, 75, 184, 136, 250) //~ 2 #4BB888
pp(8, 3, 255, 111, 1, 250) //~ € #FF6F00
pp(9, 3, 67, 164, 122, 250) //~ M #43A47A
pp(10, 3, 255, 111, 1, 250) //~ € #FF6F00
pp(11, 3, 75, 184, 136, 250) //~ 2 #4BB888
pp(12, 3, 255, 111, 1, 250) //~ € #FF6F00
//create points at y4, start at x3
pp(3, 4, 195, 69, 149, 250) //~ J #C34595
pp(4, 4, 195, 69, 149, 250) //~ J #C34595
pp(5, 4, 195, 69, 149, 250) //~ J #C34595
pp(6, 4, 195, 69, 149, 250) //~ J #C34595
pp(7, 4, 205, 88, 162, 250) //~ e #CD58A2
pp(8, 4, 205, 88, 162, 250) //~ e #CD58A2
pp(9, 4, 205, 88, 162, 250) //~ e #CD58A2
pp(10, 4, 205, 88, 162, 250) //~ e #CD58A2
pp(11, 4, 232, 104, 185, 250) //~ n #E868B9
pp(12, 4, 232, 104, 185, 250) //~ n #E868B9
pp(13, 4, 232, 104, 185, 250) //~ n #E868B9
pp(14, 4, 232, 104, 185, 250) //~ n #E868B9
//create points at y5, start at x2
pp(2, 5, 88, 222, 217, 250) //~ f #58DED9
pp(3, 5, 88, 222, 217, 250) //~ f #58DED9
pp(4, 5, 88, 222, 217, 250) //~ f #58DED9
pp(5, 5, 170, 170, 170, 250) //~ § #AAAAAA
pp(6, 5, 170, 170, 170, 250) //~ § #AAAAAA
pp(7, 5, 170, 170, 170, 250) //~ § #AAAAAA
pp(8, 5, 170, 170, 170, 250) //~ § #AAAAAA
pp(9, 5, 165, 222, 133, 250) //~ i #A5DE85
pp(10, 5, 165, 222, 133, 250) //~ i #A5DE85
pp(11, 5, 165, 222, 133, 250) //~ i #A5DE85
pp(12, 5, 165, 222, 133, 250) //~ i #A5DE85
pp(13, 5, 95, 181, 181, 250) //~ 3 #5FB5B5
pp(14, 5, 95, 181, 181, 250) //~ 3 #5FB5B5
pp(15, 5, 95, 181, 181, 250) //~ 3 #5FB5B5
//create points at y6, start at x3
pp(3, 6, 11, 122, 229, 250) // ~ x #0B7AE5
pp(4, 6, 232, 199, 17, 250) // ~ k #E8C711
pp(5, 6, 11, 122, 229, 250) // ~ x #0B7AE5
pp(6, 6, 232, 199, 17, 250) // ~ k #E8C711
// ~ .
// ~ .
// ~ .
// ~ .
pp(11, 6, 165, 222, 133, 250) // ~ i #A5DE85
pp(12, 6, 232, 199, 17, 250) // ~ k #E8C711
pp(13, 6, 165, 222, 133, 250) // ~ i #A5DE85
pp(14, 6, 232, 199, 17, 250) // ~ k #E8C711
//color reader
let A = rp(50, 80);
<canvas class="dcanvas" width=48 height=48 style="background: #383838">
有很多可能的解决方案,但这里有一个。创建一个 array of your pixel data, and a map 你的颜色。然后遍历你的像素,一个一个输出。
const pixels = [
'................',
'................',
'....B€2€M€2€....',
'..JJJJeeeennnn..',
'.fff§§§§iiii333.',
'..xkxk....ikik..',
];
const colors = new Map([
['B', '#45D38C'],
['€', '#FF6F00'],
['2', '#4BB888'],
['M', '#43A47A'],
['J', '#C34595'],
['e', '#CD58A2'],
['n', '#E868B9'],
['f', '#58DED9'],
['§', '#AAAAAA'],
['i', '#A5DE85'],
['3', '#5FB5B5'],
['x', '#0B7AE5'],
['k', '#E8C711'],
['i', '#A5DE85'],
]);
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
pixels.forEach((row, y) => {
row.split('').forEach((pixel, x) => {
if (colors.has(pixel)) {
ctx.fillStyle = colors.get(pixel);
ctx.fillRect(x, y, 1, 1);
}
});
});
<canvas id="canvas" width=48 height=48 style="background: #383838">
更快的选择:
您可能已经猜到了,如果要绘制很多像素,您会希望使用 ImageData
对象。 (它会比简单的 fillRect()
方法更快。)You'll also need to convert your hex values to RGB. 以下是您可以这样做的方法:
const pixels = [
'................',
'................',
'....B€2€M€2€....',
'..JJJJeeeennnn..',
'.fff§§§§iiii333.',
'..xkxk....ikik..',
];
const colors = new Map([
['B', '#45D38C'],
['€', '#FF6F00'],
['2', '#4BB888'],
['M', '#43A47A'],
['J', '#C34595'],
['e', '#CD58A2'],
['n', '#E868B9'],
['f', '#58DED9'],
['§', '#AAAAAA'],
['i', '#A5DE85'],
['3', '#5FB5B5'],
['x', '#0B7AE5'],
['k', '#E8C711'],
['i', '#A5DE85'],
]);
const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
const imageData = ctx.createImageData(canvas.width, canvas.height);
pixels.forEach((row, y) => {
row.split('').forEach((pixel, x) => {
const hex = colors.get(pixel);
if (hex) {
const px = x * 4;
const py = y * canvas.width * 4;
const rgb = hexToRgb(hex);
imageData.data[py + px + 0] = rgb[0]; // R value
imageData.data[py + px + 1] = rgb[1]; // G value
imageData.data[py + px + 2] = rgb[2]; // B value
imageData.data[py + px + 3] = 255; // A value
}
});
});
ctx.putImageData(imageData, 0, 0);
function hexToRgb(hex) {
hex = hex.replace('#', '');
const bigint = parseInt(hex, 16);
const r = (bigint >> 16) & 255;
const g = (bigint >> 8) & 255;
const b = bigint & 255;
return [r, g, b];
}
<canvas id="canvas" width=48 height=48 style="background: #383838">