English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Введение
Появление RequireJS сделало модульизацию кода на переднем конце更容易, когда проекты становятся все больше и больше, а код становится все больше и больше, модульизация кода делает структуру проекта более ясной, не только делает наши мысли более ясными в процессе разработки, но и упрощает后期 поддержку. НИЖЕ приведен简易绘图程序, который я разработал с использованием RequireJS после изучения RequireJS, который работает в браузере, как показано на следующей диаграмме:
Если вы еще не очень хорошо знакомы с RequireJS, вы можете ознакомиться с моими заметками о изучении RequireJS:http://blog.csdn.net/yubo_725/article/details/52913853
Начало
Этот простая программа для рисования показана на следующей диаграмме структуры проекта:
В котором index.html является主页ом проекта, все js файлы хранятся в директории js, директория js/app содержит наши пользовательские модульные файлы, директория js/lib в настоящее время пуста, когда наш проект использует какие-либо другие фронтенд-фреймворки, такие как jquery, эти фреймворки хранятся в директории js/lib, js/main.js является файлом конфигурации requirejs, который主要负责配置 пути, js/require.min.js является файлом фреймворка RequireJS. Теперь давайте шаг за шагом создадим эту простую программу для рисования!}
一、Конфигурация requirejs
Код конфигурационного файла проекта находится в js/main.js, содержимое кода следующее:
require.config({ baseUrl: 'js/lib', paths: { app: '../app' } )
Это主要是 настройка корневой директории проекта 'js/lib', затем настройка пути 'app', который равен '../app', то есть директория 'js/app'.
二、Написание модульного кода
В этом проекте主要有 следующие модули: point.js, line.js, rect.js, arc.js, utils.js, рассмотрим их по порядку:
point.js:
Модуль point.js представляет собой точку (x, y), код следующий:
/** Точка */ define(function() { return function(x, y) { this.x = x; this.y = y; this.equals = function(point) { return this.x === point.x && this.y === point.y; }; }; )
В приведенном выше коде модуль точки определен с помощью define, в回调-функции возвращается класс, у которого есть два параметра x, y и метод equals для сравнения двух точек на равенство.
Чтобы использовать этот модуль, мы можем использовать следующий код:
require(['app/point'], function(Point) { // Создание объекта класса точки var point = new Point(3, 5); )
Здесь нужно обратить внимание, что первый параметр функции require() является массивом, в回调-функции Point представляет наш класс точки, который создается объект класса Point с помощью new Point().
line.js:
Модуль line.js представляет собой прямую, код следующий:
/** Прямая */ define(function() { return function(startPoint, endPoint) { this.startPoint = startPoint; this.endPoint = endPoint; this.drawMe = function(context) { context.strokeStyle = "#000000"; context.beginPath(); context.moveTo(this.startPoint.x, this.startPoint.y); context.lineTo(this.endPoint.x, this.endPoint.y); context.closePath(); context.stroke(); } } )
Определение модуля прямой аналогично определению модуля точки, оба они возвращают класс в回调 функции define, у класса прямой есть два параметра класса point, представляющие начальную и конечную точки прямой, класс прямой также имеет метод drawMe, который рисует саму прямую через传入 объект контекста.
rect.js:
Модуль rect.js represents a rectangle, the code is as follows:
/** Прямоугольник */ define(['app/point'], function() { return function(startPoint, width, height) { this.startPoint = startPoint; this.width = width; this.height = height; this.drawMe = function(context) { context.strokeStyle = "#000000"; context.strokeRect(this.startPoint.x, this.startPoint.y, this.width, this.height); } } )
Здесь startPoint является координатами точки в левом верхнем углу прямоугольника, это класс point, width и height соответственно представляют ширину и высоту прямоугольника, в то же время у него есть метод drawMe, который рисует прямоугольник сам.
arc.js:
Модуль arc.js represents a circle, the code is as follows:
/** Круг */ define(function() { return function(startPoint, radius) { this.startPoint = startPoint; this.radius = radius; this.drawMe = function(context) { context.beginPath(); context.arc(this.startPoint.x, this.startPoint.y, this.radius, 0, 2 * Math.PI); context.closePath(); context.stroke(); } } )
Где startPoint represents the coordinates of the top-left point of the rectangle in which the circle is located, radius represents the radius of the circle, and the drawMe method is the method to draw the circle.
В указанных выше модулях классы прямой, прямоугольника и круга содержат метод drawMe(), здесь используется знание canvas-рисования, если что-то непонятно, можно проверить документацию: Руководство по HTML 5 Canvas
utils.js
модуль utils.js主要用于 обработку различных инструментов рисования, включая рисование прямых, прямоугольников и кругов, а также запись и удаление траектории рисования, код приведен ниже:
/** Инструменты управления рисованием */ define(function() { var history = []; // массив для сохранения истории рисования, в котором хранятся объекты класса прямой, прямоугольника или круга function drawLine(context, line) { line.drawMe(context); } function drawRect(context, rect) { rect.drawMe(context); } function drawArc(context, arc) { arc.drawMe(context); } /** Добавить одну траекторию рисования */ function addHistory(item) { history.push(item); } /** Нанести историю траектории */ function drawHistory(context) { for(var i = 0; i < history.length; i++) { var obj = history[i]; obj.drawMe(context); } } /** Удалить историю траектории */ function clearHistory() { history = []; } return { drawLine: drawLine, drawRect: drawRect, drawArc: drawArc, addHistory: addHistory, drawHistory: drawHistory, clearHistory: clearHistory }; )
Третий раздел: написание кода интерфейса, обработка событий мыши
Верхняя часть уже определила все модули этой программы для простого рисования, используемые при рисовании图形 - это несколько модулей выше, теперь начнем писать код главного интерфейса, в котором содержатся четыре кнопки и большая доска для рисования, код файла index.html приведен ниже:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Простая программа для рисования</title> <style type="text/css"> canvas { background-color: #ECECEC; cursor: default; /** Установить курсор мыши по умолчанию */ } .tool-bar { margin-bottom: 10px; } </style> </head> <body> <div class="tool-bar"> <button id="btn-line">Рисовать прямую</button> <button id="btn-rect">Рисовать прямоугольник</button> <button id="btn-oval">Рисовать круг</button> <button id="btn-clear">Очистить холст</button> <span id="hint" style="color: red;">Текущая операция: рисовать прямую</span> </div> <canvas id="canvas" width="800" height="600"></canvas> <script type="text/javascript" src="js/require.min.js" data-main="js/main"></script> <script type="text/javascript"> require(['app/point', 'app/line', 'app/rect', 'app/arc', 'app/utils'], function(Point, Line, Rect, Arc, Utils) { var canvas = document.getElementById("canvas"); var context = canvas.getContext('2d'); var canvasRect = canvas.getBoundingClientRect(); // Получить прямоугольник, в котором находится canvas canvas.addEventListener('mousedown', handleMouseDown); canvas.addEventListener('mousemove', handleMouseMove); canvas.addEventListener('mouseup', handleMouseUp); bindClick('btn-clear', menuBtnClicked); bindClick('btn-line', menuBtnClicked); bindClick('btn-rect', menuBtnClicked); bindClick('btn-oval', menuBtnClicked); var mouseDown = false; var selection = 1; // 0, 1, 2 соответственно рисуют прямую, прямоугольник, круг var downPoint = new Point(0, 0), movePoint = new Point(0, 0), upPoint = new Point(0, 0); var line; var rect; var arc; /** Обработка события нажатия мыши */ function handleMouseDown(event) { downPoint.x = event.clientX - canvasRect.left; downPoint.y = event.clientY - canvasRect.top; if(selection === 0) { line = new Line(downPoint, downPoint); line.startPoint = downPoint; } else if(selection === 1) { rect = new Rect(new Point(downPoint.x, downPoint.y), 0, 0); } else if(selection === 2) { arc = new Arc(new Point(downPoint.x, downPoint.y), 0); } mouseDown = true; } /** Обработка события перемещения мыши */ function handleMouseMove(event) { movePoint.x = event.clientX - canvasRect.left; movePoint.y = event.clientY - canvasRect.top; if(movePoint.x == downPoint.x && movePoint.y == downPoint.y) { return ; } if(movePoint.x == upPoint.x && movePoint.y == upPoint.y) { return ; } if(mouseDown) { else if(domID == 'btn-line') { if(selection == 0) { line.endPoint = movePoint; Utils.drawLine(context, line); } rect.width = movePoint.x - downPoint.x; rect.height = movePoint.y - downPoint.y; Utils.drawRect(context, rect); Utils.drawHistory(context); var x = movePoint.x - downPoint.x; var y = movePoint.y - downPoint.y; arc.radius = x > y ? (y / 2) : (x / 2); if(arc.radius < 0) { arc.radius = -arc.radius; } arc.startPoint.x = downPoint.x + arc.radius; arc.startPoint.y = downPoint.y + arc.radius; Utils.drawArc(context, arc); } function clearCanvas() { } } /** Обработка события поднятия мыши */ function handleMouseUp(event) { upPoint.x = event.clientX - canvasRect.left; upPoint.y = event.clientY - canvasRect.top; if(mouseDown) { mouseDown = false; if(selection == 0) { line.endPoint = upPoint; if(!downPoint.equals(upPoint)) { Utils.addHistory(new Rect(new Point(downPoint.x, downPoint.y), rect.width, rect.height)); else if(selection == 2) { } } rect.width = upPoint.x - downPoint.x; rect.height = upPoint.y - downPoint.y; Utils.addHistory(new Arc(new Point(arc.startPoint.x, arc.startPoint.y), arc.radius)); Utils.drawHistory(context); /** Очистить холст */ } else if(domID == 'btn-line') { function clearCanvas() { } } context.clearRect(0, 0, canvas.width, canvas.height); /** Обработчик события клика по кнопке меню */ function menuBtnClicked(event) { } var domID = event.srcElement.id; if(domID === 'btn-clear') { clearCanvas(); Utils.clearHistory(); else if(domID == 'btn-line') { } selection = 0; showHint('Текущая операция: нарисовать прямую'); else if(domID == 'btn-rect') { } selection = 1; showHint('Текущая операция: нарисовать прямоугольник'); } else if(domID == 'btn-oval') { selection = 2; showHint('Текущая операция: нарисовать окружность'); } } function showHint(msg) { document.getElementById('hint').innerHTML = msg; } /** Bind click event to the corresponding id dom element */ function bindClick(domID, handler) { document.getElementById(domID).addEventListener('click', handler); } }); </script> </body> </html>
В файле index.html много кода, но самым важным кодом является监听和处理鼠标按下、移动、抬起三种事件, 另外, при получении координат мыши в canvas необходимо учитывать: координаты clientX и clientY, полученные из объекта event, представляют собой координаты мыши относительно страницы, чтобы получить координаты мыши в canvas, необходимо получить прямоугольную область canvas, а затем использовать clientX - canvas.left, clientY - canvas.top, чтобы получить положение мыши в canvas.
Исходный код
Исходный код в этом блоге хранится в github, нажмите здесь, чтобы просмотретьИсходный код
Известные ошибки
При рисовании круга нужно перетащить мышь от верхнего левого угла к нижнему правому углу, если это не так, положение круга будет неправильным.
Вот и все, что есть в этой статье, надеюсь, это поможет вам в изучении, также希望大家多多支持呐喊教程。
Заявление: содержимое этой статьи взято из Интернета, авторские права принадлежат соответствующему автору, контент предоставлен пользователями Интернета, сайт не имеет права собственности, не был отредактирован вручную, и не несет ответственности за соответствующие юридические последствия. Если вы обнаружите контент,涉嫌侵犯版权, пожалуйста, отправьте письмо по адресу: notice#oldtoolbag.com (при отправке письма замените # на @) для отчета,并提供 соответствующие доказательства. При подтверждении факта infringement, сайт немедленно удалят涉嫌侵权的内容。