Goal: To center an object (horizontally and vertically) inside another object (rectangle or group) on canvas
via Fabric.js
or via Javascript which keeps the original object aspect ratio the same, but also not exceed the parent object width/height proportions?
The parent object (rectangle or group) won't be centered on the canvas
element.
Here's the code I have so far: https://stackblitz.com/edit/angular-my8hky
My app.component.ts
so far:
canvas: fabric.Canvas;
ngOnInit() {
this.canvas = new fabric.Canvas('canvas');
var rect = new fabric.Rect({
left: 100,
top: 50,
width: 300,
height: 200,
fill: '#eee'
});
this.canvas.add(rect);
fabric.Image.fromURL('https://angular.io/assets/images/logos/angular/logo-nav@2x.png', (img) => {
let bounds = rect.getBoundingRect();
let oImg = img.set({
left: bounds.left,
top: bounds.top,
width: rect.width
}).scale(1);
this.canvas.add(oImg).renderAll();
});
}
Not only is the new object not centered vertically, but also not centered horizontally if the rectangle object height is decreased (for example to 50px
in height).
I realize I'm only declaring the inner image object width to be the same as the parent rectangle boundary width.
Current solution:
Parent rectangle width: 300
and height: 200
:
Parent rectangle width: 300
and height: 50
:
Desired solution:
Parent rectangle width: 300
and height: 200
:
Parent rectangle width: 300
and height: 50
:
Can anyone assist?
Figured it out.. Here's the StackBlitz: https://stackblitz.com/edit/angular-pg4fis
The trick was to first add the rectangle to a Fabric
group, like so:
var rect = new fabric.Rect({
left: 100,
top: 50,
width: 450,
height: 200,
fill: '#e3e3e3',
});
var rectGroup = new fabric.Group([rect], {
name: 'Rectangle',
});
this.canvas.add(rectGroup);
Then, I was able to establish the parent (group) element boundaries and use a variable scaling factor to set the image via Math
functionality:
fabric.Image.fromURL('https://angular.io/assets/images/logos/angular/logo-nav@2x.png', (img) => {
let bounds = rectGroup.getBoundingRect();
const scaleFactor = Math.min(
Math.min(1, bounds.width / img.width),
Math.min(1, bounds.height / img.height)
);
img.scale(scaleFactor);
img.set({
top: bounds.top + Math.max(bounds.height - img.height * scaleFactor, 0)/2,
left: bounds.left + Math.max(bounds.width - img.width * scaleFactor, 0)/2,
});
rectGroup.addWithUpdate(img);
this.canvas.renderAll();
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.