Skip to content

Commit

Permalink
feat(canvas): add #scrollToElement function
Browse files Browse the repository at this point in the history
  • Loading branch information
marstamm committed Apr 23, 2021
1 parent a749219 commit 0129993
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 1 deletion.
43 changes: 42 additions & 1 deletion lib/core/Canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@ import {
} from '../util/Collections';

import {
getType
getType,
getBBox as getBoundingBox
} from '../util/Elements';

import { asTRBL } from '../layout/LayoutUtil';

import {
append as svgAppend,
attr as svgAttr,
Expand Down Expand Up @@ -859,6 +862,44 @@ Canvas.prototype.scroll = function(delta) {
return { x: matrix.e, y: matrix.f };
};

/**
* Scrolls the viewbox to contain the given element.
* Optionally specify a padding to be applied to the edges.
*
* @param {Object} [element] the element to scroll to.
* @param {Object|Number} [padding=100] the padding to be applied. Can also specify top, bottom, left and right.
*
*/
Canvas.prototype.scrollToElement = function(element, padding) {
var defaultPadding = 100;
if (!padding) {
padding = {};
}
if (typeof padding === 'number') {
defaultPadding = padding;
}

padding = {
top: padding.top || defaultPadding,
right: padding.right || defaultPadding,
bottom: padding.bottom || defaultPadding,
left: padding.left || defaultPadding
};

var elementTrbl = asTRBL(getBoundingBox(element)),
bbTrbl = asTRBL(this.viewbox()),
zoom = this.zoom();

var dRight = Math.max(0, zoom * (elementTrbl.right - bbTrbl.right) + padding.right),
dLeft = Math.min(0, zoom * (elementTrbl.left - bbTrbl.left) - padding.left),
dBottom = Math.max(0, zoom * (elementTrbl.bottom - bbTrbl.bottom) + padding.bottom),
dTop = Math.min(0, zoom * (elementTrbl.top - bbTrbl.top) - padding.top);

var dx = dRight || dLeft,
dy = dBottom || dTop;

this.scroll({ dx: -dx, dy: -dy });
};

/**
* Gets or sets the current zoom of the canvas, optionally zooming
Expand Down
105 changes: 105 additions & 0 deletions test/spec/core/CanvasSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -951,6 +951,111 @@ describe('Canvas', function() {

});

describe('#scrollToElement', function() {

beforeEach(function() {
container = TestContainer.get(this);
});
beforeEach(createDiagram({ canvas: { width: 500, height: 500 } }));


it('scrolls element into view', inject(function(canvas) {

// given
var element = { x: 650, y: 650, width: 50, height: 50 };

// when
canvas.scrollToElement(element);

// then
var newViewbox = canvas.viewbox();
expect(newViewbox.x).to.equal(300);
expect(newViewbox.y).to.equal(300);

}));


it('takes zoom into account', inject(function(canvas) {

// given
var element = { x: 650, y: 650, width: 50, height: 50 };
canvas.zoom(2);

// when
canvas.scrollToElement(element);

// then
var newViewbox = canvas.viewbox();
expect(newViewbox.x).to.equal(500);
expect(newViewbox.y).to.equal(500);

}));


it('does not scroll when inside bounds', inject(function(canvas) {

// given
var element = { x: 100, y: 100, width: 10, height: 10 };

// when
canvas.scrollToElement(element);

// then
var newViewbox = canvas.viewbox();
expect(newViewbox.x).to.equal(0);
expect(newViewbox.y).to.equal(0);

}));


it('adds default padding', inject(function(canvas) {

// given
var element = { x: 0, y: 0, width: 10, height: 10 };

// when
canvas.scrollToElement(element);

// then
var newViewbox = canvas.viewbox();
expect(newViewbox.x).to.equal(-100);
expect(newViewbox.y).to.equal(-100);

}));


it('can specify padding', inject(function(canvas) {

// given
var element = { x: 0, y: 0, width: 10, height: 10 };

// when
canvas.scrollToElement(element, 200);

// then
var newViewbox = canvas.viewbox();
expect(newViewbox.x).to.equal(-200);
expect(newViewbox.y).to.equal(-200);

}));

it('can have specific directional padding', inject(function(canvas) {

// given
var element = { x: 0, y: 0, width: 10, height: 10 };

// when
canvas.scrollToElement(element, { left: 500 });

// then
var newViewbox = canvas.viewbox();
expect(newViewbox.x).to.equal(-500);
expect(newViewbox.y).to.equal(-100);

}));

});


describe('zoom', function() {

Expand Down

0 comments on commit 0129993

Please sign in to comment.