版权所有: (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