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 Oct 5, 2023
1 parent c5a2ea2 commit 16db7ef
Show file tree
Hide file tree
Showing 8 changed files with 507 additions and 155 deletions.
155 changes: 155 additions & 0 deletions lib/features/complex-preview/ComplexPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
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 } } 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'));

Check warning on line 67 in lib/features/complex-preview/ComplexPreview.js

View check run for this annotation

Codecov / codecov/patch

lib/features/complex-preview/ComplexPreview.js#L67

Added line #L67 was not covered by tests

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

Check warning on line 69 in lib/features/complex-preview/ComplexPreview.js

View check run for this annotation

Codecov / codecov/patch

lib/features/complex-preview/ComplexPreview.js#L69

Added line #L69 was not covered by tests
} 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);

Check warning on line 92 in lib/features/complex-preview/ComplexPreview.js

View check run for this annotation

Codecov / codecov/patch

lib/features/complex-preview/ComplexPreview.js#L92

Added line #L92 was not covered by tests
} 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 }) => {
this._canvas.addMarker(shape, 'djs-hidden');

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

this._previewSupport.addDragger(shape, layer, undefined, 'djs-dragging');

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);
});
}

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);

Check warning on line 139 in lib/features/complex-preview/ComplexPreview.js

View check run for this annotation

Codecov / codecov/patch

lib/features/complex-preview/ComplexPreview.js#L139

Added line #L139 was not covered by tests
}

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

Check warning on line 143 in lib/features/complex-preview/ComplexPreview.js

View check run for this annotation

Codecov / codecov/patch

lib/features/complex-preview/ComplexPreview.js#L143

Added line #L143 was not covered by tests
}
}

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

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

import ComplexPreview from './ComplexPreview';

/**
* @type { import('didi').ModuleDeclaration }
*/
export default {
__depends__: [ PreviewSupportModule ],
__init__: [ 'complexPreview' ],
complexPreview: [ 'type', ComplexPreview ]
};
4 changes: 4 additions & 0 deletions lib/features/preview-support/PreviewSupport.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ PreviewSupport.prototype.addDragger = function(element, group, gfx, className =

svgAppend(group, dragger);

svgAttr(dragger, 'data-complex-preview-element-id', element.id);

return dragger;
};

Expand All @@ -141,6 +143,8 @@ PreviewSupport.prototype.addFrame = function(shape, group) {

svgAppend(group, frame);

svgAttr(frame, 'data-complex-preview-element-id', shape.id);

return frame;
};

Expand Down
10 changes: 5 additions & 5 deletions test/spec/connection-preview/ConnectionPreviewSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ describe('features/connection-preview', function() {
// when
connectionPreview.drawPreview(context, true, hints);

var preview = domQuery('.djs-connection-preview', testContainer);
var preview = domQuery('.djs-dragger', testContainer);

// then
expect(preview).to.exist;
Expand All @@ -110,7 +110,7 @@ describe('features/connection-preview', function() {
// when
connectionPreview.drawPreview(context, true, hints);

var preview = domQuery('.djs-connection-preview', testContainer);
var preview = domQuery('.djs-dragger', testContainer);

// then
expect(preview).to.exist;
Expand All @@ -131,7 +131,7 @@ describe('features/connection-preview', function() {
connectionPreview.drawPreview(context, true, hints);
connectionPreview.cleanUp(context);

var preview = domQuery('.djs-connection-preview', testContainer);
var preview = domQuery('.djs-dragger', testContainer);

// then
expect(preview).not.to.exist;
Expand All @@ -154,7 +154,7 @@ describe('features/connection-preview', function() {
// when
connectionPreview.drawPreview(context, false, hints);

var preview = domQuery('.djs-connection-preview', testContainer);
var preview = domQuery('.djs-dragger', testContainer);

// then
expect(preview).to.exist;
Expand All @@ -175,7 +175,7 @@ describe('features/connection-preview', function() {
// when
connectionPreview.drawPreview(context, false, hints);

var preview = domQuery('.djs-connection-preview', testContainer);
var preview = domQuery('.djs-dragger', testContainer);

// then
expect(preview).to.exist;
Expand Down
Loading

0 comments on commit 16db7ef

Please sign in to comment.