Читайте также:
|
|
Рассмотрим отображение 2д элементов на странице. Для работы с графикой используется элемент canvas. Элемент canvas впервые предложен корпорацией Apple в 2004 году, и использовался для создания дополнений к браузеру. На сегодняшний день canvas поддерживается во всех основных браузерах (Рисунок 3.1)
Рисунок 3.1 – Поддержка элемента canvas браузерами
Для встраивания элемента используется тег <canvas>…</canvas>, он рассматривается браузером, и имеет такие же параметры, что и любой другой блочный элемент.
Для работы с данным элементом используется язык JavaScript. Для проверки поддержки используется следующий код:
canvas = document.getElementById('canvas');
if (canvas.getContext)
{
//Canvas поддерживается
}
else
{
//Canvas не поддерживается
}
Все объекты, рисуемые на canvas, отрисовываются на объекте RenderingContext. Для получения доступа к нему вызывается функция getContext('2d'), у элемента. Никакие другие параметры, кроме 2d пока не предусмотрены, однако в будущем это может измениться. Далее все рассматриваемые методы и параметры вызываются у объекта context, если не указано другое.
Создание примитивов на элементе требует выполнения ряда операций:
- сообщить, что начинается отрисовка;
- нарисовать фигуры;
- сообщить, что отрисовка завершена и нужно отобразить нарисованные элементы.
Для этого используются функции:
- beginPath() – сообщает о начале отрисовки;
- moveTo(x, y) – перемещает перо в указанную точку холста;
- lineTo(x, y) – перемещает перо в указанную точку холста, и рисует прямую линию;
- strokeRect(x, y, width, height) – отображает прямоугольник с заданной шириной, высотой в заданной точке;
- stroke() – отображает нарисованные элементы.
Таким образом, для отображения линии, необходимо указать следующй код:
canvas = document.getElementById('canvas');
if (canvas.getContext)
{
var context = canvas.getContext('2d');
context.beginPath();
context.moveTo(10, 20);
context.lineTo(150, 100);
context.stroke();
}
else
{
alert('Canvas is not supported');
}
Результат работы данного кода изображён на рисунке 3.2
Рисунок 3.2 – Результат отображения кода
Также, canvas поддерживает работу с кривыми линиями. Поддерживаются следующие кривые:
- кривая Безье. Строится с помощью функции bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y). cpx1, cpy1 – координаты первой контрольной точки; cpx2, cpy2 – координаты второй контрольной точки; x, y – координаты конца прямой. В качестве координат начала берётся текущая позиция пера. Принцип построения кривой отображён на рисунке 3.3.
Рисунок 3.3 – Построение кривой Безье
- квадратическая кривая. Строится с помощью функции quadricCurveTo(cpx, cpy, x, y) cpx, cpy – координаты контрольной точки; x, y – координаты конца прямой. В качестве координат начала берётся текущая позиция пера. Принцип построения кривой отображён на рисунке 3.4.
Рисунок 3.4 – Построение квадратической кривой
- дуга. Строится с помощью функции arcTo(x1, y1, x2, y2, radius), где x1, y1 – координаты первой контрольной точки; x2, y2 – координаты второй контрольной точки; radius – радиус дуги. Принцип построения кривой отображён на рисунке 3.5.
Рисунок 3.5 – Построение дуги
Все фигуры, которые строили до текущего момента, имели один стиль отображения, для изменения стиля нарисованных элементов объект context элемента canvas имеет следующие параметры:
- lineWidth – ширина отображаемой линии в пикселях (по умолчанию 1 пиксель);
- lineJoin – тип соединения линий round – скруглённое соединение, bevel – срезанное, mittel – прямое (по умолчанию mittel). Примеры отображаемых линий можно увидеть на рисунке 3.6;
Рисунок 3.6 – Типы соединения линий
- strokeStyle – цвет отображаемой прямой (по умолчанию чёрный).
Помимо работы с каркасными фигурами, можно заливать необходимые области экрана заданным цветом. Для этого используются функции:
- fillRect(x, y, width, height) – заливает область шириной width и высотой height в точке x, y;
- clearRect(x, y, width, height) – восстанавливает фоновый цвет области шириной width и высотой height в точке x, y;
Для определения цвета заливки используется параметр fillStyle.
Помимо работы с фигурами заданного цвета, элемент canvas позволяет работать с уже готовыми изображениями. Для отображения изображения используется функция drawImage(image, x, y, width, height), которая отображает изображение image, в прямоугольнике с шириной width и высотой height, в точке (x, y). До вызова этой функции изображение уже должно быть полностью загружено. Однако загрузка изображения выполняется асинхронно, поэтому перед вызовом данной функции делают следующую проверку:
var image = new Image();
image.src = 'image.jpg';
image.onload = function()
{
drawImage(image, 5, 10, 100, 100);
}
Изображения могут быть использованы в качестве шаблонов, для отрисовки фигур. Для этого загруженное изображение надо преобразовать с помощью функции createPattern(image, repeat), где image –рисунок, repeat – тип повторения. Доступны следующие типы повторения изображения
- repeat – повторение, как по оси x, так и по оси y (по умолчанию);
- repeat-x – повторение только по оси x;
- repeat-y – повторение только по оси y;
- norepeat – без повторений.
Далее полученный шаблон необходимо передать в параметр strokeStyle или fillStyle, в зависимости от целей применения.
Также canvas предоставляет методы, для работы с градиентом. Поддерживаются 2 типа градиентов:
- линейный. Создаётся функцией createLinearGradient(x0, y0, x1, y1), в прямоуголнике, заданным точками (x0,y0); (x1,y1). Пример градиента отображён на рисунке 3.7.
Рисунок 3.7 – Линейный градиент
- радиальный. Создаётся функцией createRadialGradient(x0, y0, r0, x1, y1, r1), и представляет собой две окружности, заданные своими координатами и радиусами. Пример градиента отображён на рисунке 3.8.
Рисунок 3.8 – Радиальный градиент
Для указания цветов градиента, у этого объекта существует метод addColorStop(gradientPart, color), где gradientPart – часть градиента, которая представляется, как число с плавающей точкой от 0 (начало градиента), до 1 (конец градиента), color – цвет в указанной точке.
Далее объект градиент передаётся параметру strokeStyle или fillStyle, в зависимости от целей.
var gradient = createLinearGradient(0, 0, 100, 1000);
gradient.addColorStop(0, rgb(255, 0, 0));
gradient.addColorStop(0.5. rgb(0, 255, 0));
gradient.addColorStop(1 rgb(0, 0, 255));
context.fillStyle = gradient;
context.fillRect = (0, 0, 100, 100);
Элемент canvas предоставляет готовые решения для работы с тенью элементов, для этого у элемента context, предусмотрены параметры:
- shadowColor – задаёт цвет тени;
- shadowOffsetX – смещение тени относительно основного объекта по оси X;
- shadowOffsetY – смещение тени относительно основного объекта по оси Y;
- shadowBlur – размытие тени.
Работа с созданием примитивов, в неявном виде представляет собой работу с геометрическими преобразованиями изображений, однако, можно и явно преобразовывать объекты.
Данные функции, напоминают преобразование объектов в OpenGL. Рассмотрим их:
- save() – сохранение текущего состояния холста;
- translate(x, y) – перемещение центра координат в точку с координатами x, y;
- scale(x, y) – масштабирование холста по оси x и y;
- rotate(cornerRadian) – поворот системы координат вокруг начала координат, на угол cornerRadian;
- restore() – восстановление ранее сохранённого состояния холста.
Помимо, работы с элементами с помощью заданных функций, можно работать напрямую с пикселями изображений. Для получения информации о них, вызывается функция getImageData(x, y, width, height). Данная функция возвращает объект типа ImageData, который имеет следующие параметры:
- width – ширина выбранной области;
- height – высота выбранной области;
- data – одномерный массив данных, в котором записаны R, G, B и alpha компоненты каждого пикселя. Компоненты задаются целым числом от 0 до 255. Учитывая, что все данные, представлены в одном массиве, то доступ к элементам затруднён, что бы получить доступ к компонентам точки x и y используются следующие формулы:
R = ((width * y) + x) * 4
G = (((width * y) + x) * 4) + 1
B = (((width * y) + x) * 4) + 2
Alpha = (((width * y) + x) * 4) + 3
Обработав пиксели изображения, необходимо выставить его в элемент canvas, для этого используем функцию putImageData(imageData, dx, dy), где imageData – информация о пикселях изображения; dx, dy – координаты точки, куда встраиваем выбранную часть изображения.
Помимо работы с изображением canvas предоставляет функционал для работы с текстом. Для встраивания текста, используются функции:
- strokeText(text, x, y, maxWidth);
- fillText(text, x, y, maxWidth),
где text – отображаемый текст; x, y – координаты точки, куда мы встраиваем текст; maxWidth – максимальная ширина объекта текста.
Для управления текстом у элемента context предусмотрены следующие параметры:
- textAlign – выравнивание точки встраивания текста относительно точки встраивания текста. Возможные варианты изображены на рисунке 3.9.
Рисунок 3.9 – Выравнивание относительно точки встраивания
- font – указание параметров шрифта текста
- textBaseLine – указание базовой линии текста. Возможные варианты указаны на рисунке 3.10
Рисунок 3.10 – Варианты базовой линии текста
Ход работы
В качестве задания создадим простейшую игру змейка, для этого мы должны сделать следующие шаги:
- создать форму, для отображения игры;
- создать переменные для определения состояния змейки и основных констант;
- создать функции для отображения змейка
- создать функции для основной логики игры;
- создать основной игровой цикл;
- обеспечить взаимодействие с пользователем;
- добавить мелиа контент;
- проинициализировать игру.
Для начала создадим форму, на которой будет отображаться игра:
<!doctype html>
<head>
<title>Snake</title>
</head>
<body onload="init()">
<input type="button" value="Play/Pause" onclick="play()"><br />
<canvas id="canvas" style="border: solid 1px red;" width="600" height="600">
</canvas>
</body>
Создадим основные внешние переменные, используемые для написания скрипта:
var snakeColor = "rgb(0, 0, 0)"; //Цвет змейки
var foodColor = "rgb(0, 255, 0)"; //Цвет еды змейки
var ctx; //Объект context
var gridSize = 20; //Размер клетки
var snake; //Очередь элементов змейки
var food = []; //Координаты еды змейки
var direction; //Направление змейки
var changex = [-1, 0, 1, 0]; //Изменение координаты x в зависимости от направления
var changey = [0, -1, 0, 1]; //Изменение координаты y в зависимости от направления
var paused; //Состояние игры
var speed = 100; //Скорость перемещения змейки
var clock; //Объект таймера
Создание функций отрисовки элементов
function drawSnake()
{
ctx.fillStyle = snakeColor;
ctx.fillRect(snake[snake.length - 1][0] * gridSize, snake[snake.length - 1][1] * gridSize, gridSize, gridSize);
}
function drawFood()
{
ctx.fillStyle = foodColor;
ctx.fillRect(food[0] * gridSize, food[1] * gridSize, gridSize, gridSize);
}
function delPart(x, y)
{
ctx.fillStyle = bckColor;
ctx.clearRect(x * gridSize, y * gridSize, gridSize, gridSize);
}
Функция принадлежности точки телу змейки
function dotBelongSnake(x, y)
{
res = false;
for(i = 0; i < snake.length &&!res; ++i)
{
res = x == snake[i][0] && y == snake[i][1];
}
return res;
}
Добавление элементов, на поле
function setX(x)
{
return x >= 0? x % (ctx.canvas.width / gridSize): x + (ctx.canvas.width / gridSize);
}
function setY(y)
{
return y >= 0? y % (ctx.canvas.height / gridSize): y + (ctx.canvas.height / gridSize);
}
function addFood()
{
do
{
food[0] = Math.floor(Math.random() * (ctx.canvas.height / gridSize));
food[1] = Math.floor(Math.random() * (ctx.canvas.height / gridSize));
}while(dotBelongSnake(food[0], food[1]));
drawFood();
}
Проверка змейки на столкновение
function crash()
{
res = false;
for(i = 0; i < snake.length - 1 &&!res; ++i)
{
res = snake[i][0] == snake[snake.length - 1][0] && snake[i][1] == snake[snake.length - 1][1];
}
return res;
}
Управление состоянием игры
function play()
{
if(paused)
{
clock = setInterval(movement, speed);
}
else
{
clearInterval(clock);
}
paused =!paused;
}
Основной игровой цикл
function movement()
{
snake.push([setX(snake[snake.length - 1][0] + changex[direction]), setY(snake[snake.length - 1][1] + changey[direction])])
if(!dotBelongSnake(food[0], food[1]))
{
delPart(snake[0][0], snake[0][1]);
snake.shift();
}
else
{
addFood();
}
if(crash())
{
play();
alert("Game Over;");
clear();
init();
}
drawSnake();
}
Управление игрой
function changeDirection(event)
{
if(!paused)
{
code = 0
if(event == null)
{
code = window.event.keyCode;
}
else
{
code = event.keyCode;
}
switch(code)
{
case 37:
if(direction!= 2)
{
direction = 0;
}
break;
case 38:
if(direction!= 3)
{
direction = 1;
}
break;
case 39:
if(direction!= 0)
{
direction = 2;
}
break;
case 40:
if(direction!= 1)
{
direction = 3;
}
break;
}
}
}
Инициализация игры
function init()
{
canvas = document.getElementById('canvas');
if (canvas.getContext)
{
snake = [[0, 0]];
direction = 2;
paused = true;
ctx = canvas.getContext('2d');
document.onkeydown = function (event)
{
changeDirection(event);
};
addFood();
return true;
}
else
{
alert(“Canvas isn’t supported!");
return false;
}
}
Варианты заданий
1. Тетрис.
2. Арканоид
3. Пакмен
4. Pong на 2 игроков. Управление с левой и правой части клавиатуры.
Вопросы для самоконтроля
1. Какие кодеки может воспроизводить браузер?
2. Какой тег используется для создания элемента, воспроизводящего звук? Какие параметры он принимает?
3. Какой тег используется для создания элемента, воспроизводящего видео? Какие параметры он принимает?
4. Для чего используется параметр controls? Что происходит, если он не указан?
5. Как указать множественный источник медиаконтента? Какой источник будет выбран приоритетным?
6. Как изменять состояние медиаэлемента?
7. Какие параметры медиаэлемента можно изменять?
8. Какие параметры медиаэлемента доступны только для считывания?
9. Как создать элемент для отображения 2д графики?
10. Базовые функции для отрисовки элементов.
11. Отрисовка кривых.
12. Работа со стилями рисуемых фигур.
13. Отрисовка рисунков.
14. Создание градиентов.
15. Отличия линейного и радиального градиентов.
16. Работа с тенями.
17. Функции для моделирования работы графических преобразований.
18. Попиксельная работа с изображением.
19. Работа с текстом на canvas.
20. Вертикальное и горизонтальное выравнивание текста.
Источники
- http://evolutionofweb.appspot.com
- http://caniuse.com
- http://www.whatwg.org/specs/web-apps/current-work/multipage/index.html
- http://www.apple.com/hotnews/thoughts-on-flash/
- http://www.w3.org/TR/html5/
- Лабберс П., Олберс Б., Салим Ф. HTML5 для профессионалов
Дата добавления: 2015-11-14; просмотров: 56 | Нарушение авторских прав
<== предыдущая страница | | | следующая страница ==> |
Работа с медиа элементами | | | Построение геометрии |