Canvas

Canvas (англійською canvas — «полотно») — елемент HTML5, який застосовують для подання графіки, використовуючи скрипти (переважно JavaScript).

Публікація є переказом посібника з canvas англійською мовою. Текст упорядкував Олександр Рудик з метою пристосувати до використання при навчанні у школі. В усіх завданнях, починаючи з другого, аналіз коду передбачає зміну значень властивостей, передбачення результатів цих змін і порівняння передбачення з отриманим. Кожне таке завдання можна доповнити завданням зміни коду з певною метою.


Зміст

  1. Приклад запису коду
  2. Прямокутники й контури
  3. Колір
  4. Властивості лінії
  5. Градієнти
  6. Шаблон
  7. Правила заповнення
  8. Текст
  9. Зовнішні зображення
  10. Нарізання зображень
  11. Збереження й відновлення налаштувань
  12. Перетворення
  13. Відсічний контур
  14. Поєднання фігур
  15. Анімація
  16. Ефект ковзання
  17. Слідування за мишею
  18. Згладжування й масштабування
  19. Правила роботи для підвищення продуктивності
  20. Додаткові ресурси глобальної мережі


1. Приклад запису коду

<canvas id="name" width="400" height="300">

Текст і/або зображення, які:
* буде відображено старими версіями браузерів, що не підтримують canvas;
* не буде відображено новими версіями браузерів, що підтримують canvas.

</canvas>

— з назвою "name" (необов'язковий атрибут), шириною 400 i висотою 300 пікселів. Такий опис потрібно розташувати у відповідній частині коду HTML. Контейнер canvas може не містити нічого. Якщо атрибути висоти й ширини не задано, їм як усталенено буде надано значення 300 й 150 відповідно. Розміри також можна задати в CSS.

Вказівки виведення зображення подають окремим кодом Javascript у контейнері <script>…</script>.

Полотно спочатку порожнє і прозоре. Для отримання контексту унаочнення існує метод getContext, який використовують наприклад, таким чином:

var a = document.getElementById('name');
var b = a.getContext('2d');

Завдання 1. Проаналізувати код сторінки, яку можна використати як заготовку для подальших вправ, і порівняти з очікуваним.

2. Прямокутники й контури

На відміну від SVG, canvas підтримує лише одну примітивну фігуру: прямокутник, сторони якого вертикальні або горизонтальні. Всі інші фігур створюють поєднанням контурів.

Прямокутник з властивостями:

малюють за допомогою таких методів (записувати через крапку після назви контексту, отриманого методом getContext):

Контур малюють за допомогою таких методів:

Завдання 2. Проаналізувати код функції draw сторінки, на якій зображено заповнений трикутник і контур іншого трикутника.

Завдання 3. Проаналізувати код функції draw сторінки, на якій зображено дуги і сегменти.

Завдання 4. Проаналізувати код функції draw сторінок a, b, на якій зображено криві Безьє.

3. Колір

Колір визначають значенням властивостей:

Значення цих властивостей можна задати одним з 4 способів — див. приклад для помаранчевого:

b.fillStyle = "orange";        // color CSS 
b.fillStyle = "#FFA500";
b.fillStyle = "rgb(255,165,0)";
b.fillStyle = "rgba(255,165,0,1)";

— див. перелік назв і кодів. Як усталено колір заповнення й контуру — чорний (#000000).

Примітка. Тут і далі під властивістю розуміють властивість контексту зображення, отриманого методом getContext. В усіх поданих прикладах він має назву b. При зміні значення властивості нове значення стосується лише тих фігур, які буде намальовано надалі до наступної зміни цих значення властивості.

Завдання 5. Проаналізувати код функції draw сторінок, на якій зображено квадрати і кола різного кольору.

Прозорість визначають значенням властивості globalAlpha (дійсне число):

Завдання 6. Проаналізувати код функції draw сторінки, на якій зображено концентричні напівпророзі круги на тлі квадратів різного кольору.

4. Властивості лінії

Ширина лінії визначається значенням властивості lineWidth (ціле число — кількість пікселів).

Завдання 7. Проаналізувати код функції draw
сторінки, на якій зображено вертикальні лінії різної товщини.

Зображення кінців визначається значенням властивості lineCap:

Завдання 8. Проаналізувати код функції draw сторінки, на якій зображено вертикальні лінії з різним закінченням.

Спосіб поєднання ланок ліній, дуг або кривих з ненульовий довжиною задають значенням властивості lineJoin:

Останнє налаштування виконують за допомогою властивості miterLimit, про яку мова йтиме далі.

Для властивості lineJoin значенням як усталено є miter. Налаштування lineJoin не діє, якщо дві ланки мають один і той самий напрямок: у цьому випадку не буде додано область сполучення.

Завдання 9. Проаналізувати код функції draw сторінки, на якій зображено ламані з різним сполученням ланок.

Властивість miterLimit (як усталено значення 10) визначає верхню межу відстані між зовнішньою точкою сполучення і внутрішньою точкою сполучення.

Завдання 10. Проаналізувати код функції draw сторінки для різних значень b.miterLimit, що не перевищують 20.

Пунктирна лінія. Метод setLineDash задає шаблон штрихів для пунктирних ліній на основі отриманого списку цілих чисел, який визначає відстані для почергового рисування лінії і розриву.

Завдання 11. Проаналізувати код функції draw сторінки з різними пунктирними лініями.

5. Градієнти

Градієнти створюють за допомогою методів:

Після створення об’єкта градієнту потрібно вказати кольори за допомогою методу:

addColorStop(позиція, колір):

Вказати кольори можна у довільній кількості позицій додатково до початкової 0 і кінцевої 1.

Завдання 12. Проаналізувати код функції draw сторінок
лінійними і радіальними градієнтами.

6. Шаблон

Шаблон повторення зображень створюють методом createPattern (image, type), що створює і повертає новий об'єкт — шаблон (pattern):

Після створення шаблону можна призначити йому властивості fillStyle або strokeStyle.

Завдання 13. Проаналізувати код функції draw
сторінки з декоративним орнаментом, у створенні якого використано таке зображення.

7. Правила заповнення

Правила заповнення точки області, обмеженою контуром із самоперетинами, визначається значенням індекса точки відносно кривої-контурна:

Індекс точки відносно замкненого контураце кількість обертів вектора з початком у даній точці при однократному русі кінця вектора вздовж цього контура.

Завдання 14. Проаналізувати код функції draw
сторінки, що містить два однакові контури з різними правилами заповнення.

8. Текст

Виведення тексту в точку (x, y) — при бажанні можна вказати максимальну ширину:

Cтиль тексту задають значенням таких властивостей:

Ці властивості мають бути знайомі тим, хто має досвід роботи з CSS.

Тінь формують наданням значень таким властивостям:

Значення перших трьох з цих властивостей задають десятковим дробом. Від'ємні значення shadowOffsetX і shadowOffsetY використовують, щоб спричинити розширення тіні вгору чи вліво, а додатні — щоб тінь поширити вниз або вправо.

Завдання 15. Проаналізувати код функції draw
сторінки, що містить текст з тінню.

Вимірювання тексту (без вмалювання його на canvas) здійснюють методом measureText, що повертає об'єкт TextMetrics, що містить ширину тексту у пікселах, якщо його буде виведено в canvas.

Завдання 16. Проаналізувати код функції draw сторінки, що містить вимірювання довжини тексту.

9. Зовнішні зображення

Canvas надає можливість використати зовнішні зображення у будь-яких підтримуваних браузером форматах (PNG, GIF, або JPEG) чи навіть зображення, створене іншими елементами canvas на тій самій сторінці як джерело. Імпорт зображень у canvas складається з 2 етапів:

Джерело зображення Canvas (тип CanvasImageSource) може мати один з таких типів даних:

  • HTMLImageElement — зображення, створене конструктором Image (як елементи <img>);
  • HTMLVideoElement — поточний кадр елементу <video>;
  • HTMLCanvasElement — інший елемент <canvas>.

Cпособи отримання зображень для використання на полотні

  • Використання зображень з тієї самої сторінки:
    • колекція document.images;
    • метод document.getElementsByTagName;
    • метод document.getElementById.
  • Використання зображень з інших доменів. Використавши атрибут crossОrigin елемента <img>, можна запросити дозвіл на завантаження з іншого домену для використання в drawImage.

  • Використання інших елементів canvas. Як і для звичайних зображень, можна отримати доступ до інших елементів canvas, використовуючи або метод document.getElementsByTagName, або метод document.getElementById.

  • Створення зображень з нуля з використанням конструктора Image. При спробі викликати функцію drawImage перед тим як зображення завантажиться, скрипт нічого не зробить (у давніх браузерах, може навіть видати виняток). Тому необхідно використовувати подію load, наприклад, таким чином:

    var img = new Image (); // Створює нове зображення
    img.addEventListener
    ( "load",
      function () {// тут використати функцію drawImage
                  },
      False
    );
    img.src = 'myImage.png'; // Встановити джерело файлу

    Якщо використано лише одне стороннє зображення, то такий підхід прийнятний. Але якщо потрібно стежити за кількома зображеннями, то необхідно придумати щось краще.

  • Вкладення зображення за допомогою даних URL дозволяє повністю визначити зображення як Base64 кодований рядок символів прямо у код.

    var img = new Image (); // Створення нового елемента img
    img.src = 'data: image / gif; base64, R0lGODlhCwALAIAAAAAA3pn / ZiH5BAEAAAEALAAAAAALAAsAAAIUhA + hkcuO4lmNVindo7qyrIXiGBYAOw ==';

    Перевагою такого вкладення є отримання зображення відразу без інших запитів на сервер. Інша потенційна перевага полягає у тому, що так можна інкапсулювати в одному файлі все щодо CSS, JavaScript, HTML і зображень. Але зображення у цьому випадку не кешовано. Для зображень з великим розміром кодування url може стати дуже довгим процесом.

  • Використання кадрів з відео.

Метод drawImage можна використати таким чином: drawImage(image,x,y);

Завдання 17. Проаналізувати код функції draw
сторінки, на якій фото вибуху ядерної бомби перекреслено двома намальованими лініями червоного кольору.

Зміна розмірів. Інший варіант застосування методу drawImage має два додаткові параметри розміри — ширина й висота прямокутника, який буде заповнено зображенням:

drawImage (image, x, y, width, height):

Завдання 18. Проаналізувати код функції draw сторінки, на якій фото дрофи розміру 236×214 пікселів,

зменшене у 4 рази до розміру 50×38 пікселів, використано для створення шпалер.

Примітка При істотному збільшенні або зменшенні зображень растрової графіки якість відображення може стати неприйнятною. Краще за все взагалі не змінювати розміри зображення, якщо на ньому є текст, який потрібно залишити читаним.

10. Нарізання зображень

У третього і найповнішого за переліком можливостей варіанту методу drawImage крім джерела зображення є ще 8 параметрів, що описують вирізання шматка зображення, зміну його розміру й малюння:

drawImage(image, sx, sy, sW, sH, dx, dy, dW, dH);

Ця функція бере частину зображення у вигляді прямокутника, лівий верхній кут якого має координати (sx, sy), ширина і висота — sW і sH і малює в полотно canvas, розташовуючи верхній лівий його кут у точці (dx, dy) і змінюючи його розмір на значення dW і dH.

Таким чином, перші 4 параметри визначають місце розташування і розмір фрагмента вихідного зображення. Останні 4 параметри визначають прямокутник, в який буде вписано зображення на малюнку canvas.

Можна зібрати всі елементи в одному файлі зображення і використовувати нарізання для створення композиції. При цьому немає потреби завантажувати кожне зображення окремо, що може збільшити швидкість завантаження. сторінки.

Завдання 19. Проаналізувати код функції draw
сторінки, у якому частину фото дрофи подано у рамці.

В останньому коді застосовано інший спосіб завантаження зображення: замість створення нових об'єктів HTMLImageElement зображення включено як теги img безпосередньо у сторінку HTML. Зображення приховано за допомогою CSS властивості display зі значенням "none".

Завдання 20. Проаналізувати код функції draw сторінки, який подає невелику галерею, втілену таблицею з 4 зображень:

Після завантаження сторінки, елемент canvas буде вставлено перед кожним зображенням, відмінним від рамки, а навколо буде намальовано рамку.

При переборі елементів document.images додають нові елементи canvas. Для цього використано метод insertBefore батьківського вузла елемента таблиці (зображення).

11. Збереження й відновлення налаштувань

Збереження налаштувань полотна методом save і відновлення збережених налаштувань методом restore — корисні інструменти створення складних зображень. Налаштування полотна зберігає стек: першим буде відновлено те, що було збережено останнім. До цих збережуваних і відновлюваних налаштувань належать такі:

Метод save можна викликати довільну кількість разів. При виклику методу restore останній збережений стан буде зчитано зі стеку, а всі збережені налаштування буде відновлено.

Завдання 21. Проаналізувати код функції draw
сторінки, що малює вкладені прямокутники.

12. Перетворення

Паралельне перенесення полотна на x пікселів по горизонталі і на y пікселів по звертикалі здійснюють за допомогою метода

translate(x,y)

Завдання 22. Проаналізувати код функції draw
сторінки, що містить два вкладених цикли. Після кожного перенесення й малювання заповненого прямокутника полотно повертають до початкового стану методом restore. Зауважимо: виклик fillRect використовує одні й ті самі координати, спираючись попередньо застосоване паралельне перенесення.

Обертання полотна на кут angle (у радіанах) навколо точки (0, 0) здійснюють за допомогою метода

rotate(angle)

Завдання 23. Проаналізувати код функції draw сторінки, на якій використано обертання навколо двох різних точок: початку координат (0,0) і цетра прямокутника червоного кольору.

Масштабування використовують для збільшення або зменшення одиниць довжини системи координат на полотні. Для використовують метод

scale(x,y)

Тут x — множник для довжини по горизонталі, у — множник для довжини по y вертикалі. Обидва параметри — дійсні числа. Використовуючи від’ємні числа, можнае отримати дзеркальне відображення осі. Наприклад, послідовне застосування методів:

translate (0, canvas.height);
scale(1, -1);

дозволяє використовувати на полотні координати традиційної декартової системи координат з початком у нижньому лівому куті.

Завдання 24. Проаналізувати код функції draw сторінки, на якій масштабуванням розтягнуто квадрат у прямокутник і дзеркально відображено слово «читай».

Метод transform(a, b, c, d, e, f) задає лінійне перетворення координат і має таке тлумачення параметрів:

Він множить поточну матрицю перетворення на таку матрицю:

ace
bdf
001

Як усталено матриця перетворення дорівнює одиничній: 1 — на головній діагоналі, решта елементів дорівнюють 0:

100
010
001

Метод setTransform (a, b, c, d, e, f) (з тими самими аргументами) задає поточне перетворення одиничною матрицею, а потім викликає метод transform з тими самими аргументами. Інакше кажучи, скасовує поточне перетворення, після чого встановлює задане перетворення — все однією вказівкою.

Завдання 25. Проаналізувати код функції draw сторінки з урахуванням того, що матриця лінійного перетворення координат при повороті на кут φ має такий вигляд.

cos φsin φ
− sin φcos φ

Метод resetTransform() задає поточне перетворення одиничною матрицею, тобто еквівалентний дії методу setTransform(1,0,0,1,0,0).

13. Відсічний контур

Відсічний контур діє як маска для приховування небажаних частин фігур. Все, що лежить зовні цього контуру, не буде намальовано на полотні. Такий контур створюють за допомогою методу clip, що працює зі шляхами так само, як розглянуті вище методи stroke і fill. Але з такою відмінністю: clip використовують замість closePath, щоб закрити шлях і перетворити його на відсічний контур замість того, щоб обвести контур або заповнити внутрішню область. Як усталено елемент canvas має відсічний контур такого самого розміру, як і саме полотно.

Завдання 26. Проаналізувати код функції draw
сторінки з відсічним контуром у вигляді кола, всередині якого зображено випадково розташовані зірки.

14. Поєднання фігур

Поєднання (компонування, змішування) фігур задають значенням властивості globalCompositeOperation.

Завдання 27. Проаналізувати код функції draw
сторінки, що показує поєднання квадратів червоного і зеленого кольорів при різних значеннях globalCompositeOperation при умові, що першим буде зображено квадрат червоного кольору. Дати словесний опис результату поєднання для кожного значення властивості globalCompositeOperation.

15. Анімація

Створення анімації на полотні canvas має істотне обмеження: коли фігура намальована, її не можна рухати. Щоб зобразити рух, потрібно перемалювати фігуру. Перемальовування складних кадрів займає багато часу, тому результат відтворення істотно залежить від швидкодії комп'ютера.

Необхідні кроки створення нового кадру

  1. Очистити canvas. Якщо анімована фігура не займає все полотно (як, наприклад, тло), то все намальоване раніше необхідно стерти. Частот це найпростіше зробити за допомогою методу clearRect.

  2. Зберегти початковий стан canvas. Якщо змінюють будь-які налаштування canvas (стилі, трансформації тощо), а при перемалюванні починати потрібно з деякого початкового налаштування, то потрібно зробити і зберегти це початкове налаштування.

  3. Намалювати анімовані фігури.

  4. Відновити стан canvas до того, як малювати наступний кадр.

Для створення анімації необхідним є спосіб виконання функцій відтворення через певні інтервали часу.

Заплановані оновлення передбачають використання таких вказівок:

Якщо не заплановано жодної взаємодії з користувачем, можна використати setInterval. Якщо контроль анімації здійснюють мишею або клавіатурою (наприклад, у грі), то необхідно використовувати setTimeout. Встановивши EventListener, можна перехопити будь-які дії користувача і відповідним чином змінити анімацію.

У прикладах буде використано вказівку window.requestAnimationFrame для контролю анімації. Вона здійснює нову ітерацію, коли система готова до малювання нового кадру. Кількість викликів на секунду приблизно дорівнює 60 і зменшується, коли вкладення неактивне. Для детальнішого вивчення циклу анімації, особливо для ігор, радимо прочитати
статтю «Анатомія відеоігор» (англійською).

Завдання 28. Проаналізувати код сторінки, що моделює рух Землі й Місяця навколо Сонця (без збереження масштабу), використовуючи такі зображення:

Модифікувати код, використавши матеріали розробки, для моделювання сонячної системи. Тінь не відображати. Використати масиви і вкладені цикли з метою економії коду.

Завдання 29. Проаналізувати код сторінки, що відображає рух стрілок годинника. Модифікувати код з метою прискорення руху у довільну кількість разів (значення задавати на початку коду Javascript).

16. Ефект ковзання

Завдання 30. Проаналізувати код
сторінки, що моделює рух кульки при пружних ударах від пари паралельних вертикальних площин і пари паралельних горизонтальних площин. Рух розпочинається після наведення вказівника миші на зображення кулі зеленого кольору. З метою отримати ефект ковзання, закоментувати першу вказівку функції draw:

b.clearRect(0,0, canvas.width, canvas.height);

і зняти коментар з наступних двох рядків, що містять такі вказівки:

b.fillStyle = 'rgba(255, 255, 255, 0.3)';
b.fillRect(0, 0, canvas.width, canvas.height);

17. Слідування за мишею

Завдання 31. Проаналізувати код
сторінки, що зображує з ефектом ковзання рух кульки при пружних ударах від пари паралельних вертикальних площин і пари паралельних горизонтальних площин. У початковий момент зображення кульки — круг зеленого кольору — рухається за вказівником миші. Після клацання лівою кнопкою миші круг звільняється з нульовою початковою швидкістю. Після повернення вказівника із-за меж полотна зелений круг знову слідує за вказівником. Змінити код таким чином, щоб круг починав рух з випадковою ненульовою швидкістю.

Охочі заглибитися у розробку ігор на основі розширеної анімації можуть ознайомитися з публікацією «Game development» (англійською мовою).

18. Згладжування й масштабування

Зміна розмірів зображень може призвести до розмитості або до шуму. Є можливість використовувати властивості imageSmoothingEnabled (контексту малювання), щоб контролювати використання алгоритму згладжування при зміні розмірів зображення. Як усталено ця властивість має значення true, що означає згладжування зображення під час зміни розмірів. Згладжування можна вимкнути таким чином:

b.mozImageSmoothingEnabled    = false;
b.webkitImageSmoothingEnabled = false;
b.msImageSmoothingEnabled     = false;
b.imageSmoothingEnabled       = false;

За допомогою методу drawImage, другого полотна і властивості imageSmoothingEnabled можна збільшити зображення й роздивитися його детальніше.

Завдання 32. Проаналізувати код
сторінки, на якій розташування вказівника миші на полотні із зображенням птаха дрофи взято за лівий верхній кут квадрату розміру 40×40, який буде відображено на іншому полотні розміру 200×200 із збільшенням у 5 разів. Як усталено включено згладжування. Можна зняти прапорець, щоб побачити ефект властивості imageSmoothingEnabled, якому потрібні префікси для різних браузерів.

19. Правила роботи для підвищення продуктивності

20. Додаткові ресурси глобальної мережі