fabricjs - matrix hierarchy
Get canvas space coordinates of group child object
by mmalex
HTML
<script src="https://rawgithub.com/kangax/fabric.js/master/dist/fabric.js"></script>
<button onclick="getCoords();">Get Yellow Rect Coords</button>
<button onclick="recenterCanvas()">Pan canvas to red dot</button>
<p id="output">yellow rect coords: {}</p>
<canvas id="c" width="400" height="400"></canvas>
<p>
Hint: Move and rotate fabricJs group of objects.<br>Click the button to calculate coordinates of yellow rectangle.
</p>
CSS
canvas {
border: 1px solid #999;
display: inline-block;
}
button {
margin-top: 20px;
}
body {
font-family: sans-serif;
font-size: 10pt;
}
#output {
font-family: consolas;
}
JavaScript
// 1. arrange canvas layout with group of two rectangles
var canvas = new fabric.Canvas(document.getElementById('c'));
canvas.setBackgroundImage("http://mbnsay.com/rayys/images/bricks_background.jpg", canvas.renderAll.bind(canvas));
var rect = new fabric.Rect({
width: 100,
height: 100,
left: 50,
top: 50,
fill: 'rgba(255,0,0,0.25)'
});
var smallRect = new fabric.Rect({
width: 12,
height: 12,
left: 150 - 12,
top: 50 + 50 - 12 / 2 - 10,
fill: 'rgba(250,250,0,0.5)'
});
// 2. add a position marker (red dot) for visibility and debug reasons
var refRect = new fabric.Rect({
width: 3,
height: 3,
left: 100,
top: 100,
fill: 'rgba(255,0,0,0.75)'
});
var group = new fabric.Group([rect, smallRect], {
originX: 'center',
originY: 'center'
});
canvas.add(group);
canvas.add(refRect);
canvas.renderAll();
function panTo(canvas, obj) {
let w = canvas.getWidth();
let h = canvas.getHeight();
let targetX = obj.left + obj.width / 2;
let targetY = obj.top + obj.height / 2;
canvas.absolutePan(new fabric.Point(-w/2+targetX, -h/2+targetY))
}
function recenterCanvas() {
panTo(canvas, refRect);
canvas.bringToFront(refRect);
canvas.renderAll();
}
// 3. calculate coordinates of child object in canvas space coords
function getCoords() {
// get transformation matrixes for object and group individually
var mGroup = group.calcTransformMatrix(true);
// flag true means that we need local transformation for the object,
// i.e. how object is positioned INSIDE the group
var mObject = smallRect.calcTransformMatrix(true);
console.log("group: ", fabric.util.qrDecompose(mGroup));
console.log("rect: ", fabric.util.qrDecompose(mObject));
// get total transformattions that were applied to the child object,
// the...