Thank you for the time taken to read, and potentially help. So I've started experimenting with canvas and fabric.js - no experience what so ever.
I've hit a stumbling block, and that's getting the origin, or rather the location of a moving object. It appears that originX, originY is always the same value, regardless of where an object is moved to.
For a visual indicator, I've created an image:
What I don't understand is why originX, and originY is always left, and top? I assume this is the location of the control for offset?
I'm hoping their is some built in canvas/fabric methods, If not could any of you kind folk point me in the right direction on trying to output the correct origins of when an object is dropped?
A small snippet of just trying to log the output when moving an object:
canvas.on('object:moving', e => {
console.log("moving target, X: " + e.target.originX);
console.log("moving target, Y: " + e.target.originY);
console.log("moving active obj, X: " + canvas.getActiveObject().originX);
console.log("moving active obj, Y: " + canvas.getActiveObject().originY);
const coords = e.target.calcCoords();
const trans = e.target.calcTransformMatrix();
console.log(coords);
console.log(trans);
console.log(e.target.getOrigin());
});
Unless you modify the origin of a fabricjs object, querying it's .originX
and .originY
won't ever return
anything else than left and top respectively simply because these properties do not refer to it's on-screen position.
An object's origin refers to it's own coordinate space and it's meaning becomes more obvious if you think about a transformation like scale applied to an actual object.
Have a look at the following example. The origin of the square to the left is at center/center while it's top/left for the square to the right.
let canvas = new fabric.Canvas("c1");
let context = document.getElementById("c1").getContext("2d");
let rectA = new fabric.Rect({
width: 50,
height: 50,
fill: "blue",
left: 50,
top: 50,
originX: "center",
originY: "center"
});
canvas.add(rectA);
let rectB = new fabric.Rect({
width: 50,
height: 50,
fill: "blue",
left: 150,
top: 50,
originX: "left",
originY: "top"
});
canvas.add(rectB);
let scale = 1;
let a = 0;
function updateCanvas() {
rectA.scale(scale);
rectB.scale(scale);
scale = 1 + Math.sin(a);
a += 0.1;
canvas.renderAll();
context.beginPath();
context.arc(50, 50, 2, 0, 2 * Math.PI, false);
context.fillStyle = 'red';
context.fill();
context.lineWidth = 2;
context.strokeStyle = 'red';
context.stroke();
context.beginPath();
context.arc(150, 50, 2, 0, 2 * Math.PI, false);
context.fill();
context.stroke();
}
let interval = setInterval(updateCanvas, 100);
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/451/fabric.min.js" integrity="sha512-qeu8RcLnpzoRnEotT3r1CxB17JtHrBqlfSTOm4MQzb7efBdkcL03t343gyRmI6OTUW6iI+hShiysszISQ/IahA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<canvas id="c1" width="400" height="200"></canvas>
If you want to know which quadrant of the canvas is occupied by your object, you have to manually calculate it based on your object's coordinates.
Here's another example - try dragging the circle around.
var canvas = new fabric.Canvas('c1', {
backgroundColor: "#cccccc"
});
canvas.add(new fabric.Circle({
radius: 30,
fill: '#f55',
top: 100,
left: 100
}));
canvas.on('object:moving', e => {
if (e.target.left < canvas.width / 2) {
if (e.target.top < canvas.height / 2) {
console.log("TopLeft");
} else {
console.log("BottomLeft");
}
} else {
if (e.target.top < canvas.height / 2) {
console.log("TopRight");
} else {
console.log("BottomRight");
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/451/fabric.min.js" integrity="sha512-qeu8RcLnpzoRnEotT3r1CxB17JtHrBqlfSTOm4MQzb7efBdkcL03t343gyRmI6OTUW6iI+hShiysszISQ/IahA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<canvas id="c1" width="400" height="200"></canvas>