Home > Web Front-end > HTML Tutorial > How to make a drawing software similar to windows using html5

How to make a drawing software similar to windows using html5

一个新手
Release: 2017-10-19 09:56:21
Original
2189 people have browsed it

I haven’t finished this drawing tool yet, but it has implemented the general structure and common simple graphics drawing functions:

1. It can draw straight lines, circles, rectangles, and regular polygons [Completed]

2. Selection of fill color and stroke color [Completed]

3. Selection of stroke and fill functions [Completed]

Subsequent version:

Eraser, coordinate system, line settings, arrows, other process graphics, cropping and adjustment graphics. . . . .

Ultimate goal:

Process drawing software

I saw a friend leave a message on my blog before and said:

Thank you very much for this friend. Today I finally took the time to complete a very, very small prototype!

Please open the complete prototype code yourself and copy it to local testing.


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

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <meta http-equiv="X-UA-Compatible" content="ie=edge">

    <title>windows简易画图工具 - by ghostwu</title>

</head>

 

<body>

    <div class="paint">

        <div class="paint-header">

            <ul>

                <li class="active">形状</li>

                <li>颜色</li>

                <li>绘制类型</li>

                <li>线条宽度</li>

                <li>橡皮擦</li>

            </ul>

        </div>

        <div class="paint-body">

            <div class="siderbar">

                <div class="item active" data-type="paint-shape">

                    <ul>

                        <li class="active" data-role="line">线条</li>

                        <li data-role="circle">圆形</li>

                        <li data-role="rect">矩形</li>

                        <li data-role="polygon">正多边形</li>

                        <li data-role="arrow">箭头</li>

                    </ul>

                </div>

                <div class="item" data-type="paint-color">

                    <ul>

                        <li data-role="strokeStyle">

                            <input type="color" data-role="strokeStyle">

                        </li>

                        <li data-role="fillStyle">

                            <input type="color" data-role="fillStyle">

                        </li>

                    </ul>

                </div>

                <div class="item" data-type="paint-type">

                    <ul>

                        <li data-role="stroke">描边</li>

                        <li data-role="fill">填充</li>

                    </ul>

                </div>

                <div class="item" data-type="paint-line">

                    <ul>

                        <li data-role="1">小号</li>

                        <li data-role="4">中号</li>

                        <li data-role="7">大号</li>

                        <li>

                            <input type="number" data-role="line-size" placeholder="请输入数字">

                        </li>

                    </ul>

                </div>

                <div class="item" data-type="paint-erase">

                    <ul>

                        <li>

                            <input type="number" data-role="erase-size" placeholder="请输入数字">

                        </li>

                    </ul>

                </div>

            </div>

        </div>

    </div>

    <script>// <![CDATA[

        var oPaintBody = document.querySelector( &#39;.paint-body&#39; );

        var oC = document.createElement( &#39;canvas&#39; );

        oC.setAttribute( &#39;width&#39;, &#39;830&#39; );

        oC.setAttribute( &#39;height&#39;, &#39;500&#39; );

        oPaintBody.appendChild( oC );

        var aHeaderLi = document.querySelectorAll(&#39;.paint-header li&#39;),

            aItem = document.querySelectorAll(&#39;.paint-body .item&#39;),

            oCanvas = document.querySelector(&#39;.paint canvas&#39;),

            oGc = oCanvas.getContext(&#39;2d&#39;),

            cWidth = oCanvas.width, cHeight = oCanvas.height,

            curItem = aItem[0],

            aItemLi = curItem.querySelectorAll(&#39;li&#39;);

 

        for (let i = 0, len = aHeaderLi.length; i < len; i++) { //头部选项卡切换功能

            aHeaderLi[i].onclick = function () {

                for (let j = 0; j < len; j++) {

                    aHeaderLi[j].classList.remove(&#39;active&#39;);

                    aItem[j].style.display = &#39;none&#39;;

                }

                aItem[i].style.display = "block";

                this.classList.add(&#39;active&#39;);

                curItem = aItem[i];

                aItemLi = curItem.querySelectorAll(&#39;li&#39;);

                activeItem(aItemLi);

            }

        }

        activeItem(aItemLi);

        var role = null;

        function activeItem(aItemLi) { //canvas左侧选项卡切换功能

            for (let i = 0, len = aItemLi.length; i < len; i++) {

                aItemLi[i].onclick = function () {

                    checkPaintType(this); //绘制类型

                    for (let j = 0; j < len; j++) {

                        aItemLi[j].classList.remove(&#39;active&#39;);

                    }

                    this.classList.add(&#39;active&#39;);

                }

            }

        }

 

        function Shape(canvasObj, cxtObj, w, h) {

            this.oCanvas = canvasObj;

            this.oGc = cxtObj;

            this.oCanvas.width = w;

            this.oCanvas.height = h;

            this.fillStyle = &#39;#000&#39;;

            this.storkeStyle = &#39;#000&#39;;

            this.lineWidth = 1;

            this.drawType = &#39;line&#39;;

            this.paintType = &#39;stroke&#39;;

            this.nums = 6; //正多边形的边数

        }

 

        Shape.prototype = {

            init: function () {

                this.oGc.fillStyle = this.fillStyle;

                this.oGc.strokeStyle = this.strokeStyle;

                this.oGc.lineWidth = this.lineWidth;

            },

            draw: function () {

                var _this = this;

                this.oCanvas.onmousedown = function (ev) {

                    _this.init();

                    var oEvent = ev || event,

                        startX = oEvent.clientX - _this.oCanvas.offsetLeft,

                        startY = oEvent.clientY - _this.oCanvas.offsetTop;

                    _this.oCanvas.onmousemove = function (ev) {

                        _this.oGc.clearRect(0, 0, _this.oCanvas.width, _this.oCanvas.height);

                        var oEvent = ev || event,

                            endX = oEvent.clientX - _this.oCanvas.offsetLeft,

                            endY = oEvent.clientY - _this.oCanvas.offsetTop;

                        _this[_this.drawType](startX, startY, endX, endY);

                    };

                    _this.oCanvas.onmouseup = function () {

                        _this.oCanvas.onmousemove = null;

                        _this.oCanvas.onmouseup = null;

                    }

                }

            },

            line: function (x1, y1, x2, y2) {

                this.oGc.beginPath();

                this.oGc.moveTo(x1, y1);

                this.oGc.lineTo(x2, y2);

                this.oGc.closePath();

                this.oGc.stroke();

            },

            circle: function (x1, y1, x2, y2) {

                this.oGc.beginPath();

                var r = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));

                this.oGc.arc(x1, y1, r, 0, 2 * Math.PI, false);

                this.oGc.closePath();

                this.oGc[this.paintType]();

            },

            rect: function (x1, y1, x2, y2) {

                this.oGc.beginPath();

                this.oGc.rect(x1, y1, x2 - x1, y2 - y1);

                this.oGc[this.paintType]();

            },

            polygon: function (x1, y1, x2, y2) {

                var angle = 360 / this.nums * Math.PI / 180;//边对应的角的弧度

                var r = Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));

                this.oGc.beginPath();

                for (var i = 0; i < this.nums; i++) {

                    this.oGc.lineTo(x1 + r * Math.cos(angle * i), y1 + r * Math.sin(angle * i));

                }

                this.oGc.closePath();

                this.oGc[this.paintType]();

            }

        }

 

        var oShape = new Shape(oCanvas, oGc, cWidth, cHeight);

        function checkPaintType(liType) {

            var dataType = liType.parentNode.parentNode.dataset.type;

            var curType = liType.dataset.role;

            switch (dataType) {

                case &#39;paint-shape&#39;: //形状

                    oShape.drawType = curType;

                    if (curType == &#39;polygon&#39;) {

                        oShape.nums = prompt("请输入边数", 6);

                    }

                    oShape.draw();

                    break;

                case &#39;paint-color&#39;: //绘制颜色

                    liType.children[0].onchange = function () {

                        oShape[this.dataset.role] = this.value;

                    }

                    oShape.draw();

                    break;

                case &#39;paint-type&#39;: //绘制类型

                    oShape.paintType = curType;

                    oShape.draw();

                    break;

            }

        }

// ]]></script>

    <style>

        .paint * {

            margin: 0;

            padding: 0;

        }

 

        .paint ul,

        .paint li {

            list-style: none;

        }

 

        .paint li:hover {

            cursor: pointer;

        }

 

        .paint {

            width: 980px;

            margin: 20px auto;

            border: 1px solid #ccc;

            overflow: hidden;

        }

 

        .paint .paint-header ul {

            width: 980px;

            height: 40px;

            line-height: 40px;

            border-bottom: 1px solid #ccc;

        }

 

        .paint .paint-header li {

            float: left;

            width: 120px;

            height: 40px;

            line-height: 40px;

            text-align: center;

        }

 

        .paint li.active {

            box-shadow: #666 0px 1px 8px inset;

        }

 

        .paint .paint-body .siderbar {

            float: left;

            width: 150px;

            height: 500px;

        }

 

        .paint .paint-body .item {

            width: 150px;

            overflow: hidden;

            display: none;

            height: 500px;

            border-right: 1px solid #ccc;

        }

 

        .paint .paint-body canvas {

            float: right;

        }

 

        .paint .paint-body .item li {

            height: 40px;

            text-align: center;

            border-bottom: 1px solid #ccc;

            line-height: 40px;

        }

 

        .paint .paint-body .active {

            display: block;

        }

    </style>

</body>

Copy after login

Regarding process design, the functions to be done in the later stage and the ideas are basically there. Well, Compass is telling the story. If you want to achieve this ultimate goal, complete it. A drawing tool should get you close. Let’s experience the current simple functions first. You can draw pictures normally below. [You need your browser to support canvas.]
Mainly talk about the prototype structure of the target:

1, for the graphics drawing part, I encapsulated a class Shape

1

2

3

4

5

6

7

8

9

10

11

12

function Shape(canvasObj, cxtObj, w, h) {

        this.oCanvas = canvasObj;

        this.oGc = cxtObj;

        this.oCanvas.width = w;

        this.oCanvas.height = h;

        this.fillStyle = &#39;#000&#39;;

        this.storkeStyle = &#39;#000&#39;;

        this.lineWidth = 1;

        this.drawType = &#39;line&#39;;

        this.paintType = &#39;stroke&#39;;

        this.nums = 6; //正多边形的边数

    }

Copy after login

canvasObj: It is the canvas object

cxtObj: It is the context drawing environment

w: width of canvas

h: height of canvas

fillStyle: fill color

strokeStyle: stroke color

lineWidth: line width

drawType: The default is to draw a straight line

paintType: two options of stroke/fill (stroke/fill)

2, extend a public method draw on the prototype object To draw graphics

draw method mainly obtains the starting point coordinates (startX, startY) and end point coordinates (endX, endY);

Then call the init method to obtain the drawing status, Drawing specific graphics relies on the following key method:

_this[_this.drawType](startX, startY, endX, endY)

The drawType of this method will change according to the real-time selection of the interface. The drawing type, such as:

_this['line']( startX, startY, endX, endY)

The line in the oShape object is called, the method of drawing a straight line

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

Shape.prototype = {

        init: function () {

            this.oGc.fillStyle = this.fillStyle;

            this.oGc.strokeStyle = this.strokeStyle;

            this.oGc.lineWidth = this.lineWidth;

        },

        draw: function () {

            var _this = this;

            this.oCanvas.onmousedown = function ( ev ) {

                _this.init();

                var oEvent = ev || event,

                    startX = oEvent.clientX - _this.oCanvas.offsetLeft,

                    startY = oEvent.clientY - _this.oCanvas.offsetTop;

                _this.oCanvas.onmousemove = function ( ev ) {

                    _this.oGc.clearRect( 0, 0, _this.oCanvas.width, _this.oCanvas.height );

                    var oEvent = ev || event,

                        endX = oEvent.clientX - _this.oCanvas.offsetLeft,

                        endY = oEvent.clientY - _this.oCanvas.offsetTop;

                    _this[_this.drawType](startX, startY, endX, endY);

                };

                _this.oCanvas.onmouseup = function(){

                    _this.oCanvas.onmousemove = null;

                    _this.oCanvas.onmouseup = null;

                }

            }

        },

        line: function ( x1, y1, x2, y2 ) {

            this.oGc.beginPath();

            this.oGc.moveTo( x1, y1 );

            this.oGc.lineTo( x2, y2 );

            this.oGc.closePath();

            this.oGc.stroke();

        },

        circle : function( x1, y1, x2, y2 ){

            this.oGc.beginPath();

            var r = Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) );

            this.oGc.arc( x1, y1, r, 0, 2 * Math.PI, false );

            this.oGc.closePath();

            this.oGc[this.paintType]();

        },

        rect : function( x1, y1, x2, y2 ){

            this.oGc.beginPath();

            this.oGc.rect( x1, y1, x2 - x1, y2 - y1 );

            this.oGc[this.paintType]();

        },

        polygon : function( x1, y1, x2, y2 ){

            var angle = 360 / this.nums * Math.PI / 180;//边对应的角的弧度

            var r = Math.sqrt( Math.pow( x2 - x1, 2 ) + Math.pow( y2 - y1, 2 ) );

            this.oGc.beginPath();

            for( var i = 0; i < this.nums; i ++ ){

                this.oGc.lineTo( x1 + r * Math.cos( angle * i ), y1 + r * Math.sin( angle * i ) );

            }

            this.oGc.closePath();

            this.oGc[this.paintType]();

        }

    }

Copy after login

3, the interface operation is very simple, basically the operation of tab + the custom attribute of html5 + the application of classList

The above is the detailed content of How to make a drawing software similar to windows using html5. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Issues
Can Windows be learned?
From 1970-01-01 08:00:00
0
0
0
Install PHP in windows environment
From 1970-01-01 08:00:00
0
0
0
zookeeper extension under windows
From 1970-01-01 08:00:00
0
0
0
Can I play vim happily on Windows?
From 1970-01-01 08:00:00
0
0
0
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template