版权所有:
(xiaodaoxiaodao)
蓝小刀
xiaodaoxiaodao@gmail.com
http://www.blogjava.net/xiaodaoxiaodao/articles/103445.html
转载请注明来源
/
作者
鼠标拖曳实现
svg
矩形的任意切分
关于SVG查看需要装一个浏览器插件,可以从adobe网站下载
http://www.adobe.com/svg/viewer/install/mainframed.html
最近要实现一个关于矩形任意拆分的问题,当鼠标在矩形上拖曳一段长度松开,要求矩形可以被切分成两块,实现原理很简单,就是切分前是一个矩形,切分后根据鼠标起始和结束坐标生成两个多边形。
中间有个问题稍微麻烦一点,就是鼠标在矩形内部拖曳时,我只能得到它在矩形内部的起始和结束坐标,而实际切分时要知道切分后边界的坐标,所以在实际中要用斜率去计算切分后边界的坐标,用var xbegin = 0;var ybegin = 0;var xend = 0;var yend = 0; 来表示。
本来想给代码加一点注释,可注释成中文总是提示报错,后来查到SVG对中文的支持不是很好,搞了半天也没有搞好,所以下面的注释只能用e文来写,呵呵,e文太差,注释省略很多了,代码copy下来就可以跑了。
<svg width='400' height='400' onload='creat_event(evt)'>
<script><![CDATA[
// record the coordinates on mousedown and mouseup event in rect element
var xbefore = 0;
var ybefore = 0;
var xafter = 0;
var yafter = 0;
// count the coordinates to do split_event
var xbegin = 0;
var ybegin = 0;
var xend = 0;
var yend = 0;
// properties value of rect element
var x = 50;
var y = 50;
var w = 100;
var h = 50;
// move step after one rect splitted into two polygons
var step = 5;
function creat_event(evt){
svgdoc = evt.target.ownerDocument;
node = svgdoc.createElement('rect');
node.setAttribute('x',x);node.setAttribute('y',y);
node.setAttribute('width',w);node.setAttribute('height',h);
node.setAttribute('style','fill:red');
node.addEventListener('mousedown',store_before,false);
node.addEventListener('mouseup',store_after,false);
ou = svgdoc.getElementById('graph');
ou.appendChild(node);
}
function split_event(evt){
svgdoc = evt.target.ownerDocument;
ou = svgdoc.getElementById('graph');
objet = evt.target;
// when do click event no action should be executed
if(xbefore != xafter){
// remove the origin rect object
ou.removeChild(objet);
var k = (yafter - ybefore)/(xafter - xbefore);
xbegin = xafter + (y - yafter)/k;
xend = xafter + ((y + h) - yafter)/k;
if(xend <= x && (xbegin >=x && xbegin <=(x + w)) ){
xend = x;
yend = yafter + (xend - xafter)*k;
var coordinate1 = x + ',' + y + ' ' + xbegin + ',' + y + ' '
+ xend + ',' + yend;
var coordinate2 = (xbegin + step) + ',' + y + ' ' + ( x + w + step) + ',' + y + ' '
+ (x + w + step) + ',' + (y + h) + ' ' + (xend + step) + ',' + (y + h)+ ' '
+ (xend+step) + ',' + yend;
node1 = svgdoc.createElement('polygon');
node1.setAttribute('points',coordinate1);
node1.setAttribute('style','fill:red');
node2 = svgdoc.createElement('polygon');
node2.setAttribute('points',coordinate2);
node2.setAttribute('style','fill:blue');
}else if(xend >= (x+w) && (xbegin >=x && xbegin <=(x + w)) ){
xend = x + w;
yend = yafter + (xend - xafter)*k;
var coordinate1 = xbegin + ',' + y + ' ' + (x + w) + ',' + y + ' '
+ (x + w) + ',' + yend;
var coordinate2 = (xbegin - step) + ',' + y + ' ' + ( x - step) + ',' + y + ' '
+ (x - step) + ',' + (y + h) + ' ' + (xend - step) + ',' + (y + h)+ ' '
+ (xend - step) + ',' + yend;
node1 = svgdoc.createElement('polygon');
node1.setAttribute('points',coordinate1);
node1.setAttribute('style','fill:red');
node2 = svgdoc.createElement('polygon');
node2.setAttribute('points',coordinate2);
node2.setAttribute('style','fill:blue');
}else if(xend <= x && (xbegin >(x + w)) ){
// the logic of this else block is the same as the next
xbegin = x + w;
xend = x;
ybegin = yafter + (xbegin - xafter)*k;
yend = yafter + (xend - xafter)*k;
var coordinate1 = x + ',' + y + ' ' + xbegin + ',' + y + ' '
+ xbegin + ',' + ybegin + ' ' + xend + ',' + yend;
var coordinate2 = x + ',' + (yend + step) + ' ' + xbegin + ',' + (ybegin + step) + ' '
+ xbegin + ',' + (y + h + step) + ' ' + xend + ',' + (y + h + step);
node1 = svgdoc.createElement('polygon');
node1.setAttribute('points',coordinate1);
node1.setAttribute('style','fill:red');
node2 = svgdoc.createElement('polygon');
node2.setAttribute('points',coordinate2);
node2.setAttribute('style','fill:blue');
}else if(xend >= (x+w) && (xbegin < x) ){
xbegin = x + w;
xend = x;
ybegin = yafter + (xbegin - xafter)*k;
yend = yafter + (xend - xafter)*k;
var coordinate1 = x + ',' + y + ' ' + xbegin + ',' + y + ' '
+ xbegin + ',' + ybegin + ' ' + xend + ',' + yend;
var coordinate2 = x + ',' + (yend + step) + ' ' + xbegin + ',' + (ybegin + step) + ' '
+ xbegin + ',' + (y + h + step) + ' ' + xend + ',' + (y + h + step);
node1 = svgdoc.createElement('polygon');
node1.setAttribute('points',coordinate1);
node1.setAttribute('style','fill:red');
node2 = svgdoc.createElement('polygon');
node2.setAttribute('points',coordinate2);
node2.setAttribute('style','fill:blue');
}else if( (xend >=x && xend <=(x + w)) && (xbegin >(x + w)) ){
xbegin = x + w;
ybegin = yafter + (xbegin - xafter)*k;
var coordinate1 = xbegin + ',' + ybegin + ' ' + (x + w) + ',' + (y + h) + ' '
+ xend + ',' + (y + h);
var coordinate2 = (x - step) + ',' + y + ' ' + ( x + w - step) + ',' + y + ' '
+ (x + w - step) + ',' + ybegin + ' ' + (xend - step) + ',' + (y + h)+ ' '
+ (x - step) + ',' + (y + h);
node1 = svgdoc.createElement('polygon');
node1.setAttribute('points',coordinate1);
node1.setAttribute('style','fill:red');
node2 = svgdoc.createElement('polygon');
node2.setAttribute('points',coordinate2);
node2.setAttribute('style','fill:blue');
}else if( (xend >=x && xend <=(x + w)) && xbegin <x ){
xbegin = x;
ybegin = yafter + (xbegin - xafter)*k;
var coordinate1 = x + ',' + ybegin + ' ' + xend + ',' + (y + h) + ' '
+ x + ',' + (y + h);
var coordinate2 = (x + step) + ',' + y + ' ' + ( x + w + step) + ',' + y + ' '
+ (x + w + step) + ',' + (y + h) + ' ' + (xend + step) + ',' + (y + h)+ ' '
+ (xbegin + step) + ',' + ybegin;
node1 = svgdoc.createElement('polygon');
node1.setAttribute('points',coordinate1);
node1.setAttribute('style','fill:red');
node2 = svgdoc.createElement('polygon');
node2.setAttribute('points',coordinate2);
node2.setAttribute('style','fill:blue');
}else{
var coordinate1 = x + ',' + y + ' ' + xbegin + ',' + y + ' '
+ xend + ',' + (y + h) + ' ' + x + ',' + (y + h);
var coordinate2 = (xbegin + step) + ',' + y + ' ' + ( x + w + step) + ',' + y + ' '
+ (x + w + step) + ',' + (y + h) + ' ' + (xend + step) + ',' + (y + h);
node1 = svgdoc.createElement('polygon');
node1.setAttribute('points',coordinate1);
node1.setAttribute('style','fill:red');
node2 = svgdoc.createElement('polygon');
node2.setAttribute('points',coordinate2);
node2.setAttribute('style','fill:blue');
}
ou = svgdoc.getElementById('graph');
// create two new polygons
ou.appendChild(node1);
ou.appendChild(node2);
}
}
function store_before(evt){
// reset before value in case of doing mousedown event inside the rect element more times
xbefore = 0;
ybefore = 0;
if(xbefore == 0 && ybefore == 0){
xbefore = evt.clientX;
ybefore = evt.clientY;
//alert(xbefore + '*' + ybefore);
}
}
function store_after(evt){
// reset after value in case of doing mousedown event inside the rect element more times
xafter = 0;
yafter = 0;
if(xafter == 0 && yafter == 0){
xafter = evt.clientX;
yafter = evt.clientY;
//alert(xafter + '*' + yafter);
}
split_event(evt);
}
]]></script>
<g id='graph'>
<text id='pos' x='220' y='20' style='text-anchor:middle;font-size:15;font-family:Arial;fill:red'>
Mouse down and up inside the red rectangle then it will be splitted</text>
</g>
</svg>
版权所有:
(xiaodaoxiaodao)
蓝小刀
xiaodaoxiaodao@gmail.com