Рисование перекрывающихся полупрозрачных линий без видимого перекрытия - PullRequest
8 голосов
/ 07 декабря 2011

Я разрабатываю программу для рисования с использованием HTML5 canvas. Я создал инструмент для рисования, где пользователь перетаскивает и перемещает мышь.

У меня есть слушатель события mousemove, который рисует короткие линии:

Painter.mainCanvas.beginPath();
Painter.mainCanvas.moveTo(Painter.lastX, Painter.lastY);
Painter.lastX = e.offsetX;
Painter.lastY = e.offsetY;
Painter.mainCanvas.lineTo(Painter.lastX, Painter.lastY);
Painter.mainCanvas.stroke();

Все работает хорошо, пока я не установлю глобальную альфу на <1. При использовании этого метода для рисования, конечная точка также является начальной точкой. Таким образом, точка рисуется дважды. И поскольку у нас есть прозрачный цвет, точка теперь имеет другой цвет с другими точками в линии. </p>

Я попробовал другой метод, который при запуске mousemove использует lineTo() и stroke() только при запуске mouseup.

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

1 Ответ

20 голосов
/ 07 декабря 2011

(Восстановление вашей проблемы) Ваша первоначальная проблема заключалась в том, что при вызове beginPath() и stroke() для каждого сегмента у вас было много перекрывающихся полупрозрачных путей.Ваша новая «проблема» заключается в том, что, создавая все ваши lineTo() команды как часть одного и того же пути, а затем вызывая stroke() один раз в конце, любые самопересекающиеся пути, предназначенные пользователем, не показываютвидимое перекрытие.

Ниже приведен пример, показывающий разницу между

  • множеством полупрозрачных линий на одном пути и штрихом один раз (вверху слева) по сравнению с

http://jsfiddle.net/jhyG5/2/

A semi-transparent set of crossing lines (all the same opacity) in the upper left and a set of crossing lines with increasing opacity where they cross in the bottom right.

Я бы сказал, что ваше текущее решение(единственный путь) является правильным способом сделать это, даже если один самопересекающийся путь не удваивается в непрозрачности.Это то, что вы видите в Adobe Photoshop и Illustrator при рисовании полупрозрачных контуров: все рисование с мышью вниз является частью одного и того же неперекрывающегося прозрачного объекта.Только когда пользователь отпускает и повторно нажимает кнопку мыши, вы накапливаете больше прозрачности:

  • Два мазка кистью Photoshop с непрозрачностью 50%:
    Photoshop Overlapping Style

  • Два тракта Illustrator с непрозрачностью 50%: Illustrator Overlapping Strokes

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

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

...