Элемент <canvas>
, представленный в HTML5, позволяет разработчикам динамически создавать графические изображения с использованием JavaScript. В этом руководстве вы узнаете о некоторых основных операциях, поддерживаемых элементом <canvas>
и создадите простую анимацию с использованием JavaScript.
Canvas был впервые представлен Apple в 2004 году для использования в Mac OS X и Safari. Теперь это было принято каждым главным браузером. Текущие версии Mozilla Firefox, Chrome, Opera, Safari и IE 9 и 10 поддерживают элемент <canvas>
.
Как использовать холст
Следующий код добавляет элемент <canvas>
.
<canvas id="canvasDemo" height="400" width="300"> Sorry, your browser does not support canvas. </canvas>
Атрибут id
используется для доступа к элементу <canvas>
из JavaScript. Атрибуты height
и width
используются для определения размера холста. Все, что вы пишете внутри <canvas>
, появится, если браузер не поддерживает холсты. Это действует как запасной вариант для старых браузеров. Из JavaScript мы можем получить доступ к элементу <canvas>
как показано ниже.
var canvas=document.getElementById("canvasDemo"); var context=canvas.getContext("2d");
В следующем примере показано, как нарисовать линию на холсте. Код рисует прямую линию от координаты (30, 40) до (145, 120), причем верхний левый угол холста выступает в качестве координаты (0, 0). Следует отметить, что элементы <canvas>
не поддерживают DOM. В результате, если вы хотите что-то изменить на холсте, вам, вероятно, придется перерисовать все это.
var canvas=document.getElementById("canvasDemo"); var context=canvas.getContext("2d"); context.strokeStyle="green"; context.moveTo(30,40); context.lineTo(145,120); context.stroke();
Модифицированный холст показан на следующем рисунке.
Рисование основных фигур
Прежде чем перейти к анимации, вам необходимо понять основные формы, которые можно нарисовать на холсте. Нам понадобятся эти основные формы каждый раз, когда мы хотим что-то создать. Давайте начнем со следующих операций, связанных с прямоугольниками.
-
fillRect(x,y,width,height);
-
clearRect(x,y,width,height);
-
strokeRect(x,y,width,height);
Первые два параметра каждой функции представляют собой координаты верхнего левого угла прямоугольника. Следующие два параметра определяют ширину и высоту прямоугольника. Рассмотрим следующий фрагмент JavaScript:
var context=document.getElementById("canvasDemo").getContext("2d"); context.strokeStyle="green"; context.fillStyle="red"; context.strokeRect(70,70,80,80); context.fillRect(80,80,60,60); context.clearRect(95,95,30,30);
Он производит следующий вывод:
Как видите, метод fillRect()
создает прямоугольник и заполняет его цветом, указанным свойством context.fillStyle
. clearRect()
очищает прямоугольную часть от холста, а strokeRect()
рисует прямоугольный контур, цвет которого определяется свойством context.strokeStyle
.
Рисование линий
Линии могут быть нарисованы с помощью функции lineTo()
. Метод принимает два параметра, которые представляют координаты конечной точки. Чтобы нарисовать линию, вам нужно сначала вызвать moveTo()
, которая представляет начальную точку линии. Первый пример в этой статье рисует линию таким образом.
Рисование дуг
Дуга рисуется с использованием функции arc()
, показанной ниже.
arc(x,y,radius,startAngle,endAngle,direction);
Первые два параметра представляют координату центра. startAngle
представляет начальный угол для дуги. Чтобы создать круг, установите это в ноль. endAngle
определяет угол, под которым заканчивается дуга. Рисуя круг, вы установите его на 360 градусов. Для полукруга это должно быть 180 градусов. Обратите внимание, что углы должны быть указаны в радианах. Поэтому вы должны использовать константу Math.PI для конвертации из градусов. Наконец, параметр direction
указывает, должна ли дуга быть нарисована по часовой стрелке или против часовой стрелки.
Рассмотрим следующий фрагмент:
var ctx = document.getElementById('canvasDemo').getContext('2d'); ctx.arc(180,180,70,0,Math.PI,true); ctx.stroke();
Это производит следующий вывод.
Однако, если вы хотите изменить направление на по часовой стрелке, вам нужно вызвать arc()
с последним аргументом, установленным в false
. Это приводит к следующему выводу.
Рисование контуров
Обычно путь состоит из нескольких фигур. Каждый путь внутренне представлен списком вспомогательных путей, таких как прямоугольники, линии или дуги. Пути могут быть нарисованы с использованием следующих функций.
-
beginPath()
-
closePath()
-
stroke()
-
fill()
Каждый путь содержит список подпутей. Когда beginPath()
этот список сбрасывается, и мы можем начать рисовать различные фигуры для пути. В следующем примере показаны функции пути в действии.
var ctx = document.getElementById("canvasDemo").getContext("2d"); ctx.beginPath(); ctx.arc(180,180,70,0,Math.PI*2,true); ctx.moveTo(230,180); ctx.arc(180,180,50,0,Math.PI,false); ctx.moveTo(155,150); ctx.arc(150,150,5,0,Math.PI*2,true); ctx.moveTo(215,150); ctx.arc(210,150,5,0,Math.PI*2,true); ctx.fillText("Happy", 165, 270); ctx.stroke();
Полученный холст показан ниже.
Рисование изображений
Рисовать изображение на холсте довольно просто. Вы можете создать объект Image
и нарисовать его на холсте, как показано ниже.
var ctx = document.getElementById("canvasDemo").getContext("2d"); var img =new Image(); img.onload=function(){ ctx.drawImage(img,15,25); } img.src="myImg.png";
Другой способ — добавить изображение в документ и сделать его невидимым. В JavaScript мы можем получить к нему доступ по id
и нарисовать его, как показано ниже.
var ctx = document.getElementById("canvasDemo").getContext("2d"); var img = document.getElementById("myimage"); ctx.drawImage(img,0,0);
Полное руководство по рисованию основных фигур вы можете найти в документации по Mozilla Developer Network.
Создание приложения для прыгающего мяча
В этом примере будет создано приложение, содержащее прыгающий мяч. Вам нужно поймать мяч веслом, когда он достигнет нижней части экрана. Мы будем использовать функцию setTimeout()
для создания анимации. Мы уже знаем, что все, что вы рисуете на холсте, сохраняется до тех пор, пока вы его не очистите. Таким образом, для перемещения объекта по холсту вам необходимо периодически вызывать функцию, которая очищает холст и обновляет положение объекта.
В нашем случае пользовательская функция draw()
будет вызываться каждые десять миллисекунд. Это очистит весь холст и обновит координаты x
и y
шара. Это дает иллюзию, что мяч движется непрерывно.
Поместите следующий код JavaScript в файл с именем bouncingball.js
.
var canvas; var ctx; var dx = 1; var dy = 2; var bar=new Bar(400,500); var circle=new Circle(400,30,10); var dxBar=6; var timer; var barImg; function Bar(x,y){ this.x=x; this.y=y; } function Circle(x,y,r){ this.x=x; this.y=y; this.r=r; } function drawBall(c) { ctx.beginPath(); ctx.arc(cx, cy, cr, 0, Math.PI*2, true); ctx.fill(); } function doKeyDown(e){ if(e.keyCode==37){ if(bar.x-dxBar>0) bar.x-=dxBar; } else if(e.keyCode==39){ if(bar.x+dxBar<canvas.width) bar.x+=dxBar; } } function init() { window.addEventListener("keydown",doKeyDown,false); barImg=document.getElementById("bar"); canvas = document.getElementById("canvas"); ctx = canvas.getContext("2d"); timer=setInterval(draw, 10); return timer; } function draw() { ctx.clearRect(0, 0, canvas.width, canvas.height); ctx.fillStyle = "#FAF7F8"; ctx.fillRect(0,0,canvas.width,canvas.height); ctx.fillStyle = "#003300"; drawBall(circle); if (circle.x +dx > canvas.width || circle.x +dx < 0) dx=-dx; if(circle.y+dy>bar.y && circle.x>bar.x && circle.x<bar.x+barImg.width) dy=-dy; if (circle.y +dy > canvas.height || circle.y +dy < 0) dy=-dy; circle.x += dx; circle.y += dy; ctx.drawImage(barImg,bar.x,bar.y); if(circle.y>bar.y){ clearTimeout(timer); ctx.clearRect(0, 0, canvas.width, canvas.height); alert("Game Over"); } }
HTML-документ, содержащий код JavaScript, показан ниже.
<!doctype html> <html> <head> <title>Canvas Demo</title> <script type="text/javascript" src="bouncingball.js"/> </head> <body onload="init();"> <div> <canvas id="canvas" width="800" height="600"> Sorry, browser does not support canvas. </canvas> </div> <img src="bar.png" id="bar" style="display:none"/> </body> </html>
Вы можете попробовать игру через онлайн-демо . Обратите внимание, что в этой игре можно сделать несколько оптимизаций и улучшений. Сначала мы начнем с определения двух объектов, ball
и bar
. Панель может отражать шар, когда он достигает нижней части экрана. Переменные dx
и dy
определяют, насколько быстро шар движется вдоль оси x и оси y соответственно. dxBar
представляет скорость перемещения полосы вдоль оси x.
Функция init()
вызывается при загрузке тела. Затем мы регистрируем прослушиватель событий, который прослушивает события keydown
. Если пользователь нажимает стрелку влево, мы dxBar
значение x
dxBar
влево на dxBar
пикселей. Если пользователь нажимает стрелку вправо, мы сдвигаем панель вправо.
Затем мы инициализируем холст и получаем 2D-контекст, который инициализирует переменную ctx
. После этого мы регистрируем функцию draw()
с помощью setTimeout()
чтобы она setTimeout()
каждые десять миллисекунд.
Каждый раз, когда выполняется draw()
, мы очищаем холст и рисуем обновленный шар и полосу. Внутри функции мы проверяем, не сталкивается ли шар с перекладиной. Если это так, мяч отскакивает назад. Если мяч выходит за пределы экрана, холст очищается и анимация останавливается, завершая игру.
Куда пойти отсюда
Если вы заинтересованы в улучшении игры, ознакомьтесь с руководством по оптимизации холстов . Вы также можете использовать requestAnimationFrame () для выполнения анимации. Он инструктирует браузер запланировать перерисовку окна, чтобы можно было визуализировать следующий кадр анимации. К сожалению, это экспериментальная технология, и ее спецификация еще не стабилизировалась. Вы также должны узнать о различных преобразованиях, которые можно выполнить на холсте, и проверить несколько анимаций в MDN.