最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

RequireJS簡易繪圖程序開發(fā)

 更新時間:2016年10月28日 15:41:54   作者:對面的小胖妞看過來  
這篇文章主要為大家詳細介紹了使用RequireJS簡易繪圖程序開發(fā),具有一定的參考價值,感興趣的小伙伴們可以參考一下

前言

RequireJS的出現(xiàn)讓前端代碼模塊化變得容易,當前端項目越來越大,代碼越來越多的時候,模塊化代碼讓項目結(jié)構(gòu)更清晰,不僅在開發(fā)時讓我們的思路更清晰,而且后期維護起來也更容易。下面是我學習RequireJS后使用RequireJS開發(fā)的一款簡易繪圖程序,運行在瀏覽器中如下圖所示:

如果你對RequireJS還不是很了解,可以看我的RequireJS學習筆記:http://blog.csdn.net/yubo_725/article/details/52913853

開始

這個簡易繪圖程序的項目結(jié)構(gòu)如下圖所示:

其中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中,代碼內(nèi)容如下:

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定義了點這個模塊,在回調(diào)函數(shù)中返回了一個類,該類有兩個參數(shù)x,y,還有一個equals方法用于比較兩個點是否相等。
要使用這個模塊,我們可以使用如下代碼:

require(['app/point'], function(Point) {
  //新建一個點類的對象
  var point = new Point(3, 5);
})

這里需要注意require()函數(shù)的第一個參數(shù)是一個數(shù)組,回調(diào)函數(shù)中的Point就代表了我們的點類,通過new Point()的方式創(chuàng)建點類的對象。

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的回調(diào)函數(shù)中返回一個類,這個直線類的構(gòu)造方法中有兩個點類的參數(shù),代表直線的起點和終點,直線類還有一個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 = []; //用來保存歷史繪制記錄的數(shù)組,里面存儲的是直線類、矩形類或者圓形類的對象

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

三、編寫界面代碼,處理鼠標事件

上面已經(jīng)將本次簡易繪圖程序的模塊都定義完了,在繪制圖形時用到的也就是上面幾個模塊,下面要開始編寫主界面的代碼了,主界面里包含四個按鈕,還有一塊大的畫布用于繪圖,下面直接上index.html文件的代碼:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>簡易繪圖程序</title>
  <style type="text/css">
    canvas {
      background-color: #ECECEC;
      cursor: default; /** 鼠標設(shè)置成默認的指針 */
    }
    .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;
      }

      /** 給對應(yīng)id的dom元素綁定點擊事件 */
      function bindClick(domID, handler) {
        document.getElementById(domID).addEventListener('click', handler);
      }
    });
  </script>
</body>
</html>

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

源碼

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

已知bug

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

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • JS正則獲取HTML元素的方法

    JS正則獲取HTML元素的方法

    這篇文章主要介紹了JS正則獲取HTML元素的方法,結(jié)合實例形式分析了JS針對頁面HTML元素正則操作相關(guān)技巧與注意事項,需要的朋友可以參考下
    2017-03-03
  • 深入理解javascript嚴格模式(Strict Mode)

    深入理解javascript嚴格模式(Strict Mode)

    Strict mode是JavaScript1.8.5引進的技術(shù),但還沒有瀏覽器確實可靠的實現(xiàn)了嚴格模式,所以使用時要小心并且多測試。Strict mode可以應(yīng)用于整個腳本,也可以適合于單個函數(shù)。
    2014-11-11
  • JS平滑無縫滾動效果的實現(xiàn)代碼

    JS平滑無縫滾動效果的實現(xiàn)代碼

    下面小編就為大家?guī)硪黄狫S平滑無縫滾動效果的實現(xiàn)代碼。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考
    2016-05-05
  • Google 二維條碼 API 整理

    Google 二維條碼 API 整理

    Google 二維條碼 API 整理,需要的朋友可以參考下。
    2010-11-11
  • uniapp使用uni.chooseLocation()打開地圖選擇位置詳解

    uniapp使用uni.chooseLocation()打開地圖選擇位置詳解

    這篇文章主要給大家介紹了關(guān)于uniapp使用uni.chooseLocation()打開地圖選擇位置的相關(guān)資料,因為最近在項目中遇到一個要用戶授權(quán)位置且可以用戶自己選擇位置的功能,需要的朋友可以參考下
    2023-06-06
  • ES6入門教程之Iterator與for...of循環(huán)詳解

    ES6入門教程之Iterator與for...of循環(huán)詳解

    最近在學習ES6,剛剛看到Iterator和for...of循環(huán)這一章,所以想要跟大家略微分享一下,下面這篇文章主要給大家介紹了關(guān)于ES6入門學習中Iterator與for...of循環(huán)的相關(guān)資料,不足之處還望大家多多指正,需要的朋友們可以參考學習。
    2017-05-05
  • javascript隨機將第一個dom中的圖片添加到第二個div中示例

    javascript隨機將第一個dom中的圖片添加到第二個div中示例

    此代碼的是一個簡單的例子,將第一個div中的五張圖片中,提取隨機兩張顯示到第二個div中,具體實現(xiàn)如下,感興趣的朋友可以參考下
    2013-10-10
  • js 輸出內(nèi)容到新窗口具體實現(xiàn)代碼

    js 輸出內(nèi)容到新窗口具體實現(xiàn)代碼

    js 輸出內(nèi)容一般都是在本窗口,如果要實現(xiàn)在新窗口的話該如何實現(xiàn)呢?下面與大家分享具體的代碼
    2013-05-05
  • uniapp使用uni自帶websocket進行即時通訊詳細步驟

    uniapp使用uni自帶websocket進行即時通訊詳細步驟

    在開發(fā)程序過程中通信功能還是比較常用到的,下面這篇文章主要給大家介紹了關(guān)于uniapp使用uni自帶websocket進行即時通訊的詳細步驟,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-11-11
  • js圖片模糊切換顯示特效的方法

    js圖片模糊切換顯示特效的方法

    這篇文章主要介紹了js圖片模糊切換顯示特效的方法,涉及js操作圖片特效的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02

最新評論

云林县| 特克斯县| 濉溪县| 昌都县| 报价| 凉山| 台中县| 蚌埠市| 土默特右旗| 奇台县| 长宁县| 吉水县| 将乐县| 额尔古纳市| 时尚| 康马县| 胶南市| 行唐县| 永州市| 西青区| 汕头市| 阿拉尔市| 金堂县| 喀喇| 江都市| 云浮市| 呈贡县| 扎囊县| 乌什县| 清水河县| 大安市| 民权县| 青神县| 石阡县| 库车县| 房产| 大关县| 东光县| 禄丰县| 泉州市| 太仆寺旗|