国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

RequireJS簡易繪圖程序開發

2019-11-20 08:38:10
字體:
來源:轉載
供稿:網友

前言

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'  }})

主要就是配置了項目根目錄為'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就代表了我們的點類,通過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的回調函數中返回一個類,這個直線類的構造方法中有兩個點類的參數,代表直線的起點和終點,直線類還有一個drawMe方法,通過傳入一個context對象,將自身畫出來。

rect.js:

rect.js模塊代表一個矩形,代碼如下:

/** 矩形 */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);  }  /** 添加一條繪制軌跡 */  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) {          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 === '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;      }      /** 給對應id的dom元素綁定點擊事件 */      function bindClick(domID, handler) {        document.getElementById(domID).addEventListener('click', handler);      }    });  </script></body></html>

index.html文件中的代碼比較多,但最主要的代碼還是對鼠標按下、移動、抬起三種事件的監聽和處理,另外,獲取鼠標在canvas中的坐標位置需要注意一點:由于event對象中獲取的clientX和clientY是鼠標相對于頁面的坐標,為了獲取鼠標在canvas中的坐標,需要獲得canvas所在的矩形區域,然后用clientX-canvas.left,clientY-canvas.top,來獲取鼠標在canvas中的位置。

源碼

本篇博客中的源碼已托管到github,點擊這里查看源碼

已知bug

在畫圓形時需要鼠標從左上角拖到右下角畫圓,如果不是這樣,圓的位置會有問題。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 平阴县| 曲阳县| 益阳市| 太和县| 托克逊县| 泗阳县| 泰来县| 黔西县| 武平县| 资源县| 额敏县| 静安区| 台江县| 鞍山市| 南京市| 江西省| 明水县| 杭锦后旗| 大港区| 枣强县| 通渭县| 毕节市| 焦作市| 沭阳县| 商洛市| 济南市| 简阳市| 辉南县| 松滋市| 莎车县| 长沙市| 财经| 高邮市| 光山县| 汤阴县| 衡南县| 石景山区| 安阳县| 灵武市| 青州市| 玉溪市|