javascript - zoom ve pan sonrası fabricJS'de nesne hizalaması
Angular ile fabricJS kullanıyorum, örneğin bir öğeyi sola hizalamak istediğimde aşağıdaki yöntemi kullanıyorum
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();
}
}
Hizalama, yalnızca yakınlaştırma %100 olduğunda sorunsuz çalışıyor; yakınlaştırmayı değiştirir veya tuvali kaydırırsam her şey yanlış yöne gidiyor. Aşağıda yakınlaştırma açma/kapatma için kullandığım yöntemler var
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;
});
Birden fazla soru ve fabricJS Dokümantasyonunu okuduktan sonra alignLeft() metodunu şu şekilde değiştirdim:
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();
}
}
Cevap #1
canvas için top left, top right, bottom left, bottom right koordinatlarını görünüm alanına göre almak için ViewPortCoordinates (bkz. fabricJS Dokümanları) kullanmanız gerekir.
Tuval öğesinin tasarım özellikleri üzerindeki uzantısını tl, tr, bl, br olarak tanımlayın. Eğer tuval yakınlaştırılmamış/taşınmamışsa, bu noktalar tuvalin dört köşesidir; eğer tuval viewportTransformed ise, bu noktalar tuval öğesinin düz, dönüştürülmemiş koordinatlardaki uzantısını gösterir. Koordinatlar @method calcViewportBoundaries ile güncellenir.
alignLeft() metodu için bunu aşağıdaki şekilde güncelleyebilirsiniz:
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 });
}
