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文件,js/main.js为requirejs的配置文件,主要是配置一些路径,js/require.min.js是RequireJS框架的文件。下面请跟我一步一步完成这个简易的绘图程序吧!
一、配置requirejs
本项目的配置文件代码放在js/main.js中,代码内容如下:
require.config({ baseUrl: 'js'/lib',}} paths: { app: '../app' } })
Es wurde hauptsächlich die Projektbasis konfiguriert als 'js'/Verzeichnis 'lib', dann wurde ein Pfad 'app' konfiguriert, der Pfad ist '..'/Verzeichnis 'app', d.h. 'js'/Verzeichnis 'app'
Zwei, Modulcode schreiben
Die Module in diesem Projekt sind hauptsächlich: point.js, line.js, rect.js, arc.js, utils.js. Sie werden nacheinander erläutert:
point.js:
Der Modul 'point.js' repräsentiert einen Punkt (x, y), der Quellcode lautet wie folgt:
/** Punkt */ 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 definiert den Modul 'Punkt' mit define, gibt in der Callback-Funktion eine Klasse zurück, die zwei Parameter x, y hat und eine Methode equals, um zu vergleichen, ob zwei Punkte gleich sind.
Um diesen Modul zu verwenden, können wir den folgenden Code verwenden:
require(['app/point'], function(Point) { //Ein Objekt der Klasse Punkt neu erstellen var point = new Point(3, 5); })
Hier ist zu beachten, dass der erste Parameter der require()-Funktion ein Array ist, und der Punkt im Callback-Funktion repräsentiert unsere Punkt-Klasse. Durch new Point() wird ein Objekt der Punkt-Klasse erstellt.
line.js:
Der Modul 'line.js' repräsentiert eine Linie, der Quellcode lautet wie folgt:
/** Linie */ 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 Linienmoduls ähnelt der Definition des Punktemoduls, beide liefern in der Callback-Funktion von define eine Klasse zurück. Der Konstruktor der Linienklasse hat zwei Parameter vom Typ Punkt, die den Anfangs- und Endpunkt der Linie darstellen. Die Linienklasse verfügt ebenfalls über eine Methode drawMe, die durch Übergeben eines Kontextobjekts das Linienobjekt selbst zeichnet.
rect.js:
Der Modul 'rect.js' repräsentiert ein Rechteck, der Quellcode lautet wie folgt:
/** Rechteck */ 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模块代表一个圆形,代码如下:
/** 圆形 */ 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代表圆形所在的矩形的左上角的点的坐标,radius代表圆的半径,drawMe方法是画圆的方法。
在以上几个模块中,直线类、矩形类、圆形类都包含有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); } /** Fügen Sie einen Zeichnungsverlauf hinzu */ function addHistory(item) { history.push(item); } /** Zeichnen Sie den historischen Verlauf */ function drawHistory(context) { for(var i = 0; i < history.length; i++) { var obj = history[i]; obj.drawMe(context); } } /** Löschen Sie den historischen Verlauf */ function clearHistory() { history = []; } return { drawLine: drawLine, drawRect: drawRect, drawArc: drawArc, addHistory: addHistory, drawHistory: drawHistory, clearHistory: clearHistory }; })
Drei. Schreiben Sie die Benutzeroberfläche, verarbeiten Sie die Mausereignisse
Die Module dieses einfachen Zeichenprogramms sind bereits definiert. Bei der Zeichnung der Grafiken werden nur die oben genannten Module verwendet. Jetzt wird der Code für die Hauptoberfläche geschrieben. Die Hauptoberfläche enthält vier Schaltflächen und ein großes Zeichenblatt zum Zeichnen. Der Code des index.html-Datei wird direkt gezeigt:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Einfaches Zeichenprogramm</title> <style type="text/css"> canvas { background-color: #ECECEC; cursor: default; /** Die Mauszeiger auf den Standardzeiger setzen */ } .tool-bar { margin-bottom: 10px; } </style> </head> <body> <div class="tool-bar"> <button id="btn-line">Zeichnen einer Linie</button> <button id="btn-rect">Zeichnen eines Rechtecks</button> <button id="btn-oval">Zeichnen eines Kreises</button> <button id="btn-clear">Leeren Sie das Zeichenblatt</button> <span id="hint" style="color: rot;">Aktuelle Aktion: Zeichnen einer Linie</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(); //Erhalten des Rechtecks, in dem sich das canvas befindet 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, 2stehen für das Zeichnen einer Linie, eines Rechtecks und eines Kreises var downPoint = new Point(0, 0), movePoint = new Point(0, 0), upPoint = new Point(0, 0); var line; var rect; var arc; /** Verarbeitung des Mausdrückereignisses */ 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; } 1) { rect = new Rect(new Point(downPoint.x, downPoint.y), 0, 0); } 2) { arc = new Arc(new Point(downPoint.x, downPoint.y), 0); } mouseDown = true; } /** Verarbeitung des Ereignisses, wenn die Maus bewegt wird */ 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 &63; (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); } } /** Verarbeitung des Ereignisses, wenn die Maustaste losgelassen wird */ 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 === '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; } /** Klicken Sie auf das DOM-Element mit der entsprechenden ID, um das Klickereignis zu binden */ function bindClick(domID, handler) { document.getElementById(domID).addEventListener('click', handler); } }); </script> </body> </html>
Es gibt viel Code im index.html-Datei, aber der wichtigste Code ist die Überwachung und Verarbeitung der drei Ereignisse Mausdrücken, Bewegen und Loslassen. Außerdem müssen Sie darauf achten, dass die Koordinaten des Mauszeigers im Canvas ermittelt werden: Da die clientX und clientY im event-Objekt die Koordinaten des Mauszeigers relativ zur Seite sind, müssen Sie das Rechteck, in dem sich das Canvas befindet, erhalten, um die Koordinaten des Mauszeigers im Canvas zu erhalten, und verwenden Sie dann clientX-canvas.left, clientY-canvas.top, um die Position des Mauszeigers im Canvas zu erhalten.
Quellcode
Der Quellcode dieses Blogs ist auf GitHub gehostet. Klicken Sie hier, um zu sehen.Quellcode
Bekannter Bug
Bei der Zeichnung eines Kreises müssen Sie den Mauszeiger von der linken oberen Ecke nach der rechten unteren Ecke ziehen, um einen Kreis zu zeichnen. Wenn dies nicht der Fall ist, kann sich die Position des Kreises ändern.
Das ist der gesamte Inhalt dieses Artikels. Wir hoffen, dass er Ihnen bei Ihrem Lernen hilft und dass Sie die Anstrengungen des呐喊教程 unterstützen.
Erklärung: Der Inhalt dieses Artikels wurde aus dem Internet übernommen und gehört dem Urheberrechtlichem Inhaber. Der Inhalt wurde von Internetnutzern freiwillig beigesteuert und hochgeladen. Diese Website besitzt keine Eigentumsrechte und hat den Inhalt nicht manuell bearbeitet. Sie übernimmt auch keine Haftung für rechtliche Verantwortlichkeiten. Wenn Sie Inhalte mit涉嫌版权 finden, sind Sie herzlich eingeladen, eine E-Mail an notice#w zu senden.3codebox.com (Bitte ersetzen Sie # durch @, wenn Sie eine E-Mail senden, um zu melden, und fügen Sie relevante Beweise bei. Sobald die Informationen überprüft sind, wird diese Website die涉嫌侵权的内 容立即删除。)