Рисовалка на JavaScript Canvas. Основы



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. Тогда на помощь приходит вот эта библиотека.
Теги:
Canvas
Добавлено: 24 Февраля 2015 07:13:50 Добавил: Андрей Ковальчук Нравится 0
Добавить
Комментарии:
Нету комментариев для вывода...