-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Breaking changes on 4.0.0-rc1: hard to overrides fabricJs #6494
Comments
The idea is to gather feedback on how those controls handlers are used. Some functions in controls.actions.js are not meant to be reused for different scopes ( like the scaling logic, either you use it for scaling or nothing else ). Ideally we can build fabricJS without controls entirely, and you add your own file that attach your own controls, we do not want people to override methods and then be locked to old version, but instead, let them add their own functionality on their project OR in external reusable libraries.
|
Can you be more specific on what kind of control you want to change and that you can't do with the actual latest version of the library? ( 4.0 rc1) |
The actual behavior of Textbox for the scaleY or Equally is increase fontsize. Or I want to increase the size of the box without change fontsize. To do this, only change on followed method is necessary. So I must copy several function and redefine controls to be able to do this.
|
I understand. So eventually you do not touch the scale handler. You leave as it is. You create an action handler that can change height ( one that change width exist ) and you combine both to change the corner. You attach this new action handler to the textbox controls or special class controls. I ll come back with an extended example, now i can't, but i wanted to let you know it can be done and is actually much simpler. |
I'm not sure if you read the introduction docs and demos before starting your override: As you have noticed, the Textbox class changes the width of the object when using the scaling control. in fabric 3.x and below , this was done with some code like your, Now it works differently, talking of the the textbox example, the MR and ML controls do change width and they do it with a specific handler, the handler is in This is change width. /**
* Action handler to change textbox width
* Needs to be wrapped with `wrapWithFixedAnchor` to be effective
* @param {Event} eventData javascript event that is doing the transform
* @param {Object} transform javascript object containing a series of information around the current transform
* @param {number} x current mouse x position, canvas normalized
* @param {number} y current mouse y position, canvas normalized
* @return {Boolean} true if some change happened
*/
function changeWidth(eventData, transform, x, y) {
var target = transform.target, localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),
strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleX : 1),
newWidth = Math.abs(localPoint.x / target.scaleX) - strokePadding;
target.set('width', Math.max(newWidth, 0));
return true;
} and this is the wrapper: /**
* Wrap an action handler with saving/restoring object position on the transform.
* this is the code that permits to obects to keep their position while transforming.
* @param {Function} actionHandler the function to wrap
* @return {Function} a function with an action handler signature
*/
function wrapWithFixedAnchor(actionHandler) {
return function(eventData, transform, x, y) {
var target = transform.target, centerPoint = target.getCenterPoint(),
constraint = target.translateToOriginPoint(centerPoint, transform.originX, transform.originY),
actionPerformed = actionHandler(eventData, transform, x, y);
target.setPositionByOrigin(constraint, transform.originX, transform.originY);
return actionPerformed;
};
} Then this is how we attach controls to objects: Now it seems that you want the corners to change width and height instead of scaling. You need an handler to change height first of all and you can easily create it looking at the one that change width: /**
* Action handler to change textbox HEIGHT
* Needs to be wrapped with `wrapWithFixedAnchor` to be effective
* @param {Event} eventData javascript event that is doing the transform
* @param {Object} transform javascript object containing a series of information around the current transform
* @param {number} x current mouse x position, canvas normalized
* @param {number} y current mouse y position, canvas normalized
* @return {Boolean} true if some change happened
*/
function changeHeight(eventData, transform, x, y) {
var target = transform.target, localPoint = getLocalPoint(transform, transform.originX, transform.originY, x, y),
strokePadding = target.strokeWidth / (target.strokeUniform ? target.scaleY : 1),
newHeight = Math.abs(localPoint.y / target.scaleY) - strokePadding;
target.set('height', Math.max(newHeight, 0));
return true;
} Then eventually to reuse code, you want to just combine those together: function changeWidthAndHeight(eventData, transform, x, y) {
fabric.controlsUtils.changeHeight(eventData, transform, x, y);
changeWidth(eventData, transform, x, y);
} Then you want to wrap it with the wrapper so that the object has a fixed position while you drag the corners var finalHandler = fabric.controlsUtils.wrapWithFixedAnchor(changeWidthAndHeight); Now exactly has is done for the object prototype, create 4 new controls A B C D to attach to your textboxes, name does not matter. var myControlSet = {};
// let's keep the rotation control
myControlSet.rotationControl = fabric.Object.prototype.controls.mtr;
// let's keep the standard change width form textbox control
myControlSet.mr = fabric.Textbox.prototype.controls.mr;
myControlSet.ml = fabric.Textbox.prototype.controls.ml;
// repeat this for br, tl, tr with different x and y values
myControlSet.bl = new fabric.Control({
x: -0.5,
y: 0.5,
actionHandler: finalHandler,
cursorStyleHandler: controlsUtils.scaleCursorStyleHandler,
actionName: 'notImportant',
});
// attach them to your custom class at app init.
MyDifferentTextbox.prototype.controls = myControlSet; This is the process to help creat custom interaction without overriding fabricJS code. The interface for actions should be stable and not change with fabricJS versions anymore. |
Oh greats ! My brain was staying in I have some notes:
Thanks lot for the time spent to answer me. It's very pleasant 👍 |
1: maybe i exported it later than rc1, yesterday i tagget a 4.0.0 official. 2: because fabric was started in 2010, and went on changing one line at time. I am mostly alone in mantaining it and a full rewrite with modern JS + transpilier while is nice is less beneficial than new features, helping with issues, writing docs. 3: so the object controls on the prototype is mutable, so if you do: This is in the nature of JS and mutation, a cool feature to use carefully, i suggest to swap the whole control set at once, is easier. The way i use it is that i have, for example, 3 control set. A normal one, a crop one, a perspective one. in this example you see the control set has 12 controls instead of the classic 9, 4 of which are completely out of the image area. in this demo here: the controls are as many as the polygon point and let you modify the polygon points ( the code isn't super easy or slim ) |
Your last message give me lots of idea to resolve some problems with my crop system ! 👍 I consider that original message receives explanations, so I close the issue. |
Hello,
I updated to 4.0.0-rc1. A lot of things are broken in my developments that extend your library. So I'm looking to fix this.
1 ) But I can't properly overrides method of
controls.actions.js
without copy/past the entirely file.. And it's mandatory to redefine alldefault_controls.js
to take care about overrides... I search to overrides behavior of scaleX/Y/Equally of Textbox.Somethings is scheduled to help developers to overrides easier the lib ? Or I miss something ?
2 ) Can you explain why the lib export some methods to
fabric.controlsUtils
but at the execution this methods are infabric.controlHandlers
? (term not found in the code of lib)Thanks to your help.
The text was updated successfully, but these errors were encountered: