React-diagrams: How to lock a canvas widget (not only nodes)

Created on 13 Mar 2020  路  5Comments  路  Source: projectstorm/react-diagrams

Hi,

Is there a way to fix the canvas widget position?
I have tried using model.setLocked(true) according to demo: https://github.com/projectstorm/react-diagrams/blob/master/packages/diagrams-demo-gallery/demos/demo-locks/index.tsx,
but it seems to be locked only the nodes and links inside. I can still move and zoom the entire page.

Thank you in advance for your kindly response.

answered question

All 5 comments

Hey @netzanava05.

I never done this, but I would bet that to achieve this you would have to override the default state that handles canvas dragging (DragCanvasState) and add something like this:

async activated(prev) {
+ if (this.engine.getModel().isLocked()) return;

  super.activated(prev);
  this.engine.getModel().clearSelection();
  await this.engine.repaintCanvas(true);

  // ...

}

Or maybe

fireMouseMoved(event: AbstractDisplacementStateEvent) {
+ if (this.engine.getModel().isLocked()) return;

  this.engine
    .getModel()
    .setOffset(this.initialCanvasX + event.displacementX, this.initialCanvasY + event.displacementY);
  this.engine.repaintCanvas();
}

@renato-bohler @pierre-moire added those lines, nothing changed. Canvas is still draggable and zoomable/scalable. Any ideas? What am I missing?

Hmm, I tested the change and it works for me.

Here's what I did:

  1. Imported DragCanvasState into my project, including the proposed change on the fireMouseMoved method:
import {
  State,
  AbstractDisplacementState,
} from '@projectstorm/react-canvas-core';

export default class DragCanvasState extends AbstractDisplacementState {
  constructor() {
    super({
      name: 'drag-canvas',
    });
  }

  async activated(prev) {
    super.activated(prev);
    this.engine.getModel().clearSelection();
    await this.engine.repaintCanvas(true);

    // we can block layer rendering because we are only targeting the transforms
    for (const layer of this.engine.getModel().getLayers()) {
      layer.allowRepaint(false);
    }

    this.initialCanvasX = this.engine.getModel().getOffsetX();
    this.initialCanvasY = this.engine.getModel().getOffsetY();
  }

  deactivated(next: State) {
    super.deactivated(next);
    for (const layer of this.engine.getModel().getLayers()) {
      layer.allowRepaint(true);
    }
  }

  fireMouseMoved(event) {
    // (!!) This is my proposed change
    if (this.engine.getModel().isLocked()) return;

    this.engine
      .getModel()
      .setOffset(
        this.initialCanvasX + event.displacementX,
        this.initialCanvasY + event.displacementY,
      );
    this.engine.repaintCanvas();
  }
}
  1. Edited my States class to use my custom DragCanvasState:
import {
  // ...
- DragCanvasState,
} from '@projectstorm/react-canvas-core';

+import DragCanvasState from './DragCanvasState';

export default class States extends State {
  constructor() {
    // ...
+   this.dragCanvas = new DragCanvasState();
  }

To show it working, in my application, when simulation starts, the diagram model is locked. This is the result:

Peek 2020-03-30 20-21

Not sure if it's relevant, but I only wanted to remove the zoom and this works just right:

const engine = createEngine({ registerDefaultZoomCanvasAction: false });

https://github.com/projectstorm/react-diagrams/blob/1d5ab683c3fb42ab3a6b6821e51bd011cc741924/packages/react-canvas-core/src/CanvasEngine.ts#L63

Preraped PR which allows lock the canvas
https://github.com/projectstorm/react-diagrams/pull/660

Was this page helpful?
0 / 5 - 0 ratings

Related issues

quangas picture quangas  路  3Comments

ganesh-sankey picture ganesh-sankey  路  4Comments

affanshahid picture affanshahid  路  3Comments

dixitk13 picture dixitk13  路  3Comments

gugaevkirill picture gugaevkirill  路  3Comments