JavaScript-холст, вручную клонируя холст на другой, генерирует странный паттерн

Я пытаюсь сделать текстовый эффект похожим на эффект, найденный внизу этой статьи.

введите описание изображения здесь

Мой предложенный подход:

  1. Сделайте два полотна, одно видно, другое невидимо, я использую это как буфер.
  2. Нарисуйте некоторый текст на холсте буфера
  3. Цикл по пикселям getImageData
  4. если альфа пикселя не равен нулю (когда пиксель нарисован в буфере холста) с небольшой вероятностью, то есть 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;

остальное хорошо:)

Другие вопросы по тегам