JointJS - Port Hit Area

prevent contextmenu. https://github.com/clientIO/joint/issues/2658

by Roman Bruckner

HTML

<script src="https://cdn.jsdelivr.net/npm/@joint/[email protected]/dist/joint.min.js"></script>
<div id="paper"></div>

CSS

.joint-paper:not(.dragging) .hit-area:hover {
  fill: black;
  fill-opacity: 0.1;
}

.joint-paper:not(.dragging) .hit-area:hover~circle {
  r: 8;
  transition: r 200ms;
}

JavaScript

const { dia, shapes: defaultShapes } = joint

const shapes = {
  ...defaultShapes,
}

const graph = new dia.Graph(
  {},
  {
    cellNamespace: shapes,
  },
)

const paper = new dia.Paper({
  el: document.getElementById("paper"),
  width: 800,
  height: 600,
  model: graph,
  cellViewNamespace: shapes,
  async: true,
  linkPinning: false,
  snapLinks: { radius: 5 },
  connectionStrategy: (end) => {
     delete end.magnet;
     return end;
  }
})

const el1 = new defaultShapes.standard.Rectangle({
  position: { x: 50, y: 50 },
  size: { width: 100, height: 100 },
  attrs: {
    root: {
        magnet: false
    },
    body: {
      fill: "#31d0c6",
    },
  },
  ports: {
    groups: {
      a: {
        position: "right",
        markup: [
          {
            tagName: "circle",
            selector: "portHitArea",
          },
          {
            tagName: "circle",
            selector: "portBody",
          },
        ],
        attrs: {
          portRoot: {
            // When link is connected to the port
            // without specifying `magnet` we
            // connect to the `portBody` node.
            magnetSelector: "portBody",
          },
          portBody: {
            r: 5,
            pointerEvents: "none",
            fill: "#31d0c6",
            stroke: "black",
            strokeWidth: 2,
          },
          portHitArea: {
            highlighterSelector: "portBody",
            class: 'hit-area',
            r: 20,
            magnet: true,
            fill: "transparent",
            stroke: "none",
            cursor: "crosshair",
          },
        },
      },
    },
    items: [
      {
        id: "a1",
        group: "a",
      },
    ],
  },
});

const el2 = el1.clone().translate(200, 0);

graph.addCells([el1, el2]);

paper.on('element:magnet:pointerdown', () => {
  paper.el.classList.add('dragging');
});
paper.on('element:magnet:pointerup', () => {
  paper.el.classList.remove('dragging');
});