drawPath() - это ещё один из стандартных методов динамического рисования в ActionScript 3.0. Появился этот метод в арсенале языка только с выходом Flash Player 10 (возможно, это связано с тем, что метод drawPath() в своей работе использует класс Vector, который поддерживается флеш-плеерами только начиная с 10-й версии).
Фактически, метод drawPath() дублирует/заменяет несколько других методов программного рисования: moveTo(), lineTo() и curveTo(). То есть, используя метод drawPath(), можно нарисовать любую линию или кривую.
Посмотрим на синтаксис метода drawPath():
drawPath(commands, coords, winding)
где
- commands - массив-Vector команд рисования. Сами команды рисования представлены в виде целых чисел:
0 - значение по умолчанию (константа GraphicsPathCommand.NO_OP);
1 - аналог метода moveTo() (константа GraphicsPathCommand.MOVE_TO);
2 - аналог метода lineTo() (константа GraphicsPathCommand.LINE_TO);
3 - аналог метода curveTo() (константа GraphicsPathCommand.CURVE_TO);
4 - аналог метода moveTo(), но используется две пары координат вместо одной (константа GraphicsPathCommand.WIDE_MOVE_TO);
5 - аналог метода lineTo(), но используется две пары координат вместо одной (константа GraphicsPathCommand.WIDE_LINE_TO).
- coords - это массив-Vector с координатами рисования.
- winding - этот необязательный параметр определяет направление отрисовки контура и может принимать два значения:
1.) "evenOdd" (константа GraphicsPathWinding.EVEN_ODD; стоит по умолчанию);
2.) "nonZero" (константа GraphicsPathWinding.NON_ZERO).
Лучше, конечно, работу метода drawPath() объяснять на примере. Смотрим пример...
Код ActionScript 3.0:
/*
массив команд
*/
var commands:Vector.<int> = new Vector.<int>();
/*
массив координат
*/
var coords:Vector.<Number> = new Vector.<Number>();
/*
рисуем начальную точку для линии (moveTo())
*/
commands[0] = 1;
coords[0] = 100;
coords[1] = 50;
/*
рисуем конечную точку нашей линии (lineTo())
*/
commands[1] = 2;
coords[2] = 450;
coords[3] = 350;
/*
создаём спрайт, в котором будем рисовать
*/
var sprite:Sprite = new Sprite();
/*
задаём стиль линии
*/
sprite.graphics.lineStyle(5,0xff0000,1);
/*
применяем метод drawPath()
*/
sprite.graphics.drawPath(commands, coords);
/*
добавляем спрайт на сцену
*/
addChild(sprite);
В данном примере мы рисуем линию из точки с координатами (100,50) в точку с координатами (450,350). Для этого мы первым делом создаём точку опускания пера (commands[0] = 1) и задаём для этой точки координаты по оси X и Y (coords[0] = 100 и coords[1] = 50). То есть, фактически, мы прописали старый-добрый метод moveTo():
Код ActionScript 3.0:
sprite.graphics.moveTo(100, 50);
Теперь мы должны указать вторую точку для нашей линии. То есть, де-факто, мы должны применить метод lineTo(). Поэтому в массив commands мы добавляем значение два (commands[1] = 2). А в массив coords, который хранит все координаты для рисования, мы добавляем координаты второй точки нашей прямой (coords[2] = 450 и coords[3] = 350). Таким образом, мы прописали код, аналогичный следующему:
Код ActionScript 3.0:
sprite.graphics.lineTo(450, 350);
Надеюсь, понятно объяснил.
Если для вас команды в виде цифр неудобны, то вы можете воспользоваться для указания команд рисования более "говорящими" константами. Например, приведённый ранее код можно записать так:
Код ActionScript 3.0:
/*
массив команд
*/
var commands:Vector.<int> = new Vector.<int>();
/*
массив координат
*/
var coords:Vector.<Number> = new Vector.<Number>();
/*
рисуем начальную точку для линии (moveTo())
*/
commands[0] = GraphicsPathCommand.MOVE_TO;
coords[0] = 100;
coords[1] = 50;
/*
рисуем конечную точку нашей линии (lineTo())
*/
commands[1] = GraphicsPathCommand.LINE_TO;
coords[2] = 450;
coords[3] = 350;
/*
создаём спрайт, в котором будем рисовать
*/
var sprite:Sprite = new Sprite();
/*
задаём стиль линии
*/
sprite.graphics.lineStyle(5,0xff0000,1);
/*
применяем метод drawPath()
*/
sprite.graphics.drawPath(commands, coords);
/*
добавляем спрайт на сцену
*/
addChild(sprite);
Код абсолютно тот же, но команды-цифры (1 и 2) мы заменили на команды-константы (GraphicsPathCommand.MOVE_TO и GraphicsPathCommand.LINE_TO). Немного громоздко, но зато сразу видно, что за команды выполняются.
Конечно, для рисования одной простой линии метод drawPath(), мягко говоря, избыточен. Его главное назначение - создание сложных векторных фигур. Для примера нарисуем букв "Z":
Код ActionScript 3.0:
/*
массив команд
*/
var commands:Vector.<int> = new Vector.<int>();
/*
массив координат
*/
var coords:Vector.<Number> = new Vector.<Number>();
/*
рисуем начальную точку
*/
commands[0] = GraphicsPathCommand.MOVE_TO;
coords[0] = 100;
coords[1] = 50;
/*
2-я точка
*/
commands[1] = GraphicsPathCommand.LINE_TO;
coords[2] = 450;
coords[3] = 50;
/*
3-я точка
*/
commands[2] = GraphicsPathCommand.LINE_TO;
coords[4] = 100;
coords[5] = 350;
/*
4-я точка
*/
commands[3] = GraphicsPathCommand.LINE_TO;
coords[6] = 450;
coords[7] = 350;
/*
создаём спрайт, в котором будем рисовать
*/
var sprite:Sprite = new Sprite();
/*
задаём стиль линии
*/
sprite.graphics.lineStyle(5,0xff0000,1);
/*
применяем метод drawPath()
*/
sprite.graphics.drawPath(commands, coords);
/*
добавляем спрайт на сцену
*/
addChild(sprite);
Результат:
Как уже ранее говорилось, с помощью drawPath() можно рисовать и кривые. Давайте нарисуем кривую из точки (100,50) в точку (450,350), а контрольная точка у этой кривой будет иметь координаты (450,50) (подробнее о динамическом рисовании кривых в ActionScript смотри в посте «Динамическое рисование кривых в ActionScript»). Рисуем кривую следующим образом:
Код ActionScript 3.0:
/*
массив команд
*/
var commands:Vector.<int> = new Vector.<int>();
/*
массив координат
*/
var coords:Vector.<Number> = new Vector.<Number>();
/*
рисуем начальную точку
*/
commands[0] = 1;
coords[0] = 100;
coords[1] = 50;
/*
рисуем кривую
*/
commands[1] = 3;
coords[2] = 450;
coords[3] = 50;
coords[4] = 450;
coords[5] = 350;
/*
создаём спрайт, в котором будем рисовать
*/
var sprite:Sprite = new Sprite();
/*
задаём стиль линии
*/
sprite.graphics.lineStyle(5,0xff0000,1);
/*
применяем метод drawPath()
*/
sprite.graphics.drawPath(commands, coords);
/*
добавляем спрайт на сцену
*/
addChild(sprite);
или так
Код ActionScript 3.0:
/*
массив команд
*/
var commands:Vector.<int> = new Vector.<int>();
/*
массив координат
*/
var coords:Vector.<Number> = new Vector.<Number>();
/*
рисуем начальную точку
*/
commands[0] = GraphicsPathCommand.MOVE_TO;
coords[0] = 100;
coords[1] = 50;
/*
рисуем кривую
*/
commands[1] = GraphicsPathCommand.CURVE_TO;
coords[2] = 450;
coords[3] = 50;
coords[4] = 450;
coords[5] = 350;
/*
создаём спрайт, в котором будем рисовать
*/
var sprite:Sprite = new Sprite();
/*
задаём стиль линии
*/
sprite.graphics.lineStyle(5,0xff0000,1);
/*
применяем метод drawPath()
*/
sprite.graphics.drawPath(commands, coords);
/*
добавляем спрайт на сцену
*/
addChild(sprite);
Результат:
Эту же кривую с помощью старых-добрых методов moveTo() и curveTo() мы нарисовали бы следующим кодом:
Код ActionScript 3.0:
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(5,0xff0000,1);
sprite.graphics.moveTo(100,50);
sprite.graphics.curveTo(450,50,450,350);
addChild(sprite);
Пока непонятным остаются только команды рисования 4 (GraphicsPathCommand.WIDE_MOVE_TO) и 5 (GraphicsPathCommand.WIDE_LINE_TO). У них специфическое предназначение. Если вы помните, то у методов moveTo() и lineTo() по два параметра (координаты точки по оси X и по оси Y). А у метода curveTo() уже целых четыре параметра:
Код ActionScript:
curveTo(координаты_контрольной_точки_по_оси_x, координаты_контрольной_точки_по_оси_y, координаты_якорной_точки_по_оси_x, координаты_якорной_точки_по_оси_y);
А теперь представьте, что к одному и тому же набору координат (массиву coords) надо иметь возможность в разных ситуациях применять разные методы: и moveTo(), и lineTo(), и curveTo(). Но тогда для метода curveTo() будет просто недостаточно параметров. Именно для этого и вводятся два дополнительные значения на каждую команду рисования. При moveTo() и lineTo() эти два дополнительных значения будут игнорироваться, но зато они позволят корректно работать с этим же набором координат команде curveTo().
Давайте рассмотри два примера:
Пример № 1
Код ActionScript 3.0:
/*
массив команд
*/
var commands:Vector.<int> = new Vector.<int>();
/*
массив координат
*/
var coords:Vector.<Number> = new Vector.<Number>();
/*
рисуем начальную точку
*/
commands[0] = 1;
coords[0] = 100;
coords[1] = 50;
/*
рисуем линию
*/
commands[1] = 5;
coords[2] = 450;
coords[3] = 50;
coords[4] = 450;
coords[5] = 350;
/*
создаём спрайт, в котором будем рисовать
*/
var sprite:Sprite = new Sprite();
/*
задаём стиль линии
*/
sprite.graphics.lineStyle(5,0xff0000,1);
/*
применяем метод drawPath()
*/
sprite.graphics.drawPath(commands, coords);
/*
добавляем спрайт на сцену
*/
addChild(sprite);
Пример № 2
Код ActionScript 3.0:
/*
массив команд
*/
var commands:Vector.<int> = new Vector.<int>();
/*
массив координат
*/
var coords:Vector.<Number> = new Vector.<Number>();
/*
рисуем начальную точку
*/
commands[0] = 1;
coords[0] = 100;
coords[1] = 50;
/*
рисуем линию
*/
commands[1] = 5;
coords[2] = 450;
coords[3] = 50;
coords[4] = 450;
coords[5] = 350;
/*
создаём спрайт, в котором будем рисовать
*/
var sprite:Sprite = new Sprite();
/*
задаём стиль линии
*/
sprite.graphics.lineStyle(5,0xff0000,1);
/*
применяем метод drawPath()
*/
sprite.graphics.drawPath(commands, coords);
/*
добавляем спрайт на сцену
*/
addChild(sprite);
Обратите внимание, что оба примера используют абсолютно одинаковые наборы координат. Но в первом примере рисуется прямая линия из точки с координатами (100,50) в точку с координатами (450,350). А во втором случае рисуется кривая, но тоже из точки (100,50) в точку (450,350). Таким образом, используя один и тот же набор координат, вы можете корректно рисовать и прямые и кривые.
Логично задать вопрос: "Зачем нужен метод drawPath(), если в языке ActionScript уже давно существуют методы с аналогичным функционалом?"
Если верить заверениям разработчиков, то смысл в создании метода drawPath() всё же был. Дело в том, что метод drawPath() работает быстрее и точнее, чем старые методы moveTo(), lineTo() и curveTo(). А значит, что если вам надо создать достаточно сложную графику методами динамического рисования, то ваш выбор должен пасть именно на метод drawPath(). Ну, а в простых случаях, врядли вы заметите разницу в производительности между drawPath() и его старшими собратьями. Учтите также, что производительность метода drawPath() зависит от того, насколько оптимизированными являются используемые этим методом массивы Vector. Утверждается, например, что Vector с фиксированной длиной работает быстрее, чем вектор, чья длина заранее не определена. Давайте проведём оптимизацию нашего примера, в котором мы рисовали букву "Z". А для этого укажем длину нашего будущего массива-вектора и сделаем массив фиксированным (о работе с классом Vector я недавно уже рассказывал в посте «Класс Vector в ActionScript 3.0» и повторяться не буду).
Код ActionScript 3.0:
/*
массив команд
*/
var commands:Vector.<int> = new Vector.<int>(4,true);
/*
массив координат
*/
var coords:Vector.<Number> = new Vector.<Number>(8,true);
/*
рисуем начальную точку
*/
commands[0] = GraphicsPathCommand.MOVE_TO;
coords[0] = 100;
coords[1] = 50;
/*
2-я точка
*/
commands[1] = GraphicsPathCommand.LINE_TO;
coords[2] = 450;
coords[3] = 50;
/*
3-я точка
*/
commands[2] = GraphicsPathCommand.LINE_TO;
coords[4] = 100;
coords[5] = 350;
/*
4-я точка
*/
commands[3] = GraphicsPathCommand.LINE_TO;
coords[6] = 450;
coords[7] = 350;
/*
создаём спрайт, в котором будем рисовать
*/
var sprite:Sprite = new Sprite();
/*
задаём стиль линии
*/
sprite.graphics.lineStyle(5,0xff0000,1);
/*
применяем метод drawPath()
*/
sprite.graphics.drawPath(commands, coords);
/*
добавляем спрайт на сцену
*/
addChild(sprite);
Что же касается последнего параметра (winding) метода drawPath(), то, как уже сказано ранее, этот параметр является необязательным. Главное предназначение winding - определять, как будет производится заливка при пересечении контуров фигур.