版權所有:
(xiaodaoxiaodao)
藍小刀
??
xiaodaoxiaodao@gmail.com
http://www.tkk7.com/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