HTML5 — несомненный тренд. Причем, не столько новая спецификация с новыми тегами, сколько гармоничное и могучее сочетание HTML + CSS + JS, изящно утирающее нос Flash.
Уже сейчас можно наблюдать красивые HTML-5 сайты без мегабайтов изображений и без сотен килобайт скриптов. Например, фон вот
этого сайта сделан при помощи JavaScript Canvas.
Как видите, JS Canvas действительно хорошая вещь. Именно ей я хочу посвятить первый пост свежеоткрытой рубрики «HTML5″. В нем я опишу процесс создания простенькой рисовалки на HTML5 с единственным инструментом «Pencil».
Вот такую.
Общие сведения
Canvas позволяет рисовать в специальном элементе документа <canvas> линии, дуги, прямоугольники, окружности, заливать пространство, манипулировать текстом и картинками. Всё это прекрасно описано в «
Canvas Tutorial« Mozilla Developers Center с примерами и картинками, прям как мне нравится.
Мы же напишем рисовалку, управлять которой будем при помощи специального объекта Canva, а сам инструмент «карандаш» (ну или «кисть») будет задан объектом Pencil.
Canva
Canva — управляющий объект. С его помощью мы переопределим реакцию страницы на события <canvas>, будем выбирать нужный инструмент, будем задавать свойства типа цвета заливки и толщины линий и пр. Вот его реализация:
var Canva = {};
// Инициализация объекта
Canva.init = function(id, width, height)
{
var canv = document.getElementById(id);
canv.width = width;
canv.height = height;
this.canvasId = id;
this.ctx = canv.getContext("2d");
// Свойства
this.selectedColor = '#000000';
this.selectedFillColor = '#FFFFFF';
this.selectedWidth = 1;
this.tool = Pencil; // Выбранный инструмент
this.drawing = false; // true - если зажата кнопка мыши
// Кнопка мыши зажата, рисуем
canv.onmousedown = function(e)
{
var evnt = ie_event(e);
Canva.tool.start(evnt);
};
// Кнопка мыши отпущена, рисование прекращаем
canv.onmouseup = function(e)
{
if (Canva.drawing)
{
var evnt = ie_event(e);
Canva.tool.finish(evnt);
}
};
// процесс рисования
canv.onmousemove = function(e)
{
if (Canva.drawing)
{
var evnt = ie_event(e);
Canva.tool.move(evnt);
}
};
};
Canva.setTool = function(t) // Задать инструмент
{
Canva.tool = t;
};
Canva.setWidth = function(width) // Задать толщину линий
{
Canvas.selectedWidth = width;
};
Canva.setColor = function(color) // Задать текущий цвет
{
Canva.selectedColor = color;
};
Canva.clear = function() // Очистить рисовалку
{
var canv = document.getElementById(Canva.canvasId);
Canva.ctx.clearRect(0, 0, canvas.width, canvas.height);
};
При инициализации объекта ему передается в качестве параметров id canvas, необходимые ширина и высота рисовалки.
функция ie_event — специальный костыль для IE (см.
эту запись), вот ее реализация:
function ie_event(e)
{
if (e === undefined)
{ return window.event; };
return e;
}
Pencil
Наш инструмент, которым мы будем рисовать, должен иметь функции move, start и finish. Принцип полиморфизма в действии.
Все нарисованное этим инструментом будет представлять собой последовательность прямых линий, коротких и не очень. Тут уже зависит от того, насколько быстр браузер пользователя.
var Pencil = {};
// Начинаем рисование
Pencil.start = function(evnt)
{
// Текущее положение мыши - начальные координаты
Pencil.x = evnt.clientX;
Pencil.y = evnt.clientY;
Canva.ctx.beginPath();
// Свойства рисования
Canva.ctx.strokeStyle = Canva.selectedColor;
Canva.ctx.lineWidth = Canva.selectedWidth;
Canva.ctx.moveTo(Pencil.x, Pencil.y); // Курсор на начальную позицию
Canva.drawing = true; // Начато рисование
};
// Рисование закончили
Pencil.finish = function(evnt)
{
Pencil.x = evnt.clientX;
Pencil.y = evnt.clientY;
Canva.ctx.lineTo(Pencil.x, Pencil.y); // Дорисовываем последнюю линию
Canva.drawing = false;
};
// Рисование в разгаре
Pencil.move = function(evnt)
{
Pencil.x = evnt.clientX;
Pencil.y = evnt.clientY;
Canva.ctx.lineTo(Pencil.x, Pencil.y); // Дорисовываем начатую линию
Canva.ctx.stroke();
// Начинаем рисованть новую линию из той же точки.
Canva.ctx.moveTo(Pencil.x, Pencil.y);
};
Принцип такой: на нажатие кнопки мыши начинаем линию. На событие onmousemove (движение мыши) начатую линию дорисовываем и тут же начинаем новую. Так повторяется до тех пор, пока кнопка мыши не будет отпущена.
Использование
В header документа подключаем файл, содержащий весь приведенный выше код. В теле документа (после <canvas>!) вставляем JS-код с инициализацией объекта Canva:
<script type="text/javascript">
// Сделаем рисовалку во всю страницу
Canva.init('canvas', window.innerWidth, window.innerHeight);
</script>
Internet Explorer
Поддержки canvas в IE 8 и младше нет. Но у доброго Google есть проект
explorercanvas, который должен подружить IE с canvas. К сожалению, в моем случае этот костыль почему-то не работает, так что пользователи IE ничего порисовать не смогут. Сами виноваты.
Сохранение изображения на стороне клиента
Чтобы сохранить нарисованное в canvas как изображение на стороне клиента, можно сделать специальную кнопку и на onclick ей повесить событие
window.open(document.getElementById("canvas").toDataURL("image/png"), "new_window_name");
При нажатии на кнопку будет открыто новое окно (вкладка) с PNG-изображением.
Сохранение изображения на сервере
Так как предыдущий вариант работает через GET, зачастую он не применим для сохранения изображения на сервере из-за ограничения на длину URL. Тогда на помощь приходит вот
эта библиотека.