Опрос
Вы участвуете в программе Windows Insider?
Популярные новости
Обсуждаемые новости

09.03.2011 14:14 | dronov_va

18. Создаём анимацию на канве
К сожалению, канва HTML 5 не предоставляет никаких специальных средств для создания анимации. Нам придётся пользоваться для этого стандартные средства веб-браузера, а именно, метод setInterval объекта Window.

Объект Window представляет окно веб-браузера. Экземпляр этого объекта, представляющий текущее окно веб-браузера, доступен через переменную window, доступную в любом веб-сценарии.

Метод setInterval создаёт таймер, который можно рассматривать как своего рода "будильник", который срабатывает каждый раз, когда пройдет определённый интервал времени. Срабатывание этого "будильника" заключается в вызове указанной нами функции.

Вот формат вызова этого метода:

окно веб-браузера.setInterval(
  функция, которая будет вызываться по истечении интервала,
  интервал
);

зываться по истечении интервала,
интервал
);[/code]
Первый параметр задаёт саму функцию, которая будет вызываться каждый раз при срабатывании таймера. В качестве его значения можно использовать как имя именованной функции, так и анонимную функцию. Второй параметр задаёт сам интервал в виде числа в миллисекундах, по истечении которого будет срабатывать таймер.

Метод setInterval возвращает особое числовое значение - идентификатор созданного нами таймера. Его можно использовать, чтобы деактивировать данный таймер, но обычно его игнорируют.

[code]window.setInterval(1000, drawFrame);[/code]
Этот код запускает таймер, который будет срабатывать каждую секунду и вызывать функцию drawFrame.

Как это связано с анимацией? А вот как...

Анимацию можно представить как последовательность отдельных картинок - кадров, быстро сменяющих друг друга. Каждый такой кадр несколько отличается от предыдущего, из-за чего и возникает иллюзия, что изображение движется.

Значит, чтобы создать анимацию на канве, нам следует периодически выводить на ней содержимое её отдельных кадров. А если точнее:

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


Код, который выполняет всё это, мы поместим в тело функции, которая будет вызываться при каждом срабатывании таймера. Вот нам и пригодился метод setInterval!

[code]var angle = 0;
window.setInterval(
function ()
{
ctx1.clearRect(0, 0, 400, 300);
ctx1.save();
ctx1.translate(200, 150);
ctx1.rotate(angle);
ctx1.beginPath();
ctx1.moveTo(0, -100);
ctx1.lineTo(-100, 50);
ctx1.lineTo(100, 50);
ctx1.closePath();
ctx1.stroke();
ctx1.restore()
angle += Math.PI / 20;
if (angle >= Math.PI * 2) angle = 0;
}, 100);[/code]
Этот код рисует вращающийся контур равностороннего треугольника. Давайте разберёмся, как он работает.

Сначала он устанавливает начальное значение угла (переменная angle), на который будет повёрнут треугольник, равное 0 радиан. После этого он создаёт таймер, который будет срабатывать каждые 0,1 секунды (100 миллисекунд) и вызывать функцию, которая рисует очередной кадр анимации. Здесь мы указали анонимную функцию прямо в вызове метода setInterval.

Что касается данной функции, то она будет выполнять действия, которые перечислены ниже.

  • Очистка канвы от присутствующей на ней графики.
  • Сохранение состояния канвы. Это нужно, чтобы впоследствии мы смогли вернуться к изначальному состоянию её системы координат.
  • Сдвиг начала координат в центр канвы.
  • Поворот системы координат на значение угла, хранящееся в переменной angle (см. выше). Поскольку перед этим мы сдвинули начало системы координат в середину канвы, поворот будет выполнен относительно именно этой точки.
  • Рисование в центре канвы равностороннего треугольника без заливки.
  • Восстановление состояния канвы. Мы сделали это, чтобы вернуться к изначальному состоянию системы координат - в нём проще выполнить очистку канвы перед рисованием очередного кадра (см. выше).
  • Добавляем к значению угла, хранящемуся в переменной angle, значение "число пи" / 20 радиан (9 градусов). Это значение называется приращением.
  • Проверяем, не превышает ли хранящееся в переменной angle значение величину "число пи" * 2 (360 градусов), и, если так и есть, присваиваем переменной angle значение 0. Если значение угла, большее, чем "число пи" * 2 (360 градусов), передать методу rotate, выполнение веб-сценария завершится по ошибке. Поэтому мы и выполняем описанную выше проверку.


"Играя" со значениями интервала, по окончанию которого срабатывает таймер, и приращения угла, на который каждый раз будет поворачиваться рисуемый треугольник, можно регулировать скорость и плавность его вращения.

[code]var img1 = new Image();
img1.src = "picture.jpg";
img1.addEventListener("load",
function ()
{
var x = 0, y = 0;
var deltaX = 2, deltaY = 2;
window.setInterval(
function ()
{
ctx1.save();
ctx1.clearRect(0, 0, 400, 300);
ctx1.fillStyle = "#CCCCCC";
ctx1.globalAlpha = 0.4;
ctx1.drawImage(img1, 0, 0, 400, 300);
ctx1.globalAlpha = 1.0;
ctx1.beginPath();
ctx1.arc(x + 50, y + 50, 50, 0, 2 * Math.PI, false);
ctx1.clip();
ctx1.drawImage(img1, 0, 0, 400, 300);
x += deltaX;
y += deltaY;
if (x + 100 >= 400) {
deltaX = -deltaX;
} else {
if (x <= 0) deltaX = -deltaX;
}
if (y + 100 >= 300) {
deltaY = -deltaY;
} else {
if (y <= 0) deltaY = -deltaY;
}
ctx1.restore();
}, 100);
}, false);[/code]
Этот код выводит мутное, малоразличимое изображение с движущейся "дыркой" - маской - посередине, в которой видно то же изображение, но уже чёткое, прекрасно видимое. Фактически мы доработали пример, представленный в параграфе 17, анимировав маску для пущего эффекта. Получилось, кстати, великолепно!

Вы можете сами разобраться, как работает этот код. Пусть это будет вашим домашним заданием.

На этом мы закончим рассмотрение возможностей рисования на канве. Оставшиеся параграфы будут посвящены дополнительным возможностям самого тега <CANVAS> и представляющего его объекта HTMLCanvasElement. Эти возможности во многих случаях могут оказаться очень кстати.


19. Использование содержимого канвы в качестве обычного изображения. Интернет-адреса с данными
Канва HTML 5 поддерживает очень интересную функцию - она позволяет использовать её содержимое как источник изображения для тега <IMG>. Другими словами, мы можем поместить содержимое канвы на другое место веб-страницы с помощью хорошо нам знакомого тега <IMG>.

Обычно, чтобы указать файл, из которого будет взято изображение для помещения на веб-страницу, мы задаём в теге <IMG> интернет-адрес, или URL, этого файла. Привычный нам интернет-адрес сам по себе не содержит никаких графических данных - он только указывает веб-браузеру, где их следует искать.

[code]<IMG SRC="/images/pictures/picture.jpg">[/code]
Но HTML 5 поддерживает интернет-адреса другого типа. Они не указывают веб-браузеру, где следует искать графические данные, - они сами содержат графические данные. Поэтому такие интернет-адреса получили название интернет-адресов с данными, или data URL.

Интернет-адреса с данными имеют такой формат:

[code]data:MIME-тип данных;обозначение кодировки данных,собственно данные, закодированные в текстовом виде[/code]
Данные, хранящиеся в таких интернет-адресах, должны быть представлены в текстовом виде, иначе их невозможно будет указать в HTML-коде веб-страницы. Как мы знаем, веб-страницы - суть текстовые файлы. Поэтому данные кодируются особым образом, для чего применяются специальные кодировки, обычно - Base64.

Вот пример интернет-адреса с данными, хранящего изображение в формате PNG (приведён в сокращённом виде):

[code]data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAEsCAYAAADtt[/code]
Интернет-адрес с данными можно указать в качестве значения атрибута SRC тега <IMG>.

[code]<IMG SRC="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAEsCAYAAADtt">[/code]
Но какое отношение это имеет к канве? А вот какое...

Мы имеем возможность превратить содержимое канвы в интернет-адрес с данными. Для этого мы используем метод toDataURL объекта HTMLCanvasElement, представляющего канву.

[code]канва.toDataURL(
[MIME-тип графических данных[,
качество изображения JPEG]]
);[/code]
Первый параметр этого метода необязателен и указывает MIME-тип графических данных, фактически - формат изображения, что мы собираемся получить, в виде строки.

  • Графические данные в формате GIF имеют MIME-тип image/gif.
  • Графические данные JPEG - image/jpg.
  • Графические данные PNG - image/png.


Если первый параметр не указан, графические данные будут иметь формат PNG.

Примечание:
Даже если при вызове метода toDataURL указать MIME-тип image/jpg или image/gif, Internet Explorer 9 RC во многих случаях возвращает интернет-адрес с графическими данными в формате PNG. Почему так происходит - непонятно; возможно, это ещё не устранённая ошибка в программе.

Второй, также необязательный, параметр имеет смысл только в случае вывода графических данных в формате JPEG и указывает качество изображения. Его значение должно иметь вид числа с плавающей точкой от 0.0 (минимальное качество) до 1.0 (максимальное качество). Если этот параметр не указан, веб-браузера сам устанавливает качество изображения JPEG; поэтому лучше данный параметр всё-таки указывать.

Метод toDataURL возвращает то, что нам нужно, - интернет-адрес с данными в виде строки.

[code]var url = oCan1.toDataURL();[/code]
После выполнения этого выражения мы получим в переменной url строку с интернет-адресом, содержащим графические данные в формате PNG (ни один параметр метода toDataURL не указан).

[code]var url = oCan1.toDataURL("image/jpg", 1.0);[/code]
А это выражение присвоит переменной url интернет-адрес с графическими данными JPEG максимального качества.

Полученные таким образом графические данные мы можем использовать для вывода графики на веб-страницу с помощью тега <IMG>.

[code]<CANVAS ID="can1" WIDTH="400" HEIGHT="300" STYLE="display: none;"></CANVAS>
<IMG ID="img1" SRC="">
<SCRIPT>
var oCan1 = document.getElementById("can1");
var ctx1 = oCan1.getContext("2d");
ctx1.beginPath();
ctx1.moveTo(200, 0);
ctx1.lineTo(0, 300);
ctx1.lineTo(400, 300);
ctx1.closePath();
ctx1.stroke();
var oImg1 = document.getElementById("img1");
oImg1.src = oCan1.toDataURL();
</SCRIPT>[/code]
Этот код помещает на веб-страницу невидимую канву (мы сделали её невидимой, задав для атрибута стиля display значение none) и "пустое" графическое изображение (тег <IMG>). Далее на канве рисуется равносторонний треугольник, который впоследствии выводится на веб-страницу с помощью данного тега <IMG>.

20. Получение размеров канвы
Мы можем получить в веб-сценарии размеры канвы - её ширину и высоту. Для этого предназначены свойства width и height объекта HTMLCanvasElement, представляющего канву. Свойство width хранит значение ширины канвы в пикселах, а свойство height - её высоту, также в пикселах; оба этих значения представляют собой целые числа.

[code]ctx1.beginPath();
ctx1.moveTo(oCan1.width / 2, 0);
ctx1.lineTo(0, oCan1.height);
ctx1.lineTo(oCan1.width, oCan1.height);
ctx1.closePath();
ctx1.stroke();[/code]
Этот код рисует равнобедренный треугольник, занимающий всю канву.

21. Что делать, если веб-браузер не поддерживает канву
Мы долго экспериментировали с канвой, изучали её возможности, рисовали на ней красивые картинки и совсем забыли, что не все веб-браузеры, имеющие хождение на данный момент, поддерживают эту самую канву и вообще HTML 5. Так, половину современного парка веб-браузеров составляют старые версии Internet Explorer, которые не "обучены" рисовать на веб-странице. И если посетитель откроет в таком веб-браузере страницу с канвой, нарисованную нами графику он не увидит... Что же делать?

Единственный выход - представить такому посетителю что-то взамен, какой-то текст, сообщающий об отсутствии в его веб-браузере поддержки канвы, или обычную картинку. Одним словом, дать ему альтернативное содержимое.

HTML-код, создающий альтернативное содержимое, помещается в сам тег <CANVAS>, создающий канву, - именно для такого случая данный тег сделан парным.

  • Веб-браузер с поддержкой HTML 5 проигнорирует альтернативное содержимое, помещённое в тег <CANVAS>, и выведет на экран канву.
  • Веб-браузер, не поддерживающий HTML 5, наоборот, проигнорирует тег <CANVAS> и выведет на экран альтернативное содержимое, помещённое в этот тег.


[code]<CANVAS ID="can1" WIDTH="400" HEIGHT="300">
<P>Извините, но ваш браузер не поддерживает канву.</P>
</CANVAS>[/code]

Дополнительные материалы



dronov_va, TheVista.Ru Team
Март 2011

Комментарии

Комментариев нет...
Для возможности комментировать войдите в 1 клик через

По теме

Акции MSFT
420.55 0.00
Акции торгуются с 17:30 до 00:00 по Москве
Все права принадлежат © ms insider @thevista.ru, 2022
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.03 секунд (Общее время SQL: 0.014 секунд - SQL запросов: 53 - Среднее время SQL: 0.00027 секунд))
Top.Mail.Ru