Skip to content

Commit

Permalink
dia.ElementView: fix getNodeMatrix() and getNodeBBox() for elements w…
Browse files Browse the repository at this point in the history
…ith rotatable group (#1791)
  • Loading branch information
kumilingus authored Aug 25, 2022
1 parent 75a3c5f commit 50619b2
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 9 deletions.
29 changes: 22 additions & 7 deletions src/dia/CellView.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -255,11 +255,20 @@ export const CellView = View.extend({

getNodeBBox: function(magnet) {

var rect = this.getNodeBoundingRect(magnet);
var magnetMatrix = this.getNodeMatrix(magnet);
var translateMatrix = this.getRootTranslateMatrix();
var rotateMatrix = this.getRootRotateMatrix();
return V.transformRect(rect, translateMatrix.multiply(rotateMatrix).multiply(magnetMatrix));
const rect = this.getNodeBoundingRect(magnet);
const transformMatrix = this.getRootTranslateMatrix().multiply(this.getNodeRotateMatrix(magnet));
const magnetMatrix = this.getNodeMatrix(magnet);
return V.transformRect(rect, transformMatrix.multiply(magnetMatrix));
},

getNodeRotateMatrix(node) {
if (!this.rotatableNode || this.rotatableNode.contains(node)) {
// Rotate transformation is applied to all nodes when no rotatableGroup
// is present or to nodes inside the rotatableGroup only.
return this.getRootRotateMatrix();
}
// Nodes outside the rotatable group
return V.createSVGMatrix();
},

getNodeUnrotatedBBox: function(magnet) {
Expand Down Expand Up @@ -730,9 +739,15 @@ export const CellView = View.extend({

getNodeMatrix: function(magnet) {

var metrics = this.nodeCache(magnet);
const metrics = this.nodeCache(magnet);
if (metrics.magnetMatrix === undefined) {
var target = this.rotatableNode || this.el;
const { rotatableNode, el } = this;
let target;
if (rotatableNode && rotatableNode.contains(magnet)) {
target = rotatableNode;
} else {
target = el;
}
metrics.magnetMatrix = V(magnet).getTransformToElement(target);
}
return V.createSVGMatrix(metrics.magnetMatrix);
Expand Down
3 changes: 2 additions & 1 deletion src/highlighters/mask.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,12 @@ export const mask = HighlighterView.extend({
vel.remove();
}
const highlighterBBox = cellView.getNodeBoundingRect(node).inflate(padding + maskClip);
const highlightMatrix = cellView.getNodeRotateMatrix(node).multiply(cellView.getNodeMatrix(node));
const maskEl = this.getMask(cellView, V(node));
this.addMask(cellView.paper, maskEl);
vel.attr(highlighterBBox.toJSON());
vel.attr({
'transform': V.matrixToTransformString(cellView.getNodeMatrix(node)),
'transform': V.matrixToTransformString(highlightMatrix),
'mask': `url(#${maskEl.id})`,
'fill': color
});
Expand Down
2 changes: 1 addition & 1 deletion src/highlighters/stroke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export const stroke = HighlighterView.extend({
highlightNode(cellView, node) {
const { vel, options } = this;
const { padding, layer } = options;
let highlightMatrix = cellView.getNodeMatrix(node);
let highlightMatrix = cellView.getNodeRotateMatrix(node).multiply(cellView.getNodeMatrix(node));
// Add padding to the highlight element.
if (padding) {
if (!layer && node === cellView.el) {
Expand Down
75 changes: 75 additions & 0 deletions test/jointjs/elementView.js
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,81 @@ QUnit.module('elementView', function(hooks) {

elementView.model.resize(200, 300, { passed: true });
});

QUnit.test('getNodeBBox(), getNodeMatrix()', function(assert) {

elementView.model.set({
markup: [
{
tagName: 'g',
selector: 'rotatable',
children: [
{
tagName: 'rect',
selector: 'rectInside',
},
{
tagName: 'circle',
selector: 'circle',
attributes: {
transform: 'translate(11,13)',
r: 5
}
}
],
}, {
tagName: 'rect',
selector: 'rectOutside',
},
],
attrs: {
rectInside: {
x: 21,
y: 13,
width: 20,
height: 10
},
rectOutside: {
x: 21,
y: 13,
width: 20,
height: 10
}
}
});

elementView.model.resize(100, 100).translate(100, 100).rotate(90);

var rectInside = elementView.findBySelector('rectInside')[0];
assert.checkBboxApproximately(1, elementView.getNodeBBox(rectInside), {
x: 177,
y: 121,
width: 10,
height: 20
});

assert.equal(V.matrixToTransformString(elementView.getNodeMatrix(rectInside)), 'matrix(1,0,0,1,0,0)');

var rectOutside = elementView.findBySelector('rectOutside')[0];
assert.checkBboxApproximately(1, elementView.getNodeBBox(rectOutside), {
x: 121,
y: 113,
width: 20,
height: 10
});

assert.equal(V.matrixToTransformString(elementView.getNodeMatrix(rectOutside)), 'matrix(1,0,0,1,0,0)');

var circle = elementView.findBySelector('circle')[0];
assert.checkBboxApproximately(1, elementView.getNodeBBox(circle), {
x: 182,
y: 106,
width: 10,
height: 10
});

assert.equal(V.matrixToTransformString(elementView.getNodeMatrix(circle)), 'matrix(1,0,0,1,11,13)');
});
});

QUnit.module('no rotatable group and no scalable group', function(hooks) {
Expand Down
2 changes: 2 additions & 0 deletions types/joint.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,8 @@ export namespace dia {

getNodeMatrix(node: SVGElement): SVGMatrix;

getNodeRotateMatrix(node: SVGElement): SVGMatrix;

getNodeBoundingRect(node: SVGElement): g.Rect;

getBBox(opt?: { useModelGeometry?: boolean }): g.Rect;
Expand Down

0 comments on commit 50619b2

Please sign in to comment.