绘画板 02——抽象并实现图形绘制功能
github地址: https://github.com/wangyuheng/painter
DEMO地址: http://painter.crick.wang/
针对上个版本的基础代码进行抽象和封装
将所有的图形绘制工具,都“继承”一个DrawTool工具类,在此工具类中绑定、解绑事件,代码如下
(function() {
var defaultListener = {
mousedown: function() {
console.log('mousedown you should implement this function!');
},
mousemove: function() {
console.log('mousemove you should implement this function!');
},
mouseup: function() {
console.log('mouseup you should implement this function!');
}
};
var DrawTool = {
init: function(svgDoc, listeners) {
var l = $.extend({}, defaultListener, listeners);
svgDoc.on('mousedown', l.mousedown);
svgDoc.on('mousemove', l.mousemove);
svgDoc.on('mouseup', l.mouseup);
},
stop: function(svgDoc, listeners) {
var l = $.extend({}, defaultListener, listeners);
svgDoc.off('mousemove', l.mousemove);
svgDoc.off('mousedown', l.mousedown);
svgDoc.off('mouseup', l.mouseup);
}
};
this.DrawTool = DrawTool;
})();
所有js独立代码都采用闭包形式,避免的参数污染。 拆分后的目录结构如下
还是以矩形为例,Rect在构造函数中继承使用了DrawTool的init方法,并重写stop方法,暴露出去。
var Rect = function(parentEle) {
parent = parentEle;
svgDoc = parent.doc();
DrawTool.init(svgDoc, listener);
this.stop = function () {
DrawTool.stop(svgDoc, listener);
};
};
this.DrawTool.Rect = Rect;
通过在Rect类内部定义mousedown、mousemove、mouseup事件方法,调用svgjs提供的绘制方法,实现图形的绘制工作。完整代码如下:
(function() {
var parent = null;
var drawing = false;
var element = null;
var startPoint = null;
function mousedown(event) {
console.log('rect mousedown');
drawing = true;
startPoint = svgDoc.transformPoint(event);
element = parent.rect(0, 0).style("fill-opacity", '0.0').stroke({
width: '2',
color: '#000000'
});
}
function mousemove(event) {
console.log('rect mousemove');
if (drawing) {
var svgPoint = svgDoc.transformPoint(event);
var x = svgPoint.x;
var y = svgPoint.y;
var newWidth = x - startPoint.x;
var newHeight = y - startPoint.y;
var startX = startPoint.x;
var startY = startPoint.y;
if (newWidth < 0) {
startX += newWidth;
}
if (newHeight < 0) {
startY += newHeight;
}
newWidth = Math.abs(newWidth);
newHeight = Math.abs(newHeight);
element.x(startX).y(startY).width(newWidth).height(newHeight);
}
};
function mouseup(event) {
console.log('rect mouseup ' + element);
drawing = false;
}
var listener = {
mousedown: mousedown,
mousemove: mousemove,
mouseup: mouseup,
};
var Rect = function(parentEle) {
parent = parentEle;
svgDoc = parent.doc();
DrawTool.init(svgDoc, listener);
this.stop = function () {
DrawTool.stop(svgDoc, listener);
};
};
this.DrawTool.Rect = Rect;
})();
有一个特殊的类为折线polyline工具类,此图形为连续绘制,需要记录上一个element,并且在stop方法中清空之前的element,并且监听鼠标右键点击事件,结束图形绘制。
阻止鼠标右键方法为
function mousedown(event) {
if (event.button == 2) {
document.oncontextmenu=function(){return false;}
drawing=false;
points = [];
element = null;
return;
}
if (!drawing) {
drawing = true;
var currPoint = svgDoc.transformPoint(event);
points.push([currPoint.x, currPoint.y]);
}
}
至此,已完成图形的基本绘制功能