亚洲欧美日韩综合系列在线_91精品人妻一区二区_欧美大肥婆一级特大AA片_九色91视频免费观看_亚洲综合国产精品_av中文字幕在线不卡_久久精品色综合网_看黄色视频的软件_无卡无码高清中文字幕码2024_亚洲欧美日韩天堂网

Web前端項(xiàng)目實(shí)戰(zhàn)——使用RequireJS開(kāi)發(fā)簡(jiǎn)易繪圖程序

來(lái)源:yubo_725 發(fā)布時(shí)間:2018-11-22 14:30:36 閱讀量:1084

前言

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

 

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


開(kāi)始

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

 

其中index.html是項(xiàng)目的主頁(yè),js目錄下存放所有js文件,js/app目錄為我們自定義的模塊文件,js/lib目錄中暫時(shí)沒(méi)有文件,當(dāng)我們的項(xiàng)目里用到一些其他前端框架如jquery等時(shí),js/lib目錄就存放這些框架的js文件,js/main.js為requirejs的配置文件,主要是配置一些路徑,js/require.min.js是RequireJS框架的文件。下面請(qǐng)跟我一步一步完成這個(gè)簡(jiǎn)易的繪圖程序吧!


一、配置requirejs

本項(xiàng)目的配置文件代碼放在js/main.js中,代碼內(nèi)容如下:


require.config({

    baseUrl: 'js/lib',

    paths: {

        app: '../app'

    }

})

1

2

3

4

5

6

主要就是配置了項(xiàng)目根目錄為’js/lib’,然后配置了一個(gè)名為’app’的路徑,路徑為’../app’,即’js/app’目錄。


二、編寫模塊代碼

這個(gè)項(xiàng)目中的模塊主要有如下幾個(gè):point.js, line.js, rect.js, arc.js, utils.js,下面一一說(shuō)明:


point.js:

point.js這個(gè)模塊代表一個(gè)點(diǎn)(x, y),代碼如下:


/** 點(diǎn) */

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;

        };

    };

})

1

2

3

4

5

6

7

8

9

10

上面的代碼中使用define定義了點(diǎn)這個(gè)模塊,在回調(diào)函數(shù)中返回了一個(gè)類,該類有兩個(gè)參數(shù)x,y,還有一個(gè)equals方法用于比較兩個(gè)點(diǎn)是否相等。 

要使用這個(gè)模塊,我們可以使用如下代碼:


require(['app/point'], function(Point) {

    //新建一個(gè)點(diǎn)類的對(duì)象

    var point = new Point(3, 5);

})

1

2

3

4

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


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

        }

    }

})

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

直線模塊的定義跟點(diǎn)模塊的定義類似,都是在define的回調(diào)函數(shù)中返回一個(gè)類,這個(gè)直線類的構(gòu)造方法中有兩個(gè)點(diǎn)類的參數(shù),代表直線的起點(diǎn)和終點(diǎn),直線類還有一個(gè)drawMe方法,通過(guò)傳入一個(gè)context對(duì)象,將自身畫(huà)出來(lái)。


rect.js:

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


/** 矩形 */

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

        }

    }

})

1

2

3

4

5

6

7

8

9

10

11

12

其中startPoint是矩形左上角的點(diǎn)的坐標(biāo),是一個(gè)point類,width和height分別代表矩形的寬高,同時(shí)還有一個(gè)drawMe方法將矩形自身畫(huà)出來(lái)。


arc.js:

arc.js模塊代表一個(gè)圓形,代碼如下:


/** 圓形 */

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

        }

    }

})

1

2

3

4

5

6

7

8

9

10

11

12

13

其中startPoint代表圓形所在的矩形的左上角的點(diǎn)的坐標(biāo),radius代表圓的半徑,drawMe方法是畫(huà)圓的方法。 

在以上幾個(gè)模塊中,直線類、矩形類、圓形類都包含有drawMe()方法,這里涉及到了canvas繪圖的知識(shí),如果有不太清楚的,可以查一下文檔:HTML 5 Canvas 參考手冊(cè)


utils.js

utils.js模塊主要是用來(lái)處理各種圖形繪制的工具類,包括直線、矩形、圓形的繪制,也包括記錄繪制軌跡、清除繪制軌跡,代碼如下:


/** 管理繪圖的工具 */

define(function() { 

    var history = []; //用來(lái)保存歷史繪制記錄的數(shù)組,里面存儲(chǔ)的是直線類、矩形類或者圓形類的對(duì)象


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

    }


    /** 畫(huà)出歷史軌跡 */

    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

    };

})

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

三、編寫界面代碼,處理鼠標(biāo)事件

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


<!DOCTYPE html>

<html>

<head>

    <meta charset="UTF-8">

    <title>簡(jiǎn)易繪圖程序</title>

    <style type="text/css">

        canvas {

            background-color: #ECECEC;

            cursor: default; /** 鼠標(biāo)設(shè)置成默認(rèn)的指針 */

        }

        .tool-bar {

            margin-bottom: 10px;

        }

    </style>

</head>

<body>

    <div>

        <button id="btn-line">畫(huà)直線</button>

        <button id="btn-rect">畫(huà)矩形</button>

        <button id="btn-oval">畫(huà)圓形</button>

        <button id="btn-clear">清空畫(huà)布</button>

        <span id="hint" style="color: red;">當(dāng)前操作:畫(huà)直線</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分別代表畫(huà)直線、畫(huà)矩形、畫(huà)圓


            var downPoint = new Point(0, 0),  

                movePoint = new Point(0, 0), 

                upPoint = new Point(0, 0);

            var line;

            var rect;

            var arc;


            /** 處理鼠標(biāo)按下的事件 */

            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;

            }


            /** 處理鼠標(biāo)移動(dòng)的事件 */

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

                }

            }


            /** 處理鼠標(biāo)抬起的事件 */

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

                }

            }


            /** 清空畫(huà)布 */

            function clearCanvas() {

                context.clearRect(0, 0, canvas.width, canvas.height);

            }


            /** 菜單按鈕的點(diǎn)擊事件處理 */

            function menuBtnClicked(event) {

                var domID = event.srcElement.id;

                if(domID === 'btn-clear') {

                    clearCanvas();

                    Utils.clearHistory();

                } else if(domID == 'btn-line') {

                    selection = 0;

                    showHint('當(dāng)前操作:畫(huà)直線');

                } else if(domID == 'btn-rect') {

                    selection = 1;

                    showHint('當(dāng)前操作:畫(huà)矩形');

                } else if(domID == 'btn-oval') {

                    selection = 2;

                    showHint('當(dāng)前操作:畫(huà)圓形');

                }

            }


            function showHint(msg) {

                document.getElementById('hint').innerHTML = msg;

            }


            /** 給對(duì)應(yīng)id的dom元素綁定點(diǎn)擊事件 */

            function bindClick(domID, handler) {

                document.getElementById(domID).addEventListener('click', handler);

            }

        });

    </script>

</body>

</html>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

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

--------------------- 



標(biāo)簽: PHP
分享:
評(píng)論:
你還沒(méi)有登錄,請(qǐng)先