В поле >tool есть элементы > для всех определённых нами инструментов, а обработчик события >"mousedown" на холсте берёт на себя обязанность вызывать функцию текущего инструмента, передавая ей объекты >event и >context. Также он вызывает >preventDefault, чтобы зажатие и перетаскивание мыши не вызывало выделения участков страницы.
Самый простой инструмент – линия, который рисует линии за мышью. Чтобы рисовать линию, нам надо сопоставить координаты курсора мыши с координатами точек на холсте. Вскользь упомянутый в 13 главе метод >getBoundingClientRect может нам в этом помочь. Он говорит, где показывается элемент, относительно левого верхнего угла экрана. Свойства события мыши >clientX и >clientY также содержат координаты относительно этого угла, поэтому мы можем вычесть верхний левый угол холста из них и получить позицию относительно этого угла.
Несколько инструментов рисования должны слушать событие >"mousemove", пока кнопка мыши нажата. Функция >trackDrag регистрирует и убирает событие для данных ситуаций.
>function trackDrag(onMove, onEnd) {
> function end(event) {
> removeEventListener("mousemove", onMove);
> removeEventListener("mouseup", end);
> if (onEnd)
> onEnd(event);
> }
> addEventListener("mousemove", onMove);
> addEventListener("mouseup", end);
>}
У неё два аргумента. Один – функция, которая вызывается при каждом событии >"mousemove", а другая – функция, которая вызывается при отпускании кнопки. Каждый аргумент может быть не задан.
Инструмент для рисования линий использует две вспомогательные функции для самого рисования.
>tools.Line = function(event, cx, onEnd) {
> cx.lineCap = "round";
> var pos = relativePos(event, cx.canvas);
> trackDrag(function(event) {
> cx.beginPath();
> cx.moveTo(pos.x, pos.y);
> pos = relativePos(event, cx.canvas);
> cx.lineTo(pos.x, pos.y);
> cx.stroke();
> }, onEnd);
>};
Функция сначала устанавливает свойство контекста >lineCap в >“round”, из-за чего концы нарисованного пути становятся закруглёнными, а не квадратными, как это происходит по умолчанию. Этот трюк обеспечивает непрерывность линий, когда они нарисованы в несколько приёмов. Если рисовать линии большой ширины, вы увидите разрывы в углах линий, если будете использовать установку