English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Простая программа для рисования с использованием RequireJS

Введение

Появление 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, сайт немедленно удалят涉嫌侵权的内容。

Тебе понравится