javascript - Alignement des objets dans fabricJS après zoom et déplacement
J'utilise fabricJS avec Angular quand je veux aligner un élément à gauche par exemple j'utilise la méthode suivante
alignLeft() {
// Get Selected Elements
var obj = this.canvas.getActiveObject();
// if no element is selected
if (obj !== undefined) {
// Bounding Box of the selected element
var bound = obj.getBoundingRect();
obj.set('left', (obj.left - bound.left));
//this.canvas.getActiveObject().setCoords();
this.canvas.renderAll();
}
}
L'alignement fonctionne à merveille seulement lorsque le zoom est à 100 %, si je change le zoom ou que je déplace le canevas, tout se passe mal. Ci-dessous se trouvent les méthodes que j'utilise pour zoomer avant/arrière
this.canvas.on('mouse:wheel', function (opt) {
var delta = opt.e.deltaY;
var zoom = this.canvas.getZoom();
zoom *= 0.999 ** delta;
if (zoom > 20) zoom = 20;
if (zoom < 0.01) zoom = 0.01;
this.canvas.zoomToPoint({ x: opt.e.offsetX, y: opt.e.offsetY }, zoom.toFixed(4));
opt.e.preventDefault();
opt.e.stopPropagation();
}.bind(this));
this.canvas.on('mouse:down', function (opt) {
var evt = opt.e;
if (evt.altKey === true) {
this.isDragging = true;
this.selection = false;
this.lastPosX = evt.clientX;
this.lastPosY = evt.clientY;
}
});
this.canvas.on('mouse:move', function (opt) {
if (this.isDragging) {
var e = opt.e;
var vpt = this.viewportTransform;
vpt[4] += e.clientX - this.lastPosX;
vpt[5] += e.clientY - this.lastPosY;
this.requestRenderAll();
this.lastPosX = e.clientX;
this.lastPosY = e.clientY;
}
});
this.canvas.on('mouse:up', function (opt) {
// on mouse up we want to recalculate new interaction
// for all objects, so we call setViewportTransform
this.setViewportTransform(this.viewportTransform);
this.isDragging = false;
this.selection = true;
});
Après avoir lu plusieurs questions et la documentation de fabricJS, j'ai modifié la méthode alignLeft() comme suit :
alignLeft() {
// Get Selected Elements
var obj = this.canvas.getActiveObject();
// if no element is selected
if (obj !== undefined) {
// Bounding Box of the selected element
var bound = obj.getBoundingRect();
let p = {x: (obj.width / 2), y: obj.top}
var invertedMatrix = fabric.util.invertTransform(this.canvas.viewportTransform);
let newp = fabric.util.transformPoint(p, invertedMatrix);
obj.set('left', newp.x);
//this.canvas.getActiveObject().setCoords();
this.canvas.renderAll();
}
}
Réponse n°1
Vous devez utiliser ViewPortCoordinates (voir la documentation de fabricJS) pour obtenir les coordonnées en haut à gauche, en haut à droite, en bas à gauche, en bas à droite du canvas selon la fenêtre d'affichage.
Décrivez l'extension de l'élément canvas sur les propriétés de conception qui sont tl, tr, bl, br. Si le canvas n'est pas zoomé/déplacé, ces points sont les quatre coins du canvas. Si le canvas est transformé par la vue, ces points indiquent l'extension de l'élément canvas dans des coordonnées non transformées. Les coordonnées sont mises à jour avec la méthode @method calcViewportBoundaries.
pour la méthode alignLeft(), vous pouvez la mettre à jour comme suit :
alignLeft() {
// Get Selected Elements
var obj = this.canvas.getActiveObject();
// if no element is selected
if (obj !== undefined) {
const viwePortCoords = this.canvas.vptCoords;
obj.set('left', viwePortCoords.bl.x + (obj.width / 2));
this.canvas.renderAll();
}
this.canvas.fire('object:modified', { target: obj });
}
