Выбрать главу

Два последних параметра могут помочь в рисовании части круга. Углы измеряются в радианах, а не градусах. Это значит, что полный круг имеет угол в 2π, или 2 * Math.PI, что примерно равно 6,28. Угол начинает отсчёт от точки справа от центра, и идёт против часовой стрелки. Чтобы нарисовать полный круг, можно задать начало в 0, а конец больше 2π (к примеру, 7).

<canvas></canvas>

<script>

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

  cx.beginPath();

  // center=(50,50) radius=40 angle=0 to 7

  cx.arc(50, 50, 40, 0, 7);

  // center=(150,50) radius=40 angle=0 to ½π

  cx.arc(150, 50, 40, 0, 0.5 * Math.PI);

  cx.stroke();

</script>

На картинке в результате будет линия слева от круга (первый вызов arc), до левой части четверти круга (второй вызов). Как и другие методы рисования путей, линия дуги соединена с предыдущим сегментом пути. Для начала рисования нового пути надо вызвать moveTo.

Рисуем круговую диаграмму

Представьте, что вы получили работу в ООО «Экономика для всех», и вашим первым заданием будет нарисовать круговую диаграмму удовлетворённости клиентов согласно результатам опроса.

Переменная result содержит массив объектов, представляющих результаты.

var results = [

  {name: "Удовлетворён", count: 1043, color: "lightblue"},

  {name: "Нейтральное", count: 563, color: "lightgreen"},

  {name: "Не удовлетворён", count: 510, color: "pink"},

  {name: "Без комментариев", count: 175, color: "silver"}

];

Чтобы нарисовать диаграмму, мы рисуем несколько секторов, каждый из которых делается из арки и пары линий от центра. Угол мы вычисляем, деля полный круг (2π) на общее количество отзывов, и умножая на количество людей, выбравших данный вариант ответа.

<canvas width="200" height="200"></canvas>

<script>

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

  var total = results.reduce(function(sum, choice) {

    return sum + choice.count;

  }, 0);

  // Start at the top

  var currentAngle = -0.5 * Math.PI;

  results.forEach(function(result) {

    var sliceAngle = (result.count / total) * 2 * Math.PI;

    cx.beginPath();

    // center=100,100, radius=100

    // from current angle, clockwise by slice's angle

    cx.arc(100, 100, 100,

           currentAngle, currentAngle + sliceAngle);

    currentAngle += sliceAngle;

    cx.lineTo(100, 100);

    cx.fillStyle = result.color;

    cx.fill();

  });

</script>

Но диаграмма не расшифровывает значения секторов – это неудобно. Нам надо как-то нарисовать на холсте текст.

Текст

У контекста двумерного холста есть методы fillText и strokeText. Последний можно использовать для обведённых букв, но обычно используется fillText. Он заполняет заданный текст цветом fillColor.

<canvas></canvas>

<script>

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

  cx.font = "28px Georgia";

  cx.fillStyle = "fuchsia";

  cx.fillText("Я и текст могу рисовать!", 10, 50);

</script>

Можно задать размер, стиль и шрифт текста через свойство font. В примере задаётся только размер и шрифт. Можно добавить наклон и жирность в начале строки.

Два последних аргумента fillTextstrokeText) задают позицию, с которой начинается текст. По умолчанию это начало линии, на которой «стоят» буквы – не считая свисающих частей букв типа р и у. Можно менять позицию по горизонтали, задавая свойству textAlign значения "end" или "center", а по вертикали – задавая textBaseline "top", "middle", или "bottom".

В конце главы мы вернёмся к нашей диаграмме.

Изображения

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

Метод drawImage позволяет выводить на холст пиксельные данные. Они могут быть взяты из элемента <img> или с другого холста, которые не обязательно видны в самом документе. Следующий пример создаёт элемент <img> и загружает в него файл изображения. Но он не может сразу начать рисовать при помощи этой картинки, потому что браузер мог не успеть её подгрузить. Для этого мы регистрируем обработчик события “load” и рисуем после загрузки.

<canvas></canvas>

<script>

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