Я играл с элементом canvas и обнаружил, что когда я пытаюсь нарисовать NxN однородные однотонные ячейки рядом друг с другом, в некоторых конфигурациях ширины / высоты между ними появляются размытые линии белого цвета.

Например, этот холст должен выглядеть чёрным, но содержит какую-то сетку , которую я предполагаю в результате ошибочного сглаживания в браузере.

The canvas demonstrating the issue.

Достаточно сказать, что эта ошибка появляется только в некоторых конфигурациях, но я бы хотел избавиться от нее навсегда. Есть ли способ обойти это? Были ли у вас проблемы с сглаживанием на холсте?

Я сделал эту скрипку, которая демонстрирует проблему и позволяет вам играть с размерами холста и количество клеток. Он также содержит код, который я использую для рисования ячеек, чтобы вы могли проверить его и сказать мне, если я делаю что-то не так.

var ctx = canvas.getContext('2d');  
ctx.clearRect(0, 0, canvasWidth, canvasHeight);
for (var i = 0; i < numberOfCells; ++i) {
    for (var j = 0; j < numberOfCells; ++j) {
    ctx.fillStyle = '#000';
    ctx.fillRect(j * cellWidth, i * cellHeight, cellWidth, cellHeight);
  }
}

Заранее спасибо,

Petr .

5
Petr Mánek 17 Дек 2015 в 14:48

3 ответа

Лучший ответ

Прочитав и попробовав несколько подходов, я решил придумать свой. Я создал другой (виртуальный) холст, который имел целочисленные размеры, соответствующие количеству ячеек в сетке.

После отрисовки всех ячеек я вызываю context.drawImage() на главном холсте и передаю виртуальный холст в качестве аргумента вместе с параметрами смещения и масштаба, чтобы он соответствовал остальной части моего рисунка. Предполагая, что браузер будет масштабировать изображение виртуального холста в целом (а не как отдельные ячейки), я надеялся избавиться от нежелательных разделительных линий.

Несмотря на мои усилия, линии все еще там. Какие-либо предложения?

Вот скрипка, демонстрирующая мою технику: https://jsfiddle.net/ngxjnywz/5/

1
Petr Mánek 18 Дек 2015 в 23:52

JsFiddle: https://jsfiddle.net/ngxjnywz/2/

Фрагмент JavaScript

var cellWidth = Math.ceil(canvasWidth / numberOfCells);
var cellHeight = Math.ceil(canvasHeight / numberOfCells);

В зависимости от ширины, высоты и вашего NumberOfCells вы иногда получаете ... скажем, 4,2, что равно 4, однако это будет отображаться неправильно и приведет к появлению пустой строки размером 1 пиксель. Так что все, что вам нужно сделать, это использовать функцию Math.ceil, и это приведет к тому, что значения cellWidth и cellHeight будут всегда больше, и вы больше не будете получать пустые строки

4
Canvas 17 Дек 2015 в 11:57

Лучшее решение - добавить обводку шириной 0,5 пикселя вокруг всех заливок, используя тот же стиль, что и для заливки, и сместить весь рисунок так, чтобы вы отображали его в центре пикселей, а не в верхнем левом углу.

Если вы добавите масштабирование или перевод, вам нужно будет откорректировать координаты, чтобы вы по-прежнему указывали центры для координат чертежа.

В конце концов вы можете только уменьшить артефакты, но во многих ситуациях вы не сможете полностью удалить их.

Этот ответ показывает, как удалить артефакты для нетрансформированного холста. Как заполнить пробелы

2
Community 23 Май 2017 в 12:32