HTML5 Canvas. Рисование мышкой. Часть 2

Дата публикации:4 мая 2013 г. 20:49:53

Здравствуйте! Первая часть урока здесь. В этой части урока мы научим наш скрипт рисовать:

  • Прямоугольник
  • Прямую линию

Для начала добавим в наш html файл следующий код:

<label for = "tools">Инструмент рисования:</label>
<select id = "tools" name = "tools">
    <option value = "line">Линия</option>
    <option value = "rect">Прямоугольник</option>
    <option value = "pencil">Карандаш</option>
</select>

Теперь откроем наш JS файл и добавим в него следующее (поскольку многие переменные и функции затрагивают старые, я приведу здесь весь код целиком):

if(window.addEventListener) {
    window.addEventListener('load', function () {
        var canvas, context, canvaso, contexto;
        
        // По умолчанию линия - инструмент по умолчанию
        var tool;
        var tool_default = 'line';

        function init () {
            canvaso = document.getElementById('tablet');
            if (!canvaso) {
                alert('Ошибка! Canvas элемент не найден!');
                return;
            }

            if (!canvaso.getContext) {
                alert('Ошибка! canvas.getContext не найден!');
                return;
            }

            contexto = canvaso.getContext('2d');
            if (!contexto) {
                alert('Ошибка! Не могу получить getContext!');
                return;
            }

            var container = canvaso.parentNode;
            canvas = document.createElement('canvas');
            if (!canvas) {
                alert('Ошибка! Не могу создать canvas элемент!');
                return;
            }

            canvas.id = 'imageTemp';
            canvas.width = canvaso.width;
            canvas.height = canvaso.height;
            container.appendChild(canvas);

            context = canvas.getContext('2d');

            // Получаем инструмент из option
            var tool_select = document.getElementById('tools');
            if (!tool_select) {
                alert('Ошибка! Элемент tools не найден!');
                return;
            }
            tool_select.addEventListener('change', ev_tool_change, false);

            // Активируем способ рисования по-умолчанию
            if (tools[tool_default]) {
                tool = new tools[tool_default]();
                tool_select.value = tool_default;
            }

            canvas.addEventListener('mousedown', ev_canvas, false);
            canvas.addEventListener('mousemove', ev_canvas, false);
            canvas.addEventListener('mouseup',   ev_canvas, false);
        }

        function ev_canvas (ev) {
            if (ev.layerX || ev.layerX == 0) {
                ev._x = ev.layerX;
                ev._y = ev.layerY;
            } else if (ev.offsetX || ev.offsetX == 0) {
                ev._x = ev.offsetX;
                ev._y = ev.offsetY;
            }

            var func = tool[ev.type];
            if (func) {
                func(ev);
            }
        }

        // Обработчик событий для изменения селекта
        function ev_tool_change (ev) {
            if (tools[this.value]) {
                tool = new tools[this.value]();
            }
        }

        // Эта функция вызывается каждый раз после того, как пользователь
        // завершит рисование. Она очищает imageTemp.
        function img_update () {
            contexto.drawImage(canvas, 0, 0);
            context.clearRect(0, 0, canvas.width, canvas.height);
        }

        // Содержит реализацию каждого инструмента рисования
        var tools = {};

        // Карандаш
        tools.pencil = function () {
        var tool = this;
        this.started = false;

        // Рисуем карандашом
        this.mousedown = function (ev) {
            context.beginPath();
            context.moveTo(ev._x, ev._y);
            tool.started = true;
        };

        this.mousemove = function (ev) {
            if (tool.started) {
                context.lineTo(ev._x, ev._y);
                context.stroke();
            }
        };

        this.mouseup = function (ev) {
            if (tool.started) {
                tool.mousemove(ev);
                tool.started = false;
                img_update();
            }
        };
    };

    // Прямоугольник
    tools.rect = function () {
        var tool = this;
        this.started = false;

        this.mousedown = function (ev) {
            tool.started = true;
            tool.x0 = ev._x;
            tool.y0 = ev._y;
        };

        this.mousemove = function (ev) {
            if (!tool.started) {
                return;
            }

            var x = Math.min(ev._x,  tool.x0),
            y = Math.min(ev._y,  tool.y0),
            w = Math.abs(ev._x - tool.x0),
            h = Math.abs(ev._y - tool.y0);

            context.clearRect(0, 0, canvas.width, canvas.height);

            if (!w || !h) {
                return;
            }

            context.strokeRect(x, y, w, h);
        };

        this.mouseup = function (ev) {
            if (tool.started) {
                tool.mousemove(ev);
                tool.started = false;
                img_update();
            }
        };
    };

    // Линия
    tools.line = function () {
        var tool = this;
        this.started = false;

        this.mousedown = function (ev) {
            tool.started = true;
            tool.x0 = ev._x;
            tool.y0 = ev._y;
        };

        this.mousemove = function (ev) {
            if (!tool.started) {
                return;
            }

            context.clearRect(0, 0, canvas.width, canvas.height);

            context.beginPath();
            context.moveTo(tool.x0, tool.y0);
            context.lineTo(ev._x,   ev._y);
            context.stroke();
            context.closePath();
        };

        this.mouseup = function (ev) {
            if (tool.started) {
                tool.mousemove(ev);
                tool.started = false;
                img_update();
            }
        };
    };

    init();

}, false); }

Я постарался прокомментировать наиболее важные части кода. Надеюсь, у вас не возникнет проблем с его пониманием. Также, добавьте к нашим стилям следующее:

<style = "text/css">
    ...
    #imageTemp { position: absolute; top: 1px; left: 1px; }
    ....
</style>

И еще, добавьте в тело нашего элемента canvas следующее:

<canvas>
<p>К сожалению, ваш браузер не поддерживает данную функцию. Мы рекомендуем вам обновить ваш браузер или установить другой.</p>
</canvas>

Так мы уведомим пользователя, браузер которого безнадежно устарел или IE. На этом пока все. Спасибо за внимание!

Метки:html5, html, css, js, canvas, урок