6

正確に何と呼ぶか​​はわかりませんが、領域をクリックしてドラッグし、mouseUpで消えるときにjavascript / svgを介して点線のアウトライン/選択ボックス効果を作成する方法を探しています(それがあれば追加できますオリジナルのパーツではありませんでした)。

jQueryライブラリが存在する場合はそれがいいでしょう。私はいくつかの周りを見回しましたが、私が探しているものを正確に見つけられませんでした。
理論は、最初のクリックから座標を取得し、マウスの座標モーメントを追跡し、それに応じてボックスを調整することだと思います。

しかし、最初からそれを書かないのはいいことです。

4

2 に答える 2

15

これは私があなたのために作ったデモです:)

デモ (静的): http://jsfiddle.net/HNH2f/1/

デモ (アニメーション): http://jsfiddle.net/HNH2f/2/

CSS を使用して、マーキーの視覚的なスタイルを制御できます。trackMarqueeメソッドには 1 つまたは 2 つの関数を渡すことができます。どちらも、マーキーの x1、y1、x2、y2 境界の 4 つの引数で呼び出されます。マーキーが解放されると、最初の関数が呼び出されます。2 番目の関数 (存在する場合) は、マーキーが移動するたびに呼び出されます (たとえば、境界ボックス内にあるアイテムを計算できるようにするため)。

SVGドキュメント(または追跡するために選択した要素)でドラッグを開始すると、<rect class="marquee" />;が作成されます。ドラッグすると、長方形のサイズが調整されます。CSS (デモで見られるように) を使用して、この四角形を好きなようにスタイルします。プロパティを使用しstroke-dasharrayて境界線を点線にしています。

スタック オーバーフローの後世のために、コードは次のとおりです (JSFiddle がダウンしている可能性があります)。

(function createMarquee(global){
  var svgNS = 'http://www.w3.org/2000/svg',
      svg   = document.createElementNS(svgNS,'svg'),
      pt    = svg.createSVGPoint();

  // Usage: trackMarquee( mySVG, function(x1,y1,x2,y2){}, function(x1,y1,x2,y2){} );
  // The first function (if present) will be called when the marquee is released
  // The second function (if present) will be called as the marquee is changed
  // Use the CSS selector `rect.marquee` to select the marquee for visual styling
  global.trackMarquee = function(forElement,onRelease,onDrag){
    forElement.addEventListener('mousedown',function(evt){
      var point0 = getLocalCoordinatesFromMouseEvent(forElement,evt);
      var marquee = document.createElementNS(svgNS,'rect');
      marquee.setAttribute('class','marquee');
      updateMarquee(marquee,point0,point0);
      forElement.appendChild(marquee);
      document.documentElement.addEventListener('mousemove',trackMouseMove,false);
      document.documentElement.addEventListener('mouseup',stopTrackingMove,false);
      function trackMouseMove(evt){
        var point1 = getLocalCoordinatesFromMouseEvent(forElement,evt);
        updateMarquee(marquee,point0,point1);
        if (onDrag) callWithBBox(onDrag,marquee);
      }
      function stopTrackingMove(){
        document.documentElement.removeEventListener('mousemove',trackMouseMove,false);
        document.documentElement.removeEventListener('mouseup',stopTrackingMove,false);
        forElement.removeChild(marquee);
        if (onRelease) callWithBBox(onRelease,marquee);
      }
    },false);
  };

  function callWithBBox(func,rect){
    var x = rect.getAttribute('x')*1,
        y = rect.getAttribute('y')*1,
        w = rect.getAttribute('width')*1,
        h = rect.getAttribute('height')*1;
    func(x,y,x+w,y+h);
  }

  function updateMarquee(rect,p0,p1){
    var xs = [p0.x,p1.x].sort(sortByNumber),
        ys = [p0.y,p1.y].sort(sortByNumber);
    rect.setAttribute('x',xs[0]);
    rect.setAttribute('y',ys[0]);
    rect.setAttribute('width', xs[1]-xs[0]);
    rect.setAttribute('height',ys[1]-ys[0]);
  }

  function getLocalCoordinatesFromMouseEvent(el,evt){
    pt.x = evt.clientX; pt.y = evt.clientY;
    return pt.matrixTransform(el.getScreenCTM().inverse());
  }

  function sortByNumber(a,b){ return a-b }
})(window);
于 2012-07-26T17:29:39.307 に答える
4

あなたは幸運です。私はこれを自分で作ったばかりです。jQuery SVG プラグイン ( http://keith-wood.name/svg.html )を使用しています。

$("#paper2").mousedown(function(ev) {
    ev.preventDefault(); 
    var pX= (ev.pageX - this.offsetLeft) * viewBox[2]/parseInt($("#paper2").css("width"));
    var pY= (ev.pageY - this.offsetTop)  * viewBox[3]/parseInt($("#paper2").css("height"));
    var rect = svg2.rect(
        pX, //X
        pY, //Y 
        1,1, //width and height
        { //Settings, you can make the box dotted here
            fill: 'black', "fill-opacity": 0.3, stroke: 'red', strokeWidth: 3, id:rect
        }
    )

    $("#paper2").mousemove(function(ev) {
        ev.preventDefault();
        var rect= $('#rect');
        var pX= (ev.pageX - this.offsetLeft) * viewBox[2]/parseInt($("#paper2").css("width")) - rect.attr("x");
        var pY= (ev.pageY - this.offsetTop)  * viewBox[3]/parseInt($("#paper2").css("height")) - rect.attr("y");
        rect.attr("width", pX);
        rect.attr("height", pY);
    });

    $("#paper2").mouseup(function(ev) {
        ev.preventDefault();
        var div= $("#paper2");
        div.unbind('mousemove');
        div.unbind('mouseup');
    })
});

paper2 は、svg 要素を含む div です (したがって、svg 要素と div の高さ/幅は同じです)。これは私がsvg2要素を作成した方法です:

var svg2;
var root2;
$(document).ready(function() {
    $("#paper2").svg({
        onLoad: function() {
            svg2= $("#paper2").svg('get');
            svg2.configure({id: 'svg2'});
            var div= $("#paper2");
            root2= svg2.root();
            $("#svg2").attr("viewBox", viewBox[0]+','+viewBox[1]+','+viewBox[2]+','+viewBox[3]);    
        },
        settings: {}
    });
}

svg 要素で viewbox を使用しない場合、計算でこれは必要ありません。

 * viewBox[2]/parseInt($("#paper2").css("*****"));

viewbox[2] はビューボックスの幅、viewbox[3] はビューボックスの高さになります。

于 2012-07-26T16:54:03.743 に答える