Выразительный JavaScript (Хавербеке) - страница 205

и им подобных, чтобы найти нужный элемент DOM для работы.

Было бы удобно определять части DOM рядом с теми частями кода JavaScript, которые ими управляют. Поэтому я решил создавать всю конструкцию DOM прямо в JavaScript. Как мы видели в главе 13, встроенный интерфейс для создания структур DOM ужасно многословен. Поскольку нам придётся создать много конструкций, нам понадобится вспомогательная функция.

Эта функция – расширенная версия функции >elt из главы 13. Она создаёт элемент с заданным именем и атрибутами, и добавляет все остальные аргументы, которые получает, в качестве дочерних узлов, автоматически преобразовывая строки в текстовые узлы.

>function elt(name, attributes) {

>  var node = document.createElement(name);

>  if (attributes) {

>    for (var attr in attributes)

>      if (attributes.hasOwnProperty(attr))

>        node.setAttribute(attr, attributes[attr]);

>  }

>  for (var i = 2; i < arguments.length; i++) {

>    var child = arguments[i];

>    if (typeof child == "string")

>      child = document.createTextNode(child);

>    node.appendChild(child);

>  }

>  return node;

>}

Так мы легко и просто создаём элементы, не раздувая код до размеров лицензионного соглашения.

Основание

Ядро нашей программы – функция >createPaint, добавляющая интерфейс рисования к элементу DOM, который передаётся в качестве аргумента. Так как мы создаём программу последовательно, мы определяем объект >controls, который будет содержать функции для инициализации разных элементов управления под картинкой.

>var controls = Object.create(null);


>function createPaint(parent) {

>  var canvas = elt("canvas", {width: 500, height: 300});

>  var cx = canvas.getContext("2d");

>  var toolbar = elt("div", {class: "toolbar"});

>  for (var name in controls)

>    toolbar.appendChild(controls[name](cx));


>  var panel = elt("div", {class: "picturepanel"}, canvas);

>  parent.appendChild(elt("div", null, panel, toolbar));

>}

У каждого элемента управления есть доступ к контексту рисования на холсте, а через него – к элементу >. Основное состояние программы хранится в этом холсте – он содержит текущую картинку, выбранный цвет (в свойстве >fillStyle) и размер кисти (в свойстве >lineWidth).

Мы обернём холст и элементы управления в элементы >

с классами, чтобы можно было добавить им стили, например серую рамку вокруг картинки.

Выбор инструмента

Первый элемент управления, который мы добавим – элемент >