您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

html5自己做一个类似windows的画图软件的方法

2024/7/2 11:49:58发布36次查看
这个绘图工具,我还没有做完,不过已经实现了总架构,以及常见的简易图形绘制功能:
1,可以绘制直线,圆,矩形,正多边形【已完成】
2,填充颜色和描边颜色的选择【已完成】
3,描边和填充功能的选择【已完成】
后续版本:
橡皮擦,坐标系,线形设置,箭头,其他流程图形,裁剪与调整图形。。。。。
终极目标:
流程绘制软件
我是之前看见一位朋友在我的博客中留言说:
非常感谢这个朋友,今天终于抽出时间完成非常非常小的雏形!
完整的雏形代码,请自行打开,复制到本地测试.
<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( '.paint-body' ); var oc = document.createelement( 'canvas' ); oc.setattribute( 'width', '830' ); oc.setattribute( 'height', '500' ); opaintbody.appendchild( oc ); var aheaderli = document.queryselectorall('.paint-header li'), aitem = document.queryselectorall('.paint-body .item'), ocanvas = document.queryselector('.paint canvas'), ogc = ocanvas.getcontext('2d'), cwidth = ocanvas.width, cheight = ocanvas.height, curitem = aitem[0], aitemli = curitem.queryselectorall('li'); 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('active'); aitem[j].style.display = 'none'; } aitem[i].style.display = "block"; this.classlist.add('active'); curitem = aitem[i]; aitemli = curitem.queryselectorall('li'); 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('active'); } this.classlist.add('active'); } } } function shape(canvasobj, cxtobj, w, h) { this.ocanvas = canvasobj; this.ogc = cxtobj; this.ocanvas.width = w; this.ocanvas.height = h; this.fillstyle = '#000'; this.storkestyle = '#000'; this.linewidth = 1; this.drawtype = 'line'; this.painttype = 'stroke'; 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 'paint-shape': //形状 oshape.drawtype = curtype; if (curtype == 'polygon') { oshape.nums = prompt("请输入边数", 6); } oshape.draw(); break; case 'paint-color': //绘制颜色 litype.children[0].onchange = function () { oshape[this.dataset.role] = this.value; } oshape.draw(); break; case 'paint-type': //绘制类型 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>
关于流程设计,后期要做的功能,思路基本上已经有了,好了,圆规正传,想要完成这个终极目标,完成一个画图工具应该就能接近目标了。先体验下目前的简易功能,下面是可以正常画图的,【需要你的浏览器支持canvas才可以额】
主要来讲下目标的雏形架构:
1,图形绘制部分,我封装了一个类shape
function shape(canvasobj, cxtobj, w, h) { this.ocanvas = canvasobj; this.ogc = cxtobj; this.ocanvas.width = w; this.ocanvas.height = h; this.fillstyle = '#000'; this.storkestyle = '#000'; this.linewidth = 1; this.drawtype = 'line'; this.painttype = 'stroke'; this.nums = 6; //正多边形的边数 }
canvasobj: 就是canvas画布对象
cxtobj: 就是上下文绘图环境
w: canvas的宽度
h: canvas的高度
fillstyle: 填充颜色
strokestyle: 描边颜色
linewidth: 线宽
drawtype: 默认为画直线
painttype: stroke/fill 两种选择( 描边/填充)
2,在原型对象上扩展一个公共方法draw用来绘制图形
draw方法,主要获取起始点坐标(startx, starty),以及终点坐标( endx, endy );
然后调用init方法来获取绘制状态,绘制具体的图形靠下面这个关键方法:
_this[_this.drawtype](startx, starty, endx, endy)
这个方法的drawtype会根据界面的实时选择,变换对应的绘制类型,如:
_this['line']( startx, starty, endx, endy )
调用的就是oshape对象中的line,画直线的方法
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](); } }
3,界面操作很简单,基本是选项卡的操作+html5的自定义属性+classlist的应用
以上就是html5自己做一个类似windows的画图软件的方法的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product