web-dev-qa-db-ja.com

jQueryを使用して線を引くことはできますか?

ユーザーに次の方法で線を引いてもらいたいWebアプリがあります。ユーザーがPoint1をクリックしてマウスを動かすと、Point1から線を引きます。 現在のマウス位置に移動し、クリックするとPoint2に最終線を描画しますPoint1からPoint2に

JQueryやそのプラグインの1つを使用してそれを行うにはどうすればよいですか?

8
Cris

勝負を受けて立つ。

私はCSS変換とJavascriptの数学の束でそれをやろうとしました-30分後に私はこれを持っています:

http://jsfiddle.net/VnDrb/2/

灰色の四角を2回クリックすると、線が引かれます。角度が45度を超えると、線が間違って描画される小さなバグがまだあります。多分誰か他の人がそれを修正する方法を知っています。たぶん、Math.asin(arcsinus)を使用する代わりに、他の三角関数を使用しますが、私はそれが本当に得意ではありません。小さなバグがあっても投稿しようと思ったので、いいスタートだと思います。

5
Jonny Burger

私は今週末にいくつかの異なるアプローチを試しましたが、私にとって最も効果的な解決策はAdam Sandersonによるものです: http://monkeyandcrow.com/blog/drawing_lines_with_css3/

彼のデモはここにあります: http://monkeyandcrow.com/samples/css_lines/

その核心は非常にシンプルで、常に良いものです。

div.line{
  transform-Origin: 0 100%;
  height: 3px; /* Line width of 3 */
  background: #000; /* Black fill */
}


function createLine(x1,y1, x2,y2){
  var length = Math.sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2));
  var angle  = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI;
  var transform = 'rotate('+angle+'deg)';

    var line = $('<div>')
      .appendTo('#page')
      .addClass('line')
      .css({
        'position': 'absolute',
        'transform': transform
      })
      .width(length)
      .offset({left: x1, top: y1});

  return line;
}
4
BaronGrivet

JQueryと従来のHTMLではそれを行うことはできません。

  1. SVGを使用してそれを行うことができます(IE8の場合は+ svgweb- http://code.google.com/p/svgweb/ )SVGは動的に作成できます。 jQuery + svgwebは完全に機能しています。SVGノードの作成方法を知っている必要があり、このノードをjquerifyするだけで済みます。ほとんどの場合、jquerifiingの後、1つのメソッドのみを使用しましたattr()

  2. Raphaelを使用してそれを行うことができます http://raphaeljs.com/ (SVGおよびVMLに基づく)

  3. Canvasを使用してそれを行うことができます( http://flashcanvas.net/ for IE8-)


SVGプログラミングの場合は次のようになります。

  1. 最初の点を作成する瞬間:空の線var Lineを作成します(この点の座標もx1y1になります)

  2. 次に、Lineのx2y2プロパティのmousemove再描画をバインドします

  3. mousedownの後のmousemoveで、最後の行の位置をフリーズします。


[〜#〜]更新[〜#〜]

CSS/JSでそれを行うことができますが、主な問題は、変換用のマトリックスフィルターしかないIE8-の計算にあります。

2
Rustam

クラス

function getXY(evt, element) {
    var rect = element.getBoundingClientRect();
    var scrollTop = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
    var scrollLeft = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft;
    var elementLeft = rect.left + scrollLeft;
    var elementTop = rect.top + scrollTop;

    x = evt.pageX - elementLeft;
    y = evt.pageY - elementTop;
    return { x: x, y: y };
}
var LineDrawer = {
    LineHTML: `<div style="cursor: pointer;transform-Origin:center; position:absolute;width:200px;height:2px; background-color:blue"></div>`,
    isDown: false,
    pStart: {},
    pCurrent :{},
    containerID: "",
    JLine: {},
    angle: 0,
    afterLineCallback: null,
    Init: function (containerID, afterLineCallback) {
        LineDrawer.containerID = containerID;
        LineDrawer.afterLineCallback = afterLineCallback;
        LineDrawer.JLine = $(LineDrawer.LineHTML).appendTo("#" + LineDrawer.containerID);
        LineDrawer.JLine.css("transform-Origin", "top left");
        LineDrawer.JLine.hide();
        //LineDrawer.JLine.draggable({ containment: "#" + LineDrawer.containerID });
        $("#" + LineDrawer.containerID).mousedown(LineDrawer.LineDrawer_mousedown);
        $("#" + LineDrawer.containerID).mousemove(LineDrawer.LineDrawer_mousemove);
        $("#" + LineDrawer.containerID).mouseup(LineDrawer.LineDrawer_mouseup);
    },
    LineDrawer_mousedown: function (e) {
        if (e.target === LineDrawer.JLine[0]) return false;
        LineDrawer.isDown = true;
        let p = LineDrawer.pStart = getXY(e, e.target);
        LineDrawer.JLine.css({ "left": p.x, "top": p.y, "width": 1});
        LineDrawer.JLine.show();
    },
    LineDrawer_mousemove: function (e) {
        if (!LineDrawer.isDown) return;
        LineDrawer.pCurrent = getXY(e, document.getElementById("jim"));
        let w = Math.sqrt(((LineDrawer.pStart.x - LineDrawer.pCurrent.x) * (LineDrawer.pStart.x - LineDrawer.pCurrent.x)) + ((LineDrawer.pStart.y - LineDrawer.pCurrent.y) * (LineDrawer.pStart.y - LineDrawer.pCurrent.y)));
        LineDrawer.JLine.css("width", w - 2);
        LineDrawer.angle = Math.atan2((LineDrawer.pStart.y - LineDrawer.pCurrent.y), (LineDrawer.pStart.x - LineDrawer.pCurrent.x)) * (180.0 / Math.PI);
        //the below ensures that angle moves from 0 to -360
        if (LineDrawer.angle < 0) {
            LineDrawer.angle *= -1;
            LineDrawer.angle += 180;
        }
        else LineDrawer.angle = 180 - LineDrawer.angle;
        LineDrawer.angle *= -1;

        LineDrawer.JLine.css("transform", "rotate(" + LineDrawer.angle + "deg");

    },
    LineDrawer_mouseup: function (e) {
        LineDrawer.isDown = false;
        if (LineDrawer.afterLineCallback == null || LineDrawer.afterLineCallback == undefined) return;
        LineDrawer.afterLine(LineDrawer.angle, LineDrawer.pStart, LineDrawer.pCurrent);
    },
};

使用法:

var ECApp = {
    start_action: function () {
        LineDrawer.Init("jim", ECApp.afterLine);            
    },
    afterLine(angle, pStart, pEnd) {
        //$("#angle").text("angle : " + angle);
        let disp = "angle = " + angle;
        disp += " Start = " + JSON.stringify(pStart) + " End = " + JSON.stringify(pEnd);
        //alert(disp);
        $("#angle").text("angle : " + disp);
    }
}
$(document).ready(ECApp.start_action);

HTML

<div class="row">
<div class="col">
    <div id="jim" style="position:relative;width:1200px;height:800px;background-color:lightblue;">            
    </div>
</div>
0
Dr.Sai

しばらくの間、これの修正バージョンを使用しています。うまく機能します。

http://www.ofdream.com/code/css/xline2.php

したがって、最初にクリックして、そこにプレースホルダーdiv(おそらく小さな円)としてオブジェクトをドロップしてオブジェクトを配置し、マウスを動かしながら線を再描画するか、元のプレースホルダーをガイドとして使用して2回目にクリックしたときに線を描画します。

私のツールには線の移動が含まれるため、最近、このための別のヘルパー関数を作成しました。

function setLinePos(x1, y1, x2, y2, id) {
    if (x2 < x1) {
        var temp = x1;
        x1 = x2;
        x2 = temp;
        temp = y1;
        y1 = y2;
        y2 = temp;
    }
    var line = $('#line' + id);
    var length = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
    line.css('width', length + "px");
    var angle = Math.atan((y2 - y1) / (x2 - x1));
    line.css('top', y1 + 0.5 * length * Math.sin(angle) + "px");
    line.css('left', x1 - 0.5 * length * (1 - Math.cos(angle)) + "px");
    line.css('-moz-transform', "rotate(" + angle + "rad)");
    line.css('-webkit-transform', "rotate(" + angle + "rad)");
    line.css('-o-transform', "rotate(" + angle + "rad)");

 }

これはjqueryバージョンであり、この反復ではIE要件がないため、無視します。元の関数から非常に簡単に適応できます。

0
ClickMatch