JavaScript-холст, вручную клонируя холст на другой, генерирует странный паттерн
Я пытаюсь сделать текстовый эффект похожим на эффект, найденный внизу этой статьи.
Мой предложенный подход:
- Сделайте два полотна, одно видно, другое невидимо, я использую это как буфер.
- Нарисуйте некоторый текст на холсте буфера
- Цикл по пикселям getImageData
- если альфа пикселя не равен нулю (когда пиксель нарисован в буфере холста) с небольшой вероятностью, то есть 2%, нарисуйте случайно сгенерированный круг с крутыми эффектами в этом пикселе на видимом холсте.
У меня проблемы на шаге 4. С помощью приведенного ниже кода я пытаюсь повторить текст на втором холсте, полностью красным. Вместо этого я получаю эту странную картину.
код
// create the canvas to replicate the buffer text on.
var draw = new Drawing(true);
var bufferText = function (size, textFont) {
// set the font to Georgia if it isn't defined
textFont = textFont || "Georgia";
// create a new canvas buffer, true means that it's visible on the screen
// Note, Drawing is a small library I wrote, it's just a wrapper over the canvas API
// it creates a new canvas and adds some functions to the context
// it doesn't change any of the original functions
var buffer = new Drawing(true);
// context is just a small wrapper library I wrote to make the canvas API a little more bearable.
with (buffer.context) {
font = util.format("{size}px {font}", {size: size, font: textFont});
fillText("Hi there", 0, size);
}
// get the imagedata and store the actual pixels array in data
var imageData = buffer.context.getImageData(0, 0, buffer.canvas.width, buffer.canvas.height);
var data = imageData.data;
var index, alpha, x, y;
// loop over the pixels
for (x = 0; x < imageData.width; x++) {
for (y = 0; y < imageData.height; y++) {
index = x * y * 4;
alpha = data[index + 3];
// if the alpha is not equal to 0, draw a red pixel at (x, y)
if (alpha !== 0) {
with (draw.context) {
dot(x/4, y/4, {fillColor: "red"})
}
}
}
}
};
bufferText(20);
Обратите внимание, что здесь мой буфер на самом деле виден, чтобы показать, куда красные пиксели должны идти по сравнению с тем, куда они на самом деле идут.
Я действительно смущен этой проблемой.
Если кто-нибудь знает альтернативный подход, это тоже очень приветствуется.
1 ответ
Решение
Заменить это...
index = x * y * 4;
с...
index = (imageData.width * y) + x;
остальное хорошо:)