JointJS - Drag Element Label

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>

JavaScript

const { dia, shapes, ui, mvc } = joint;

const graph = new dia.Graph();

const paper = new dia.Paper({
    model: graph,
    background: {
        color: '#F8F9FA',
    },
    async: true,
    cellViewNamespace: shapes
});

document.getElementById('paper').appendChild(paper.el);

const rect1 = new shapes.standard.Rectangle({
    position: { x: 100, y: 100 },
    size: { width: 100, height: 50 },
    attrs: {
        label: {
            text: 'Hello'
        }
    }
});

const rect2 = new shapes.standard.Cylinder({
    position: { x: 100, y: 200 },
    size: { width: 100, height: 50 },
    attrs: {
        label: {
            text: 'World'
        }
    }
});

graph.addCell([rect1, rect2]);

paper.on('element:pointerdown', (elementView, evt) => {

    const LABEL_SELECTOR = 'label';
    const SNAP_THRESHOLD = 10;

    // Start interaction only if the label was clicked.
    if (!evt.target.closest(`[joint-selector="${LABEL_SELECTOR}"]`)) return;
    // Prevent dragging the element if the label was clicked.
    elementView.preventDefaultInteraction(evt);
    // Create a listener that will handle the pointermove and pointerup events.
    const listener = new mvc.Listener();
    listener.listenTo(paper, {
        'element:pointermove': (elementView, evt, x, y) => {
            const element = elementView.model;
            let { x: relX, y: relY } = element.getRelativePointFromAbsolute(x, y);
            // Snap to the center of the element if close enough.
            // Unless the Shift key is pressed.
            if (!evt.shiftKey) {
                const { width, height } = element.size();
                if (Math.abs(relX - width / 2) < SNAP_THRESHOLD) relX = width / 2;
                if (Math.abs(relY - height / 2) < SNAP_THRESHOLD) relY = height / 2;
            }
            // Update label position
            element.attr(LABEL_SELECTOR, {
                x: relX,
                y: relY,
    ...