Может кто-нибудь сказать мне, как рисовать изогнутые линии от элемента к элементу в JavaScript для произвольных углов? - PullRequest
0 голосов
/ 05 ноября 2010

Просто для контекста я использую html5, css и jquery.

Я хотел бы иметь возможность рисовать изогнутые линии со стрелками между двумя элементами на веб-странице. Я почти понял, но просто не могу обернуть голову вокруг математики, чтобы нарисовать наконечники стрел. Может быть, это манипуляция виджетом canvas, который меня достает.

Вот javascript, который я использую в данный момент. Это, конечно, кажется долгим, но похоже, что работа сделана за исключением этих надоедливых наконечников стрел.

Переменная «влияние» должна немного варьировать строки, чтобы при наличии нескольких строк они отображались одна за другой.

  var start = $('#firstobject');
  var last = $('#lastobject');
  var stpos = start.position();
  var lastpos = last.position();
  var influence = Math.random*20+5;
  var maxx = Math.max(stpos.left,lastpos.left);
  var minx = Math.min(stpos.left,lastpos.left);
  var maxy = Math.max(stpos.top,lastpos.top);
  var miny = Math.min(stpos.top,lastpos.top);
  var w = maxx - minx;
  var h = maxy - miny;
  var cname = "samplename";
  var cpad = 30;
  var cstr = "<canvas id='"+cname+"' class='huntgroupcanvas' style='z-index:2;position:absolute;left:"+(0+minx-cpad)+"px;top:"+(0+miny-cpad)+"px;' id='"+cname+"' width="+(2*cpad+w)+" height="+(2*cpad+h)+"></canvas>"
  start.before(cstr);
  var canvas = document.getElementById(cname);
  var ctx = canvas.getContext("2d");
  var dx = stpos.left - lastpos.left;
  var dy = stpos.top - lastpos.top;
  var dir = dy/dx;
  var sx,sy,ex,ey;
  if (dir<0) {
    ex=w+cpad;
    ey=cpad;
    sx=cpad;
    sy=h+cpad;
  } else {
    ex=w+cpad;
    ey=h+cpad;
    sx=cpad;
    sy=cpad;
  }

  ctx.lineWidth=1;
  ctx.strokeStyle = '#000';
  ctx.beginPath();
  ctx.moveTo(sx,sy);
  ctx.quadraticCurveTo(((w/2)-(h/2))+cpad-influence,((h/2)-(w/2))+cpad,ex,ey);
  ctx.stroke();
  if (st==i-1) {
    first=0;
    ctx.beginPath();
    if (dx<0) {
      ctx.arc(sx,sy,6,0,Math.PI*2,0);
    } else {
      ctx.arc(ex,ey,6,0,Math.PI*2,0);
    }
    ctx.stroke();
  }

 /* Here's where I've been trying to draw the arrowheads.
  * I know that I can get the slope of the line like so:
    var m = (y2-y1)/(x2-x1);
  * I know I can get the angle in radians as
    var angle=Math.atan(m);
  * I'm trying to use rotation to draw the arrowhead
 */
      ctx.save();
      ctx.beginPath();
      angle = Math.atan(dir);
      if (dx<0) {
        sx=ex;
        sy=ey;
        angle = Math.atan(-dir);
      }
      ctx.moveTo(sx,sy);
      ctx.translate(sx,sy);
      ctx.rotate(angle - 0.05);
      ctx.lineTo(20,0);
      ctx.rotate(angle + 0.05);
      ctx.lineTo(20,0);
      ctx.closePath();
      ctx.fill();
      ctx.restore();

1 Ответ

0 голосов
/ 05 ноября 2010

Это большой код для чтения, но может показаться, что вы путаете свою тригонометрию при генерации угла стрелки. Взгляните на функцию atan2, она берет двухмерный вектор и преобразует его в угол. Таким образом, вы хотели бы использовать angle=Math.atan2(dy,dx)

...