javascript - Penjajaran objek di fabricJS setelah zoom dan pan
Saya menggunakan fabricJS dengan Angular ketika saya ingin menyelaraskan suatu elemen ke kiri, misalnya saya menggunakan metode berikut
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();
}
}
Penyelarasan bekerja dengan sempurna hanya ketika zoom berada pada 100%, jika saya mengubah zoom atau menggeser kanvas, semuanya menjadi salah. Di bawah ini adalah metode yang saya gunakan untuk memperbesar/memperkecil.
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;
});
Setelah saya membaca beberapa pertanyaan dan Dokumentasi fabricJS, saya mengubah metode alignLeft() menjadi berikut:
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();
}
}
Jawaban #1
Anda perlu menggunakan ViewPortCoordinates (lihat Dokumentasi fabricJS) untuk mendapatkan koordinat top left, top right, bottom left, bottom right dari canvas sesuai dengan tampilan jendela pandang.
Jelaskan perluasan elemen kanvas terhadap properti desain adalah tl, tr, bl, br. Jika kanvas tidak diperbesar/digeser, titik-titik tersebut adalah empat sudut kanvas. Jika kanvas diubah dengan viewportTransformed, titik-titik tersebut menunjukkan perluasan elemen kanvas dalam koordinat polos yang tidak ditransformasikan. Koordinat diperbarui dengan @method calcViewportBoundaries.
untuk metode alignLeft() Anda dapat memperbaruinya menjadi berikut:
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 });
}
