Heim  >  Artikel  >  Web-Frontend  >  Einfache Entwicklung eines Zeichenprogramms mit RequireJS

Einfache Entwicklung eines Zeichenprogramms mit RequireJS

高洛峰
高洛峰Original
2016-12-08 14:11:311191Durchsuche

Vorwort

Das Aufkommen von RequireJS erleichtert die Modularisierung von Frontend-Code. Wenn Frontend-Projekte immer größer werden und es immer mehr Codes gibt, macht modularer Code die Projektstruktur klarer. nicht nur während der Entwicklung Es macht unser Denken klarer und erleichtert die spätere Pflege. Das Folgende ist ein einfaches Zeichenprogramm, das ich mit RequireJS entwickelt habe, nachdem ich RequireJS gelernt habe. Es läuft im Browser wie unten gezeigt:

Einfache Entwicklung eines Zeichenprogramms mit RequireJS

Starten

Dieses einfache Projekt Die Struktur des Zeichenprogramms ist wie folgt:

wobei index.html die Homepage des Projekts ist, alle js-Dateien im js-Verzeichnis gespeichert sind, das js/app-Verzeichnis unsere angepasste Moduldatei ist und die Das Verzeichnis js/lib ist derzeit nicht vorhanden. Wenn in unserem Projekt andere Front-End-Frameworks wie jquery verwendet werden, werden die js-Dateien dieser Frameworks im Verzeichnis js/main.js gespeichert Konfigurationsdatei von requirejs, die hauptsächlich einige Pfade konfiguriert, js /require.min.js ist die Datei des RequireJS-Frameworks. Bitte folgen Sie mir Schritt für Schritt, um dieses einfache Zeichenprogramm fertigzustellen!

1. Konfigurieren Sie requirejs

Der Konfigurationsdateicode dieses Projekts wird in js/main.js abgelegt. Der Codeinhalt lautet wie folgt:

require.config({
  baseUrl: 'js/lib',
  paths: {
    app: '../app'
  }
})


Die Hauptsache ist, das Stammverzeichnis des Projekts als „js/lib“ zu konfigurieren und dann einen Pfad mit dem Namen „app“ zu konfigurieren. Der Pfad lautet „../app“. das heißt, 'js/app' Inhaltsverzeichnis.

2. Modulcode schreiben

Die Module in diesem Projekt umfassen hauptsächlich die folgenden: point.js, line.js, rect.js, arc.js, utils.js, das folgende Eine Beschreibung:

point.js:

point.js Dieses Modul stellt einen Punkt (x, y) dar, der Code lautet wie folgt:

/** 点 */
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;
    };
  };
})


Der obige Code verwendet define, um dieses Modul zu definieren, und gibt eine Klasse in der Rückruffunktion zurück. Diese Klasse verfügt über zwei Parameter x, y und eine Gleichheitsmethode zum Vergleichen der beiden Parameter . Sind die Punkte gleich?
Um dieses Modul zu verwenden, können wir den folgenden Code verwenden:

require(['app/point'], function(Point) {
  //新建一个点类的对象
  var point = new Point(3, 5);
})


Hier müssen Sie auf den ersten Parameter von achten die Funktion require() Es ist ein Array. Der Punkt in der Rückruffunktion stellt unsere Punktklasse dar, und das Punktklassenobjekt wird durch new Point() erstellt.

line.js:

Das Modul line.js stellt eine gerade Linie dar. Der Code lautet wie folgt:

/** 直线 */
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();
    }
  }
})


Die Definition des Geradenmoduls ähnelt der Definition des Punktmoduls. Beide geben eine Klasse in der Definitionsrückruffunktion zurück. Es gibt zwei Punktklassenparameter in der Konstruktionsmethode dieser Geradenklasse Der Startpunkt und der Endpunkt der geraden Linie. Es gibt auch eine drawMe-Methode, die sich selbst zeichnet, indem sie ein Kontextobjekt übergibt.

rect.js:

rect.js-Modul stellt ein Rechteck dar, der Code lautet wie folgt:

/** 矩形 */
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);
    }
  }
})


wobei startPoint ist die obere linke Ecke des Rechtecks. Die Koordinaten der Eckpunkte sind eine Punktklasse. Breite und Höhe repräsentieren die Breite bzw. Höhe des Rechtecks. Es gibt auch eine drawMe-Methode zum Zeichnen des Rechtecks.

arc.js:

arc.js-Modul stellt einen Kreis dar, der Code lautet wie folgt:

/** 圆形 */
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();
    }
  }
})


Wobei startPoint die Koordinaten der oberen linken Ecke des Rechtecks ​​darstellt, in der sich der Kreis befindet, radius den Radius des Kreises darstellt und die Methode drawMe die Methode zum Zeichnen eines Kreises ist.
In den oben genannten Modulen enthalten die Klasse „Gerade Linie“, die Klasse „Rechteck“ und die Klasse „Kreis“ alle die Methode drawMe(), die Kenntnisse über das Zeichnen von Leinwand erfordert. Wenn Sie sich nicht sicher sind, können Sie das Dokument überprüfen: HTML 5 Canvas Referenzhandbuch

utils.js

Das Modul utils.js wird hauptsächlich zur Verarbeitung verschiedener grafischer Zeichenwerkzeuge verwendet, darunter das Zeichnen von geraden Linien, Rechtecken und Kreisen sowie das Aufzeichnen von Zeichentrajektorien , Löschen Sie die Zeichenspur.

/** 管理绘图的工具 */
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
  };
})

Die oben genannten Module werden beim Zeichnen von Grafiken verwendet Die Hauptoberfläche enthält vier Schaltflächen und eine große Leinwand zum Zeichnen. Der Code der Datei index.html wird unten direkt hochgeladen:


Es gibt viele Codes in der Datei index.html, aber das Wichtigste ist, dass der Code weiterhin die drei Ereignisse des Drückens, Bewegens und Hebens der Maus überwacht und verarbeitet. Darüber hinaus ist eines zu beachten Ermitteln der Koordinatenposition der Maus auf der Leinwand: Da die im Ereignisobjekt erhaltenen clientX und clientY die Koordinaten der Maus relativ zur Seite sind, müssen Sie die Koordinaten der Maus auf der Leinwand ermitteln Erstellen Sie einen rechteckigen Bereich, in dem sich die Leinwand befindet, und verwenden Sie dann clientX-canvas.left und clientY-canvas.top, um die Position der Maus auf der Leinwand zu ermitteln.
<!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([&#39;app/point&#39;, &#39;app/line&#39;, &#39;app/rect&#39;, &#39;app/arc&#39;, &#39;app/utils&#39;],
      function(Point, Line, Rect, Arc, Utils) {
 
      var canvas = document.getElementById("canvas");
      var context = canvas.getContext(&#39;2d&#39;);
      var canvasRect = canvas.getBoundingClientRect(); //得到canvas所在的矩形
      canvas.addEventListener(&#39;mousedown&#39;, handleMouseDown);
      canvas.addEventListener(&#39;mousemove&#39;, handleMouseMove);
      canvas.addEventListener(&#39;mouseup&#39;, handleMouseUp);
      bindClick(&#39;btn-clear&#39;, menuBtnClicked);
      bindClick(&#39;btn-line&#39;, menuBtnClicked);
      bindClick(&#39;btn-rect&#39;, menuBtnClicked);
      bindClick(&#39;btn-oval&#39;, 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) {
          clearCanvas();
          if(selection == 0) {
            line.endPoint = movePoint;
            Utils.drawLine(context, line);
          } else if(selection == 1) {
            rect.width = movePoint.x - downPoint.x;
            rect.height = movePoint.y - downPoint.y;
            Utils.drawRect(context, rect);
          } else if(selection == 2) {
            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);
          }
          Utils.drawHistory(context);
        }
      }
 
      /** 处理鼠标抬起的事件 */
      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 Line(new Point(downPoint.x, downPoint.y),
                new Point(upPoint.x, upPoint.y)));
            } 
          } else if(selection == 1) {
            rect.width = upPoint.x - downPoint.x;
            rect.height = upPoint.y - downPoint.y;
            Utils.addHistory(new Rect(new Point(downPoint.x, downPoint.y), rect.width, rect.height));
          } else if(selection == 2) {
            Utils.addHistory(new Arc(new Point(arc.startPoint.x, arc.startPoint.y), arc.radius));
          }
          clearCanvas();
          Utils.drawHistory(context);
        }
      }
 
      /** 清空画布 */
      function clearCanvas() {
        context.clearRect(0, 0, canvas.width, canvas.height);
      }
 
      /** 菜单按钮的点击事件处理 */
      function menuBtnClicked(event) {
        var domID = event.srcElement.id;
        if(domID === &#39;btn-clear&#39;) {
          clearCanvas();
          Utils.clearHistory();
        } else if(domID == &#39;btn-line&#39;) {
          selection = 0;
          showHint(&#39;当前操作:画直线&#39;);
        } else if(domID == &#39;btn-rect&#39;) {
          selection = 1;
          showHint(&#39;当前操作:画矩形&#39;);
        } else if(domID == &#39;btn-oval&#39;) {
          selection = 2;
          showHint(&#39;当前操作:画圆形&#39;);
        }
      }
 
      function showHint(msg) {
        document.getElementById(&#39;hint&#39;).innerHTML = msg;
      }
 
      /** 给对应id的dom元素绑定点击事件 */
      function bindClick(domID, handler) {
        document.getElementById(domID).addEventListener(&#39;click&#39;, handler);
      }
    });
  </script>
</body>
</html>

Bekannte Fehler

Beim Zeichnen eines Kreises müssen Sie die Maus von der oberen linken Ecke in die untere rechte Ecke ziehen, um den Kreis zu zeichnen. Andernfalls kann es zu Problemen mit der Position kommen des Kreises.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn