Skip to content

Commit

Permalink
feat: add complex preview feature
Browse files Browse the repository at this point in the history
foo
  • Loading branch information
philippfromme committed Sep 29, 2023
1 parent 62c0d8d commit 6507ae6
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 0 deletions.
154 changes: 154 additions & 0 deletions lib/features/complex-preview/ComplexPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import {
attr as svgAttr,

Check failure on line 2 in lib/features/complex-preview/ComplexPreview.js

View workflow job for this annotation

GitHub Actions / Build (ubuntu-20.04)

'svgAttr' is defined but never used. Allowed unused vars must match /^_/u
clear as svgClear,
create as svgCreate
} from 'tiny-svg';

import { getVisual } from '../../util/GraphicsUtil';

import { isConnection } from '../../util/ModelUtil';

import { translate } from '../../util/SvgTransformUtil';

/**
* @typedef {import('../../model/Types').Element} Element
* @typedef {import('../../model/Types').Shape} Shape
* @typedef {import('../../util/Types').Point} Point
* @typedef {import('../../util/Types').Rect} Rect
*
* @typedef { { element: Element, delta: Point } } MovedOption
* @typedef { { shape: Shape, bounds: Rect } } ResizedOption
*
* @typedef { {
* created?: Element[],
* removed?: Element[],
* moved?: MovedOption[],
* resized?: ResizedOption[]
* } } CreateOptions
*/

const LAYER_NAME = 'complex-preview';

/**
* Complex preview for shapes and connections.
*/
export default class ComplexPreview {
constructor(canvas, graphicsFactory, previewSupport) {
this._canvas = canvas;
this._graphicsFactory = graphicsFactory;
this._previewSupport = previewSupport;

this._markers = [];
}

/**
* Create complex preview.
*
* @param {CreateOptions} options
*/
create(options) {

// there can only be one complex preview at a time
this.cleanUp();

const {
created = [],
moved = [],
removed = [],
resized = []
} = options;

const layer = this._canvas.getLayer(LAYER_NAME);

// shapes and connections to be created
created.filter(element => !isHidden(element)).forEach(element => {
let gfx;

if (isConnection(element)) {
gfx = this._graphicsFactory._createContainer('connection', svgCreate('g'));

this._graphicsFactory.drawConnection(getVisual(gfx), element);
} else {
gfx = this._graphicsFactory._createContainer('shape', svgCreate('g'));

this._graphicsFactory.drawShape(getVisual(gfx), element);

translate(gfx, element.x, element.y);
}

this._previewSupport.addDragger(element, layer, gfx);
});

// elements to be moved
moved.forEach(({ element, delta }) => {
this._previewSupport.addDragger(element, layer, undefined, 'djs-dragging');

this._canvas.addMarker(element, 'djs-element-hidden');

this._markers.push([ element, 'djs-element-hidden' ]);

const dragger = this._previewSupport.addDragger(element, layer);

if (isConnection(element)) {
translate(dragger, delta.x, delta.y);
} else {
translate(dragger, element.x + delta.x, element.y + delta.y);
}
});

// elements to be removed
removed.forEach(element => {
this._previewSupport.addDragger(element, layer, undefined, 'djs-dragging');

this._canvas.addMarker(element, 'djs-element-hidden');

this._markers.push([ element, 'djs-element-hidden' ]);
});

// elements to be resized
resized.forEach(({ shape, bounds }) => {
const gfx = this._graphicsFactory._createContainer('shape', svgCreate('g'));

this._graphicsFactory.drawShape(getVisual(gfx), shape, {
width: bounds.width,
height: bounds.height
});

translate(gfx, bounds.x, bounds.y);

this._previewSupport.addDragger(shape, layer, gfx);

this._canvas.addMarker(shape, 'djs-dragging');

this._markers.push([ shape, 'djs-dragging' ]);
});
}

cleanUp() {
svgClear(this._canvas.getLayer(LAYER_NAME));

this._markers.forEach(([ element, marker ]) => this._canvas.removeMarker(element, marker));

this._markers = [];

this._previewSupport.cleanUp();
}

show() {
this._canvas.showLayer(LAYER_NAME);
}

hide() {
this._canvas.hideLayer(LAYER_NAME);
}
}

ComplexPreview.$inject = [
'canvas',
'graphicsFactory',
'previewSupport'
];

function isHidden(element) {
return element.hidden;
}
9 changes: 9 additions & 0 deletions lib/features/complex-preview/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import ComplexPreview from './ComplexPreview';

/**
* @type { import('didi').ModuleDeclaration }
*/
export default {
__init__: [ 'complexPreview' ],
complexPreview: [ 'type', ComplexPreview ]
};

0 comments on commit 6507ae6

Please sign in to comment.