CSS властивості
ГлавнаяCanvasОснови малювання в Canvas

Основи малювання в Canvas

205

Canvas — API для малювання, нещодавно доданий до HTML і підтримується більшістю браузерів (навіть Internet Explorer 9). Canvas дозволяє малювати все, що ви хочете прямо в браузері без використання плагінів, як Flash або Java. Canvas з його оманливо простим API може революційно перетворити створення веб-застосунків для всіх пристроїв, а не тільки десктопних.

Ці скріншоти дозволять вам відчути смак можливостей Canvas.

Що таке Canvas?

Canvas — API для двовимірного малювання. Насправді браузер дає вам прямокутну область на екрані, в якій ви можете малювати лінії, фігури, зображення, текст, практично все що хочете. Canvas спочатку був створений Apple для їх віджетів, але з тих пір був прийнятий усіма розробниками основних браузерів, і тепер Canvas є частиною специфікації HTML5. Ось невеликий приклад, який виглядає певний код Canvas:

<html>
<body> <canvas width="800" height="600" id="canvas"></canvas> <script> var canvas=document.getElementById('canvas'); var c=canvas.getContext('2d'); c.fillStyle="red"; c.fillRect(100,100,400,300);
</script>
</body>
</html>

Простий червоний прямокутник

Простий червоний прямокутник

Цей прямокутник намальований функцією context.fillRect().

Важливо розуміти, що Canvas призначений для малювання пікселів. У ньому немає фігур чи векторів. Немає об'єктів зв'язування з обробниками подій. Це просто малюнки пікселів на екрані. Як ми ще побачимо в цьому і сила і слабкість.

Як це пов'язано з іншими веб-технологіями?

Є чотири способи намалювати щось на веб-сторінці: Canvas, SVG, CSS та пряма анімація через DOM. Canvas містить відмінності від інших трьох.

SVG — це API для малювання векторних фігур. Кожна фігура є об'єктом, який ви можете пов'язати з обробниками подій. При масштабуванні фігури залишаються згладженими, у той час як у Canvas помітні пікселі. Оскільки DOM не містить жодних об'єктів, які малюються в Canvas, ви не можете використовувати CSS для їх стилізації. CSS впливатиме лише на прямокутну площу самого Canvas, так що ви можете встановити межі, колір фону і на цьому все.

Анімація через DOM: DOM або Document Object Model документа) визначає кожний об'єкт на екрані. Анімація за допомогою CSS або JavaScript для пересування об'єктів в деяких випадках може бути більш плавною, ніж зроблена Canvas, але це залежить від реалізації вашого браузера.

Що? Де? Коли?

Отже, коли слід використовувати Canvas замість SVG, CSS або елементів DOM? Ну, Canvas за рівнем нижче, ніж інші, так що у вас більше контролю над малюванням і витрачається менше пам'яті, але натомість потрібно писати більше коду. Використовуйте SVG, коли у вас є фігури, які ви хочете відобразити на екрані, як на карті, зробленій в Adobe Illustrator. Використовуйте CSS або DOM-анімацію, коли ви маєте великі статичні області, які ви хочете анімувати або бажаєте використовувати тривимірні перетворення. Для схем, графіків, динамічних діаграм і, звичайно, відеоігор, Canvas — найкращий вибір. Надалі ми обговоримо кілька бібліотек, які дозволяють робити вам більше штук, орієнтованих на вектори та об'єкти, використовуючи Canvas.

Перш ніж рухатися далі, хочу пояснити, що коли я говорю про Canvas, то маю на увазі двовимірний API. Також існує тривимірний API у роботах званих WebGL. Я не збираюся розповідати про нього, тому що він все ще знаходиться в розробці і браузери підтримують його досить погано. Також цей по суті OpenGL від JavaScript знаходиться на нижчому рівні, ніж Canvas і набагато складніше у використанні. Коли WebGL стане більш зрілим, ми повернемось до нього в наступних розділах. Ви можете використовувати його. На щастя Canvas тепер стабільний API і більшість сучасних браузерів підтримують його в деякій мірі. Підтримує навіть Internet Explorer починаючи з версії 9 і дуже добре.

9 10 9 3 4

Більшість мобільних платформ підтримують Canvas, тому що в основному вони засновані на WebKit, який вже давно має хорошу підтримку. Я знаю, що підтримує WebOS, iOS, Android. Вважаю, що BlackBerry теж принаймні на PlayBook. Windows Phone 7 не підтримує, але це може змінитися в майбутньому оновленні.

iOS webOS Android BlackBerry Windows Phone 7
все все 2 PlayBook та OS 6.0

Поки не всі мобільні пристрої містять повну або швидку підтримку Canvas, тому пізніше ми розглянемо, як оптимізувати наш код для мобільних пристроїв.

Просте малювання

Як я вже говорив раніше, Canvas — це просто API. Якщо ви вже робили роботу з програмуванням на Flash або Java 2D, це має здатися досить знайомим. Ви отримуєте вказівник на графічний контекст, встановлюєте деякі властивості, такі як колір поточної заливки або контуру, а потім малюєте кілька фігур. Ось деякі приклади.

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

<code data-language="javascript">ctx.fillStyle="red"; //x, y, ширина, висота ctx.fillRect(<b id="simplerect_var1">20</b>,<b id="simplerect_var2">30</b>,<b id="simplerect_var3">40 </b>,<b id="simplerect_var4">50</b>);

Ось ще один.

<code data-language="javascript">c.fillStyle='#ccddff'; c.beginPath(); c.moveTo(50,20); c.lineTo(200,50); c.lineTo(<b id="simple_triangle_var1">150</b>,<b id="simple_triangle_var2">80</b>); c.closePath(); c.fill(); c.strokeStyle='rgb(0,128,0)'; c.lineWidth=<b id="simple_triangle_var3">5</b>; c.stroke();

У цьому прикладі ми встановлюємо поточний колір заливки, створюємо контур, а потім заливаємо та обводимо його. Слід зазначити, що контекст відстежує колір заливки та колір обведення окремо. Також зверніть увагу на різні форми вказівки кольору. fillStyle і strokeStyle може бути будь-яким коректним кольором із CSS, таким як шістнадцятковим, назвою або функцією rgb().

Контури

Canvas безпосередньо підтримує тільки прямокутник. Щоб намалювати будь-яку іншу фігуру, необхідно зробити це самостійно за допомогою контурів. Контури це фігури, створені купою прямих чи вигнутих відрізків ліній. У Canvas потрібно спочатку визначити контур через beginPath(), потім залити його або використовувати як маску. Ви визначаєте кожен відрізок такими функціями як moveTo(), lineTo() та bezierCurveTo() . У цьому прикладі фігура малюється за допомогою moveTo(), потім йде крива Безьє та кілька ліній. Після створення контуру він заливається і обводиться.

c.fillStyle='red'; c.beginPath(); c.moveTo(10,30); c.bezierCurveTo(50,90,159,-30,200,30); c.lineTo(200,90); c.lineTo(10,90); c.closePath(); c.fill(); c.lineWidth=4; c.strokeStyle='black'; c.stroke();

Система координат

Пара слів про систему координат. Canvas веде відлік від верхнього лівого кута з віссю у, яка веде вниз. Це традиційно для комп'ютерної графіки, але якщо ви хочете вказати іншу точку відліку, то можете зробити це через трансформацію, про яку ми розповімо пізніше. Ще одна важлива річ — специфікація визначає координати у лівому верхньому кутку пікселя. Це означає, що якщо ви малюєте вертикальну лінію шириною один піксель, починаючи з 5.0, то насправді це охоплює половину сусідніх пікселів (від 4.5 до 5.5). Щоб обійти це, змістіть ваші координати по осі х на 0.5. Тоді це дасть вам лінію, яка йде від 5.0 до 6.0. В якості альтернативи ви можете використовувати ширину лінії, вказавши 2 або 4.

Система координат

Зображення

Canvas може виводити зображення через функцію drawImage.

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

<code data-language="javascript">ctx.drawImage(img, 0,0); //normal drawing ctx.drawImage(img, //draw stretched 0,0,66,66, //source (x,y,w,h) 100,0,<b id="imagedemo_var1">103</b>,<b id="imagedemo_var2">100</b>//destination (x,y,w,h)); ctx.drawImage(img, //draw a slice<b id="imagedemo_s1">20</b>,<b id="imagedemo_s2">10</b>,<b id="imagedemo_s3">20</b>,<b id="imagedemo_s4">20</b>, //source coords (x,y,w,h) 250,0,250,50//destination coords (x,y,w,h)); 

Спробуйте змінити змінні, щоб побачити, як працює розтяг та обрізка. Щоб розтягнути зображення, ви повинні вказати вихідні та кінцеві координати. Вихідні координати кажуть drawImage які пікселі взяти із зображення. Оскільки малюнок вище має розміри 67x67 пікселів, то використовуючи 0,0,66,66, ми відобразимо зображення повністю. Кінцеві координати кажуть drawImage куди помістити пікселі на екрані. Змінюючи значення w і h, можна розтягнути та стиснути зображення.

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

Текст

Canvas також може малювати текст. Атрибути шрифту такі ж, як і в аналогі CSS, так що ви можете встановити стиль, розмір та сімейство шрифту. Зверніть увагу, що функція fillText(рядок,x,y) використовує базову лінію тексту, а не верхній край. Якщо ви помістите текст в 0,0, то він намалюється за межами верхньої частини екрана. Так що опустіть y на відповідне значення.

<code data-language="javascript">ctx.fillStyle="black"; ctx.font="італійський" 96</b>+"pt Arial "; ctx.fillText("this is text", <b id="textdemo_var2">20</b>,<b id="textdemo_var3">150</b>);

Градієнти

Canvas може заливати фігури градієнтом замість кольору. Ось лінійний градієнт:

<code data-language="javascript">var grad=ctx.createLinearGradient(0,0,<b id="graddemo1_var1">200</b>,<b id="graddemo1_var2">0</b>); grad.addColorStop(0, "white"); grad.addColorStop(0.5, "red"); grad.addColorStop(1, "black"); ctx.fillStyle=grad; ctx.fillRect(0,0,400,200);

Важливо відзначити, що градієнт зафарбовується в тій самій системі координат, якою малюється фігура, а не внутрішніх координат фігури. У цьому прикладі фігура малюється в 0,0. Якщо ми змінимо фігуру на 100,100, то градієнт, як і раніше, перебуватиме на початку екрана, так що виявиться менше градієнта, на зразок цього:

<code data-language="javascript">var grad=ctx.createLinearGradient(0,0,<b id="graddemo2_var1">200</b>,<b id="graddemo2_var2">0</b>); grad.addColorStop(0, "white"); grad.addColorStop(0.5, "red"); grad.addColorStop(1, "black"); ctx.fillStyle=grad; ctx.fillRect(100,100,400,200);

Отже, якщо ви вважаєте, що заливаєте фігуру градієнтом, але бачите єдиний колір, то це може бути тому, що ваші координати вимкнені.

Ось і всі основи малювання. Давайте зупинимося на досягнутому та виконаємо кілька вправ у наступному розділі. У вас вже має бути встановлений браузер і текстовий редактор. Я рекомендую використовувати Chrome, оскільки він містить хороші інструменти налагодження та jEdit, тому що він безкоштовний і крос-платформний.Але ви можете використовувати браузер і редактор на свій розсуд.