Skip to content

Commit

Permalink
feat: add complex preview feature
Browse files Browse the repository at this point in the history
  • Loading branch information
philippfromme committed Aug 4, 2023
1 parent 450a09b commit b6a2f3a
Show file tree
Hide file tree
Showing 2 changed files with 154 additions and 0 deletions.
145 changes: 145 additions & 0 deletions lib/features/complex-preview/ComplexPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
import {
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 } } MoveOption
* @typedef { { element: Element, attrs: Object } } ReplaceOption
* @typedef { { shape: Shape, bounds: Rect } } ResizeOption
*
* @typedef { {
* create: Element[],
* move: MoveOption[],
* replace: ReplaceOption[],
* resize: ResizeOption[]
* } } CreateOptions
*/

const LAYER_NAME = 'complex-preview';

const MARKER_DRAGGING = 'djs-dragging';

export default class ComplexPreview {
constructor(canvas, connectionPreview, graphicsFactory, previewSupport) {
this._canvas = canvas;
this._connectionPreview = connectionPreview;
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.delete();

const {
create = [],
move = [],
replace = [],
resize = []
} = options;

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

// shapes and connections to be created
create.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);
});

// shapes to be moved
move.forEach(({ element, delta }) => {
this._canvas.addMarker(element, MARKER_DRAGGING);

this._markers.push(element);

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

translate(dragger, element.x + delta.x, element.y + delta.y);

element.incoming.filter(connection => !isHidden(connection)).forEach(connection => {
const movingSource = move.find(({ element }) => element === connection.source);

if (movingSource && isMovingConnection(delta, movingSource.delta)) {

// connections to be moved
this._canvas.addMarker(connection, MARKER_DRAGGING);

this._markers.push(connection);

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

translate(dragger, delta.x, delta.y);
} else {

// connections to be laid out
console.log('layout connection', connection);
}
});
});

}

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

this._markers.forEach(element => this._canvas.removeMarker(element, MARKER_DRAGGING));

this._markers = [];
}

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

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

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

function isHidden(element) {
return element.hidden;
}

function isMovingConnection(a, b) {
return a.x === b.x && a.y === b.y;
}
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 b6a2f3a

Please sign in to comment.