Как нарисовать стрелку, чтобы связать ngraph.pixi с PIXI.js с webgl? - PullRequest
0 голосов
/ 25 октября 2019

Я рисую прямой график, поэтому рисую стрелку на линии, я новичок в pixi.js и javascript и хочу узнать, можете ли вы помочь мне, как я могу нарисовать стрелку дляэто?

Это демо , и я хочу добавить стрелку к ссылке.

Это код для рисования ссылки внутри этого класса

module.exports = function (link, ctx) {
  ctx.lineStyle(link.width, 0x333333, 1);
  ctx.moveTo(link.from.x, link.from.y);
  ctx.lineTo(link.to.x, link.to.y);
}

Это полный код

module.exports.main = function () {
  var graph = require('ngraph.generators').balancedBinTree(5);
  var createPixiGraphics = require('../');

  var setting = {
    rendererOptions: {
      backgroundColor: 0xFFFFFF,
      antialias: true,
    }
  }

  var pixiGraphics = createPixiGraphics(graph, setting);
  pixiGraphics.createLinkUI(require('./lib/createLinkUI'));
  pixiGraphics.renderLink(require('./lib/renderLink'));
  pixiGraphics.createNodeUI(require('./lib/createNodeUI'));
  pixiGraphics.renderNode(require('./lib/renderNode'));
  var layout = pixiGraphics.layout;

  // just make sure first node does not move:
  layout.pinNode(graph.getNode(1), true);

  // begin animation loop:
  pixiGraphics.run();
}

Ссылка для воспроизведения кода здесь

Большое спасибо

1 Ответ

1 голос
/ 26 октября 2019

Насколько я знаю, pixi.js не поддерживает рендеринг стрелок из коробки. Вы должны были бы нарисовать стрелки вручную. Идея состоит в том, чтобы использовать примитивные векторные операции для вычисления того, где должны быть крылья стрелки.

Это проще реализовать, если вы работаете с нормализованными векторами (векторами, длина которых равна 1). Когда у вас есть вектор для ссылки на график, вы знаете его направление, вы можете посчитать смещение на ссылке, где должны останавливаться крылья стрелки. После того как вы сместили, все, что вам нужно сделать, это взять ортогональный вектор и сделать шаг влево / вправо от вашего исходного вектора - это точки, где ваши крылья со стрелками должны остановиться.

Было бы намного прощеПонимаю, если вы рисуете картинку, но у меня нет хороших ручек и карандашей на данный момент, поэтому вот код, который отображает стрелку:

function defaultLinkRenderer(link) {
  graphics.lineStyle(1, 0xcccccc, 1);
  graphics.moveTo(link.from.x, link.from.y);
  graphics.lineTo(link.to.x, link.to.y);

  // first, let's compute normalized vector for our link:
  let dx = link.to.x - link.from.x;
  let dy = link.to.y - link.from.y;
  let l = Math.sqrt(dx * dx + dy * dy);

  if (l === 0) return; // if length is 0 - can't render arrows

  // This is our normal vector. It describes direction of the graph
  // link, and has length == 1:
  let nx = dx/l; let ny = dy/l;

  // Now let's draw the arrow:
  let arrowLength = 6;       // Length of the arrow
  let arrowWingsLength = 2;  // How far arrow wings are from the link?

  // This is where arrow should end. We do `(l - NODE_WIDTH)` to
  // make sure it ends before the node UI element.
  let ex = link.from.x + nx * (l - NODE_WIDTH);
  let ey = link.from.y + ny * (l - NODE_WIDTH);

  // Offset on the graph link, where arrow wings should be
  let sx = link.from.x + nx * (l - NODE_WIDTH - arrowLength);
  let sy = link.from.y + ny * (l - NODE_WIDTH - arrowLength);

  // orthogonal vector to the link vector is easy to compute:
  let topX = -ny;
  let topY = nx;

  // Let's draw the arrow:
  graphics.moveTo(ex, ey);
  graphics.lineTo(sx + topX * arrowWingsLength, sy + topY * arrowWingsLength);
  graphics.moveTo(ex, ey);
  graphics.lineTo(sx - topX * arrowWingsLength, sy - topY * arrowWingsLength);
}

И это делает стрелки хорошо выглядящими:

final result

...