Reputation: 13389
I have a fabric js rectangle and I would like to move the control squares inside the rectangle.
I don't know if this is possible in the version I'm using, I didn't found how to do this.
Note I am using fabric.js version: 2.4.6
Here is what I've tried:
this._cropRect = new window.fabric.Rect({
top: 0,
left: 0,
width: this.options.canvasWidth,
height: this.options.canvasHeight,
fill: 'red',
strokeWidth: 0,
lockRotation: true,
lockScalingFlip: true,
lockUniScaling: true,
hasBorders: false,
hasRotatingPoint: false,
padding: -12,
cornerColor: 'red',
borderColor: 'red',
cornerStroke: 10,
borderScaleFactor: 2,
cornerSize: CROP_CORNER_SIZE,
borderOpacityWhenMoving: 1,
})
this._cropRect.set('globalCompositeOperation', 'destination-out')
this._fabricCanvas.add(this._cropRect)
this._fabricCanvas.setActiveObject(this._cropRect)
this._fabricCanvas.requestRenderAll()
Here is the image of what I have now and what I want to achieve:
I have created a jsfiddle: https://jsfiddle.net/t94ksgeq/
Upvotes: 1
Views: 1748
Reputation: 1130
You could extend the draw function of the cropping rectangles.
cropRect.drawControls = function(t, e) {
e = e || {};
var i = this._calculateCurrentDimensions(),
// Modified variable r and n
r = i.x - this.cornerSize,
n = i.y - this.cornerSize,
s = e.cornerSize || this.cornerSize,
o = -(r + s) / 2,
a = -(n + s) / 2,
h = void 0 !== e.transparentCorners ? e.transparentCorners : this.transparentCorners,
c = void 0 !== e.hasRotatingPoint ? e.hasRotatingPoint : this.hasRotatingPoint,
l = h ? "stroke" : "fill";
return t.save(), t.strokeStyle = t.fillStyle = e.cornerColor || this.cornerColor, this.transparentCorners || (t.strokeStyle = e.cornerStrokeColor || this.cornerStrokeColor), this._setLineDash(t, e.cornerDashArray || this.cornerDashArray, null), this._drawControl("tl", t, l, o, a, e), this._drawControl("tr", t, l, o + r, a, e), this._drawControl("bl", t, l, o, a + n, e), this._drawControl("br", t, l, o + r, a + n, e), this.get("lockUniScaling") || (this._drawControl("mt", t, l, o + r / 2, a, e), this._drawControl("mb", t, l, o + r / 2, a + n, e), this._drawControl("mr", t, l, o + r, a + n / 2, e), this._drawControl("ml", t, l, o, a + n / 2, e)), c && this._drawControl("mtr", t, l, o + r / 2, a - this.rotatingPointOffset, e), t.restore(), this
}
in this code r
and n
represent the x and y values and I found that if you subtract the cornersize. The recetangles get drawn inside the image. Now the rectangles are exactly inside the the rectangle on the edge, but ofcourse you can modify it to your needs.
EDIT:
After further inspection I found that you can adjust the position of the resize controls in the _setCornerCoords
function.
function degrees_to_radians(degrees) {
var pi = Math.PI;
return degrees * (pi/180);
}
cropRect._setCornerCoords = function () {
var t,
e,
i = this.oCoords,
r = degrees_to_radians(45 - this.angle),
n = .707106 * this.cornerSize,
s = n * fabric.util.cos(r),
o = n * fabric.util.sin(r);
// Again this is setup to be the cornerSize, but this can be any number
var p = this.cornerSize;
var q = p / 2;
for (var a in i) {
t = i[a].x;
e = i[a].y;
// Check which kind of corner it is and translate it accordingly
switch(a) {
case "tl":
t += q;
e += q;
break;
case "tr":
t -= q;
e += q;
break;
case "br":
t -= q;
e -= q;
break;
case "bl":
t += q;
e -= q;
break;
}
i[a].corner = {
tl: { x: t - o, y: e - s },
tr: { x: t + s, y: e - o },
bl: { x: t - s, y: e + o },
br: { x: t + o, y: e + s }
}
}
}
This enables the user to resize within the previously drawn corners. The resize may seem not aligned with the mouse position (hardly noticable in usage).
This is because you begin resizing not from the corner. And the resize function follows the difference in mouse position. And uses some different coordinates, but I was unable to find those.
Upvotes: 4