LINUX.ORG.RU

html canvas, линии, координаты, пиксельные буферы, OffscreenCanvas и прочее безумие.

 ,


0

2
  1. Известно, что <canvas> 2d context считает центром самого первого пикселя координату (0.5, 0.5), потому что координаты он считает не как индексы пикселей, а как координаты, мать её, сетки, между которыми пиксели стоят. Координата (0, 0) обозначает не самый верхний левый пиксель, а верхнюю-левую вершину этого пикселя. Поэтому если ты пустил линию (0, 0, 10, 0), то получишь что-то размытое антиалиасингом серое между двумя рядами пикселями. Причём, верхнюю половину размытой линии ты не увидишь, у ибо она будет тянуться до -0.5, а экран у тебя от 0. Некоторые делают context.translate(0.5, 0.5) и так живут, а некоторые + 0.5 везде пишут. Дурка, короче, но не суть.

  2. Но есть ещё OffscreenCanvas, чтобы в памяти рисовать спрайты (например), быстро рисуемые на другом канвасе.

Теперь зацените прикол:

  1. Выключаем на главном наэкранном канвасе всякий там context.stanslate(0.5, 0.5) и рисуем линию по целочисленным координатам. Ожидаемо видим размытую хрень. Ладно, понятно.

  2. Теперь, берём и то же самое рисуем на OffscreenCanvas, ожидая что в памяти в пиксельный буфер будут отрендерены такие же размытые линии. Далее методом context.drawImage(my_offscreen_canvas) пихаем нарисованное на нашем OffscreenCanvas главный канвас. И хоба, никакого размытия мы не видим, все линии чоткие пацанские.

Как так-то?



Последнее исправление: lesopilorama (всего исправлений: 2)

скажу даже точнее: железо считает также. это вроде как можно переключить в угол (0,0). 2Д работает через 3Д.

Так что жри что дают и не жужжи. Ничего другого нет и не будет.

«И хоба»

Хоба, и контекст в onscreen канвасе это часть контекста отрисовки всего окна. А offscreen канвас это твоя личная помоечка на которую всем наплевать. Ты можешь видеть последствия работы логики браузера а не opengl.

Чтоб видеть свои последствия используй силу:

https://registry.khronos.org/OpenGL-Refpages/gl4/html/gl_FragCoord.xhtml

ckotctvo
()
Ответ на: комментарий от ckotctvo

Хоба, и контекст в onscreen канвасе это часть контекста отрисовки всего окна. А offscreen канвас это твоя личная помоечка на которую всем наплевать.

А правила рендеринга вызовов lineTo и прочих подобных-то у них почему разные? Почему линия между пикселей у первого - это пыхтит антиалиасинг, а линия между пикселей у второго - он срал на эту логику и ведёт линию тупо по одному ряду пикселей?

lesopilorama
() автор топика

иди читай про Display context, PostScript Display model (затем: PDF как подмножество постскрипт; Display PostScript как расширение постскрипта печатного)и gsave/grestore в постскрипт.

и соответственно, потом это перешло в GDI и канвас в браузере.

anonymous
()
Ответ на: комментарий от anonymous

ты пилишь фидобраузер с векторным гипертекстовым? или что?

Вывел на канвас фотку, получившуюся врезультате её ресайза в сишном коде скомпиленном в webasm, теперь надо поверх фотки вывести рамку инструмента «ресайз», чтобы юзер мог её порезать. Таки задачу решил уже, +0.5 оказалось меньшим из зол

lesopilorama
() автор топика
Последнее исправление: lesopilorama (всего исправлений: 1)
Ответ на: комментарий от anonymous

иди читай про Display context, PostScript Display model (затем: PDF как подмножество постскрипт; Display PostScript как расширение постскрипта печатного)и gsave/grestore в постскрипт

Чтобы что. Тащи сразу кратенько ответ сюда оттуда, если он там есть. Ты увибел там ответ и сюда не скопипастил его? Зачем ты тогдп туда ходил. Капец.

lesopilorama
() автор топика

Проверил, поведение не подтверждаю.

<!doctype html>
<canvas id="canvas1" width="100" height="100"></canvas>
<br>
<canvas id="canvas2" width="100" height="100"></canvas>
<script>
const canvas1 = document.getElementById('canvas1');
const context1 = canvas1.getContext('2d');
context1.strokeRect(10, 10, 10, 10);
context1.strokeRect(10.5, 30.5, 10, 30);
	
const canvas2 = document.getElementById('canvas2');
const offscreenCanvas = canvas2.transferControlToOffscreen();
const context2 = offscreenCanvas.getContext("2d");
context2.strokeRect(10, 10, 10, 10);
context2.strokeRect(10.5, 30.5, 10, 30);
</script>

Этот код рисует две канвы с идентичными квадратами. Первый расплылся, второй - нет.

vbr ★★★★★
()