Skip to content
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 for fabric 6.0 #8299

Open
asturur opened this issue Sep 18, 2022 · 178 comments
Open

🧐 Breaking changes for fabric 6.0 #8299

asturur opened this issue Sep 18, 2022 · 178 comments
Labels

Comments

@asturur
Copy link
Member

asturur commented Sep 18, 2022

b.0.0-beta16

This list is in progress and is meant to be an easy go to place to add things and find them when the time comes to write a document on what has changed.
This will be a list of descriptive items, extended as needed to capture behavior changes.
Apart from what is described here MANY bugs have been fixed in the process.

Generic concepts

  • Imports we moved from import { fabric } from 'fabric' to import { Canvas, Rect, util } from 'fabric' or import * as fabric from 'fabric'. To avoid packaging issues node has its own entrypoint import { StaticCanvas } from 'fabric/node'. This means there is no fabric namespace/object anymore.

  • method chaining is now deprecated, don't use it anymore. Not all methods were chainable, and chaining seems to offer limited advantages ( maybe saving 1-2 bytes in the code you write when minified? unsure what else ). Just for consistency sake and to be free to start returning useful information from some methods we will stop using it. We didn't remove it from everywhere so that there isn't unnecessary breakage, but you should consider that unsafe to use, since will break entirely on the next major release after 6.0
    ( add detailed list of where has been removed so far )

  • Callbacks are mostly gone, all of the functions that took a callback now return a Promise, this on top of being breaking slightly alter code behavior when is fixed. Before sync code would execute the callback synchronously, now is chained to however the browser handle the promise ( not sure if it goes in the event loop and under which circumstances ). Promises support #3684

  • TS: The code base is typed! If you used @types/fabric you should uninstall it

  • Prototype Mutation:
    Fabric has moved to native classes. No more createClass or object.util.extend. You can still mutate the prototype, however, properties do not exist on the prototype in native classes. Look into getDefaults instead.

  • scene vs. viewport
    We introduced these concepts to describe the rendering/view planes as follows: The viewer is viewing the scene (what is rendered/"playing") from the viewport. The scene was considered is the past as the absolute plane whereas the viewport wasn't feat(Canvas): provide correctly named canvas pointer methods. BREAKING: rm _normalizePointer, restorePointerVpt #9175.
    Normally geometry calculations occur in the scene with the exception of padding which is a viewport scalar.

    • All events have a scenePoint and viewportPoint properties replacing the deprecated and confusing absolutePointer and pointer properties. Brushes are still in need of this change.
    • dep Canvas#getPointer in favor of getScenePoint or getViewportPoint
    • Using viewportTransform is rather confusing with this change (especially with sendPointToPlane etc.) perhaps be renaming to sceneTransform is the correct migration path in the future.
  • React Compatibility:

    • Ensure proper disposal in useEffect, especially with React 18. Refer to this hook for guidance.
    • Async Disposal: Handle async nature of dispose method. The asynchronous disposal of Canvas and StaticCanvas safeguards an edge case in which dispose is called while rendering is still in progress. This should burden your react app.
    • DOM Mutation: Fabric modifies the DOM and cleans up after itself as long as Canvas#dispose is called

Collection

  • not available as a standard object as fabric.Collection any longer, was never meant to, it was a constrain of the previous build system ( we had no imports or require or bundling before ).
  • insertAt method signature changed from insertAt(object, index) to insertAt(index, ...objects)
  • Collection now owns the stack too, methods were renamed to accommodate Group:
    • sendObjectToBack sendToBack
    • bringObjectToFront bringToFront
    • sendObjectBackwards sendBackwards
    • bringObjectForward bringForward
    • moveObjectTo moveTo
  • Support to stack operations with active selection is gone

Canvas and StaticCanvas

  • Canvas.dispose and StaticCanvas.dispose are now async In order to handle some concurrency issue with requestAnimationFrame, dispose is now checking and waiting for any uncancellable render to finish. This could have some side effects, especially in complex environments with UI frameworks and hot reload of code.

  • trying to initialize a canvas that has already been initialized fix(Canvas): Safeguard from multiple initialization #7776 is not breaking, it saves the dev from a silent breakage that they weren't aware of

  • removed canvas.straightenObject wasn't really useful.

  • changed cloneWithoutData , now it does not clone backgrounds.

  • canvas.clone now correctly return either a canvas or staticCanvas

  • drawClipPathOnCanvas signature changed: now accepts the clipPath as a second argument instead of rechecking its existence

  • getCenter renamed to getCenterPoint dep(Canvas#getCenter): migrate to getCenterPoint #7699

  • add returns the length of the array of objects after adding, like Array#push

  • remove returns an array with the removed objects inside

  • insertAt method signature changed (refer to the Collection section)

  • removed sendToBack, bringToFront, sendBackward, moveTo, bringForward ( and gained similar methods from collection (refer to the Collection section)

  • Canvas#freeDrawingBrush is not set by default

  • scene vs. viewport changes

    • dep getPointer in favor of getScenePoint or getViewportPoint
    • rm _normalizePointer, restorePointerVpt
  • rm interactive flag, use instance of Canvas instead

  • rm setBackgroundColor, setBackgroundImage, setOverlayColor, setOverlayImage: assign the property directly and render the canvas

Object

  • BREAKING Coords system improvements:
    • removed lineCoords
    • aCoords should be treated as protected , if you need the scene corners of an object use getCoords
    • fixed coords to respect grouping and nesting, see the Group section
    • removed absolute, calculate from geometry methods signatures (all listed methods operate in the scene):
      • getCoords
      • intersectsWithRect
      • intersectsWithObject
      • isContainedWithinObject
      • isContainedWithinRect
      • getBoundingRect
      • containsPoint changed signature entirely and fixed
    • getRelativeXY/setRelativeXY to get/set the coordinate in the parent plane, getXY/setXY to get/set the coordinate in the scene plane
    • adjustPosition is gone. It took a parameter only, was internally unused, didn't take care of internal edge cases setPositionByOrigin is more flexible
    • rm _setOriginToCenter and _resetOrigin change(): rm _setOriginToCenter and _resetOrigin #9179
    • Control coords (oCoords) are calculated only if the object has a canvas ref
  • type has become a static field and should be used only for serialization with classRegistry. There is still a deprecated getter on the object for compatibility reasons. Avoid using it.
  • Object looses the stack methods, instead of guessing which was the stack we refer to when we move forward/backward we do that from the stack itself BREAKING(Object Stacking): 🔙 refactor logic to support Group 🔝 #8461, see the Collection section
  • stateful functionality is deprecated, is officially removed, but is still reacheable. Don't use it. Comparing large set of propeties to detect a change doesn't really play well neither with performance nor with edge cases. stateful and statefulCache are removed. stateful was used to fire an object modified every render cycle in which a change in state properties was determiend. All the events that can modify an object already fire an object:modified event, and the user has no ability to change colors or state outside developer written code, so there is no really need for event firing here. statefulCache was an experiment and the suggestion to use set(property, value) replaced it since long. FabricJS internally still use some stateful logic for now, but the intention is to get rid of it.
  • methods like center, centerH, centerV, viewportCenter are gone. Those were aliases for the canvas methods, use them instead.
  • animate changed to adapt to animation changes
  • The controls object is not shared between instances - it is not on the prototype as all class fields
  • BREAKING: Object#getObjectScaling, Object#getTotalObjectScaling now returns Point instead of {scaleX,scaleY} BREAKING chore(): Reuse fabric.Point logic for scaling and naming consistency #7710

Text

  • see Text styles under the Serialization section
  • rename data-fabric-hiddentextarea to data-fabric with value textarea, if you were using hasAttribute('data-fabric-hiddentextarea') now you have to use getAttribute('data-fabric') and then check for equality with textarea or change your cssSelector accordingly.
  • _getStyleDeclaration returns an empty object instead of undefined when style is not set.
  • controls can be used in editing mode

Polyline Polygon Path

  • _setPositionDimensions (considered private in the past), has been renamed to setDimensions. The logic with which Polyline based object calculate the size is changed. There wasn't an api in 5.x to change the size, but devs needed to do it anyway and the alternative was to create a new object. Is not called setPositionAndDimensions because the logic to correcly change size while keeping a visual correct position is not there yet and maybe it won't.
  • exposed long desired poly controls createPolyControls

Group

  • complete rewrite described in V6: 🎉 Group Rewrite #7670
  • CONCEPT: Group rewrite exposes a change in concept - strict object tree. An object can belong to one parent.
  • exposed the parent property on FabricObject alongside group to allow an object to return to its parent after being deselected from an active selection.
  • addWithUpdate is gone, now add does what it has to do.
  • LayoutManager has been introduced to handle group layout refactor(): Layout Manager #9152. By default it will be fit-content, meaning the group will fit around its objects, updating when objects are added/removed/modified.

Controls

Serialization

  • Text#styles is now exported differently. This is BREAKING only if you are handling the style object post export The default object we exported was large most of the time, with tons of empty keys and verbosity. It seems reasonable to think that most of the time text is styled in some chunk of text with coherent different styles ( eg: a red word in a black text or some words underlined and some not more than a rainbow of different stylings per object ) for that reason we changed the approach of serialization to an array with start and end index for the style. We didn't apply that to actual runtime code because we were unsure of performance, so at least for version 6, styles at runtime are going to be the same. It is highly recommended to not fiddle with the style object directly and to treat it as internal, using the public facing methods to apply changes. feat(Text): condensed styles structure v6 #8006
  • populateWithProperties => pick populate with properties was used internally to add the extra options to exported objects. Between spread operator and new syntax, a generic pick approach seemed more correct.
  • toJSON is not an alias of toObject. This was a long standing bug, but also a breaking change. toJSON never accepted additional properties and will give you only the default object export. toJSON is meant for JSON#stringify interoperability and is not meant to be used in your code base directly. reference fix(): weird toJson bug #8111
  • classRegistry => register your subclasses to use them during serialization
  • NUM_FRACTION_DIGIT moved to config and incremented from 2 to 4

Brushes

PatternBrush: removed the getPatternSrcFunction. Wasn't working anymore since the refactor of Pattern and also a super weird practice.

Animation

  • animation util does not accept anymore the += or -= syntax for changes, nor accept the byValue option. You can specify an animation only by startValue and endValue.
  • Every animation returns a class with a cancel method to cancel the animation.
  • Animation callback onChange and onComplete will fire for every animation generated by set of properties. This change is necessary because if we assign the callbacks to only one animation, in case that animation will be cancelled, the other ones won't have any registered callback.

Utils

  • makeBoundingBoxFromPoints signature change. The transformation is not supported anymore and requires real points
  • removal of all the array utils ( min, max, find those are well covered by es6 now and also is out of fabric scope to provide generic data manipulation utils )
  • some utils are considered internal and not exposed anymore ( TODO add list )
  • clone and extend have been removed. Those were used in all examples unfortunately so the community has likely adopted them, consider migrating to a well known common library for those functionalities ( lodash, underscore ... ). Avoid using such utilities on classes.
  • makeElementSelectable and makeElementUnselectable are removed. Those were needed internally and one of them is still used internally, but is not a fabricJS core functionality and not part of the api anymore.
  • exposed sendObjectToPlane, sendPointToPlane, sendVectorToPlane to ease common usages of linear algebra. Check them out, you will benefit from it.
  • exposed more vector utils

Misc

@asturur asturur pinned this issue Sep 18, 2022
@asturur asturur changed the title Breaking changes for fabric 6.0 🧐 Breaking changes for fabric 6.0 Sep 18, 2022
@ShaMan123
Copy link
Contributor

ShaMan123 commented Sep 19, 2022

@asturur
Copy link
Member Author

asturur commented Sep 19, 2022

i ll keep formatting the top post to be the reference to read. I ll threat this asyncronously, feel free to continue add known changes if you know them. i was planning to revisit all the PRs and extract

@ShaMan123
Copy link
Contributor

ShaMan123 commented Sep 19, 2022

What do you think about planting console.warn in highly breaking stuff that won't surface as errors?

@asturur
Copy link
Member Author

asturur commented Sep 19, 2022

we can with the /* dev mode */ thing

@ShaMan123
Copy link
Contributor

I think it is better to add an internal util and use rollup to remove console logs or use an env var or something
Those comments are useless now, right?

@ShaMan123
Copy link
Contributor

ShaMan123 commented Sep 20, 2022

from http://fabricjs.com/v6-breaking-changes:

@ShaMan123
Copy link
Contributor

@ShaMan123
Copy link
Contributor

How about we release v6.0.0 with warnings and v6.0.1 without?

@ShaMan123
Copy link
Contributor

Or add an option to config? or both

@asturur
Copy link
Member Author

asturur commented Sep 20, 2022

I think it is better to add an internal util and use rollup to remove console logs or use an env var or something Those comments are useless now, right?

Are useless now but can be activated, can safely become dead code removal with a rollup plugin that swap the comment with a falsy if, with or without an utility to log.
Let's keep this thread for logging more than discussing or it get noisy fast

@ShaMan123
Copy link
Contributor

OK I will PR an option I have in mind and we discuss there

@asturur
Copy link
Member Author

asturur commented Sep 20, 2022

OK I will PR an option I have in mind and we discuss there
Preferably something at build time, no runtime

@ShaMan123 ShaMan123 added the v6 label Oct 14, 2022
@ShaMan123
Copy link
Contributor

ShaMan123 commented Oct 15, 2022

Polyline/Polygon/Path _setPositionDimensions => setDimensions #8344

@rogeriochaves
Copy link

Group has no longer the method addWithUpdate, only add

@asturur
Copy link
Member Author

asturur commented Oct 28, 2022

From latest TS pr:
some chainability removed: setCoords, scale, scaleToWidth, scaleToHeight
adjustPosition is gone ( what it was even for? )

Going to update all the upper main description now

@asturur
Copy link
Member Author

asturur commented Nov 20, 2022

BREAKING insertAt signature - (objects, index) => (index, ...objects). Done to comply with the rest of the methods and resemblance to Array.splice
BREAKING removed fabric.Collection, but I can put it back

@ShaMan123
Copy link
Contributor

ShaMan123 commented Dec 14, 2022

toLocalPoint => controlsUtils.getLocalPoint or unexported normalizePoint

@asturur
Copy link
Member Author

asturur commented Dec 29, 2022

Added all the breaking changes from #8461 and #8519

@asturur
Copy link
Member Author

asturur commented Jan 3, 2023

Need to add the breaking changes from repacking the lib, as soon as export work i can have a full list

@asturur
Copy link
Member Author

asturur commented Jan 9, 2023

Added breakign changes from animation simplification and the removal of canvas aliases on object

@ShaMan123
Copy link
Contributor

This is a great practice, we should stick to it now on for future versions

@ShaMan123
Copy link
Contributor

EraserBrush isn't part of v6 yet, so that is breaking for now #8499

@ShaMan123
Copy link
Contributor

moved to native classes => no more createClass

@hqw567
Copy link

hqw567 commented Jul 12, 2024

Hello @asturur , v6 version of the loadFromJSON, v5.3 version of the export of json to do compatible processing?

@asturur
Copy link
Member Author

asturur commented Jul 12, 2024

I think we didn't introduce any breaking change to import / export if you export the defaults properties.

@Smrtnyk
Copy link

Smrtnyk commented Jul 12, 2024

I was able to import json created in v5 just fine after upgrade to v6

@girish1729
Copy link

girish1729 commented Jul 15, 2024

Please change import * as fabric from 'fabric' to

import * as fabric from 'fabric/node' when workin in node.

If you don't you get the bug I reported, document not found.

@alwalxed
Copy link

Can someone explain these?

  • Namespace: The Fabric namespace/object has been removed.
  • Class Registry: Introduced to manage the absence of the namespace.
  • Prototype Mutation: Moved to native classes. Use getDefaults instead.
  • Controls Object: Not shared between instances.

@hamzawain7
Copy link

hamzawain7 commented Jul 27, 2024

@alwalxed
Namespace: The Fabric namespace/object has been removed.
There is no longer a fabric instance in the window, i.e., no window. fabric. It would be best to use the ESM syntax in your code (import * as fabric from 'fabric')

Class Registry: Introduced to manage the absence of the namespace.
Use class registry when defining new classes that extend fabric classes so that fabric can easily convert them to and from a plain object, e.g., the enliveObject function.

Prototype Mutation: Moved to native classes. Use getDefaults instead.
You can't do fabric.Object.prototype.hasControls = false; to set hasControls to false for all fabric objects as code has been moved to native classes. To set default values, you can see how to change defaults for controls. A similar approach can be taken for fabric objects:
https://fabricjs.github.io/docs/configuring-controls/

Controls Object: Not shared between instances.
Like the above, controls are now moved to native classes and attached to the individual fabric objects rather than being shared between fabric objects. See related control changes here:
https://fabricjs.github.io/docs/configuring-controls/

@alwalxed
Copy link

@alwalxed

Namespace: The Fabric namespace/object has been removed.

There is no longer a fabric instance in the window, i.e., no window. fabric. It would be best to use the ESM syntax in your code (import * as fabric from 'fabric')

Class Registry: Introduced to manage the absence of the namespace.

Use class registry when defining new classes that extend fabric classes so that fabric can easily convert them to and from a plain object, e.g., the enliveObject function.

Prototype Mutation: Moved to native classes. Use getDefaults instead.

You can't do fabric.Object.prototype.hasControls = false; to set hasControls to false for all fabric objects as code has been moved to native classes. To set default values, you can see how to change defaults for controls. A similar approach can be taken for fabric objects:

https://fabricjs.github.io/docs/configuring-controls/

Controls Object: Not shared between instances.

Like the above, controls are now moved to native classes and attached to the individual fabric objects rather than being shared between fabric objects. See related control changes here:

https://fabricjs.github.io/docs/configuring-controls/

Much appreciated!

@asturur
Copy link
Member Author

asturur commented Jul 30, 2024

In particular the namespace removal means that before we identified classes by searching them on the fabric object. If tou made a custom class names 'postit' you needed to be sure fabric.postit existed or serialization wouldn't work. Now instead we register it with an utility when they are imported. The namespace was a blocker for code splitting

@leila-huang
Copy link

I can see that the function mentioned in this issue (rotation in viewport transform) is not yet supported. Will this function be considered for 6.x? Or is there any way to implement this feature? Thanks!

@Mthew
Copy link

Mthew commented Jul 30, 2024

heey there, currently upgrade the fabic version to v6+, and createclass method was removing in this new version. upgrade my code as follows:
`import * as fabric from "fabric";
import { QRCodeSVG } from "qrcode.react";

import { FabricObjectMetadataOptions } from "../common/interfaces";
import { convertJSXToXMLString } from "../utils";

export class QrCodeObject extends fabric.Group {
static type = "Qrcode";
private element: fabric.FabricObject;

constructor(options: QrCodeObjectProps) {
super([], {
...options,
lockRotation: true,
lockSkewingX: true,
lockSkewingY: true,
});

this.element = {} as fabric.FabricObject;
this.initialize(options);
return this;

}

private async initialize(options: QrCodeObjectProps) {
const svgString = QrCodeObject.toSVGString(options);
this.element = await this.createSVGFromString(svgString, options);
this.add(this.element);
this.lockMiddleControls();
}

private createSVGFromString(
svgString: string,
options: QrCodeObjectProps
): Promise<fabric.FabricObject> {
return new Promise((resolve) => {
fabric.loadSVGFromString(svgString).then((resultSVG) => {
const obj = fabric.util.groupSVGElements(
resultSVG.objects as fabric.FabricObject[],
resultSVG.options
);
obj.set({
metadata: options.metadata,
});
resolve(obj);
});
});
}

static toSVGString({
content,
widthContainer,
level = "L",
bgColor = "#ffffff",
fgColor = "#000000",
}: QrCodeReactProps) {
const svg = QRCodeSVG({
value: content,
size: widthContainer,
level,
bgColor,
fgColor,
});

const xmlString = convertJSXToXMLString(svg);
return xmlString;

}

private lockMiddleControls() {
this.setControlsVisibility({
mt: false,
mb: false,
ml: false,
mr: false,
bl: true,
br: true,
tl: true,
tr: true,
mtr: false,
});
}

toJSON() {
return super.toObject();
}
}

export interface QrCodeReactProps {
content: string;
widthContainer: number;
bgColor?: string;
fgColor?: string;
level?: "L" | "M" | "Q" | "H";
includeMargin?: boolean;
imageSettings?: {
src: string;
height: number;
width: number;
x?: number;
y?: number;
excavate?: boolean;
};
}

export interface QrCodeObjectProps
extends QrCodeReactProps,
Partial<fabric.FabricObjectProps> {
id: string;
name: string;
metadata: FabricObjectMetadataOptions;
content: string;
widthContainer: number;
}

declare module "fabric" {
namespace fabric {
class Qrcode extends QrCodeObject {
constructor(element: any, options: any);
}
}
}
`
the code working good, the custome componenent render and after I save ir with canvas.ToJson() method, but I restore canvas with the loadFromJSON function I get the the following error: fabric: No class registered for Qrcode

So far I have not found a way to fix this error. If someone can help me, I would appreciate it.

@Ryoma007
Copy link

Ryoma007 commented Jul 31, 2024

heey there, currently upgrade the fabic version to v6+, and createclass method was removing in this new version. upgrade my code as follows: `import * as fabric from "fabric"; import { QRCodeSVG } from "qrcode.react";

import { FabricObjectMetadataOptions } from "../common/interfaces"; import { convertJSXToXMLString } from "../utils";

export class QrCodeObject extends fabric.Group { static type = "Qrcode"; private element: fabric.FabricObject;

constructor(options: QrCodeObjectProps) { super([], { ...options, lockRotation: true, lockSkewingX: true, lockSkewingY: true, });

this.element = {} as fabric.FabricObject;
this.initialize(options);
return this;

}

private async initialize(options: QrCodeObjectProps) { const svgString = QrCodeObject.toSVGString(options); this.element = await this.createSVGFromString(svgString, options); this.add(this.element); this.lockMiddleControls(); }

private createSVGFromString( svgString: string, options: QrCodeObjectProps ): Promise<fabric.FabricObject> { return new Promise((resolve) => { fabric.loadSVGFromString(svgString).then((resultSVG) => { const obj = fabric.util.groupSVGElements( resultSVG.objects as fabric.FabricObject[], resultSVG.options ); obj.set({ metadata: options.metadata, }); resolve(obj); }); }); }

static toSVGString({ content, widthContainer, level = "L", bgColor = "#ffffff", fgColor = "#000000", }: QrCodeReactProps) { const svg = QRCodeSVG({ value: content, size: widthContainer, level, bgColor, fgColor, });

const xmlString = convertJSXToXMLString(svg);
return xmlString;

}

private lockMiddleControls() { this.setControlsVisibility({ mt: false, mb: false, ml: false, mr: false, bl: true, br: true, tl: true, tr: true, mtr: false, }); }

toJSON() { return super.toObject(); } }

export interface QrCodeReactProps { content: string; widthContainer: number; bgColor?: string; fgColor?: string; level?: "L" | "M" | "Q" | "H"; includeMargin?: boolean; imageSettings?: { src: string; height: number; width: number; x?: number; y?: number; excavate?: boolean; }; }

export interface QrCodeObjectProps extends QrCodeReactProps, Partial<fabric.FabricObjectProps> { id: string; name: string; metadata: FabricObjectMetadataOptions; content: string; widthContainer: number; }

declare module "fabric" { namespace fabric { class Qrcode extends QrCodeObject { constructor(element: any, options: any); } } } ` the code working good, the custome componenent render和after I save ir with canvas.ToJson() method, but I restore canvas with the loadFromJSON function I get the the following error: fabric: No class registered for Qrcode

So far I have not found a way to fix this error. If someone can help me, I would appreciate it.

try:

import { classRegistry } from 'fabric'
classRegistry.setClass(QrCodeObject , 'Qrcode')

@Mthew3
Copy link

Mthew3 commented Jul 31, 2024

heey there, currently upgrade the fabic version to v6+, and createclass method was removing in this new version. upgrade my code as follows: `import * as fabric from "fabric"; import { QRCodeSVG } from "qrcode.react";
import { FabricObjectMetadataOptions } from "../common/interfaces"; import { convertJSXToXMLString } from "../utils";
export class QrCodeObject extends fabric.Group { static type = "Qrcode"; private element: fabric.FabricObject;
constructor(options: QrCodeObjectProps) { super([], { ...options, lockRotation: true, lockSkewingX: true, lockSkewingY: true, });

this.element = {} as fabric.FabricObject;
this.initialize(options);
return this;

}
private async initialize(options: QrCodeObjectProps) { const svgString = QrCodeObject.toSVGString(options); this.element = await this.createSVGFromString(svgString, options); this.add(this.element); this.lockMiddleControls(); }
private createSVGFromString( svgString: string, options: QrCodeObjectProps ): Promise<fabric.FabricObject> { return new Promise((resolve) => { fabric.loadSVGFromString(svgString).then((resultSVG) => { const obj = fabric.util.groupSVGElements( resultSVG.objects as fabric.FabricObject[], resultSVG.options ); obj.set({ metadata: options.metadata, }); resolve(obj); }); }); }
static toSVGString({ content, widthContainer, level = "L", bgColor = "#ffffff", fgColor = "#000000", }: QrCodeReactProps) { const svg = QRCodeSVG({ value: content, size: widthContainer, level, bgColor, fgColor, });

const xmlString = convertJSXToXMLString(svg);
return xmlString;

}
private lockMiddleControls() { this.setControlsVisibility({ mt: false, mb: false, ml: false, mr: false, bl: true, br: true, tl: true, tr: true, mtr: false, }); }
toJSON() { return super.toObject(); } }
export interface QrCodeReactProps { content: string; widthContainer: number; bgColor?: string; fgColor?: string; level?: "L" | "M" | "Q" | "H"; includeMargin?: boolean; imageSettings?: { src: string; height: number; width: number; x?: number; y?: number; excavate?: boolean; }; }
export interface QrCodeObjectProps extends QrCodeReactProps, Partial<fabric.FabricObjectProps> { id: string; name: string; metadata: FabricObjectMetadataOptions; content: string; widthContainer: number; }
declare module "fabric" { namespace fabric { class Qrcode extends QrCodeObject { constructor(element: any, options: any); } } } ` the code working good, the custome componenent render和after I save ir with canvas.ToJson() method, but I restore canvas with the loadFromJSON function I get the the following error: fabric: No class registered for Qrcode
So far I have not found a way to fix this error. If someone can help me, I would appreciate it.

try:

import { classRegistry } from 'fabric'
classRegistry.setClass(QrCodeObject , 'Qrcode')

thanks, work for me

@felipefranzim
Copy link

I really didn't understand how to extend the toObject in V6, like the code below:

var rect = new fabric.Rect();

rect.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      name: this.name
    });
  };
})(rect.toObject);

canvas.add(rect);

rect.name = 'trololo';

console.log(JSON.stringify(canvas));

Someone could help me?

@asturur
Copy link
Member Author

asturur commented Aug 2, 2024

How do I use methods like new fabric.Frame in V6? or new fabric.Background, do they still exist?

For exemplo:

initialize() { const frame = new fabric.Frame({ ...defaultFrameOptions, absolutePositioned: this.config.clipToFrame, })

Could anyone help me?

I have never seen fabric.Frame or fabric.Background, maybe were some extensions from some other repository?

@asturur
Copy link
Member Author

asturur commented Aug 2, 2024

I really didn't understand how to extend the toObject in V6, like the code below:

var rect = new fabric.Rect();

rect.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      name: this.name
    });
  };
})(rect.toObject);

canvas.add(rect);

rect.name = 'trololo';

console.log(JSON.stringify(canvas));

Someone could help me?

@felipefranzim in order to extend objects you have to use classes.
Do you need to add name to rect?
You can do that by replacing the toObject function of rect.

  /**
   * Returns object representation of an instance
   * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
   * @return {Object} object representation of an instance
   */
  Rect.prototype.toObject = function<
    T extends Omit<Props & TClassProperties<this>, keyof SProps>,
    K extends keyof T = never
  >(propertiesToInclude: K[] = []): Pick<T, K> & SProps {
    return super.toObject([...RECT_PROPS, ...propertiesToInclude, 'name']);
  }

for example

@felipefranzim
Copy link

felipefranzim commented Aug 2, 2024

I really didn't understand how to extend the toObject in V6, like the code below:

var rect = new fabric.Rect();

rect.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      name: this.name
    });
  };
})(rect.toObject);

canvas.add(rect);

rect.name = 'trololo';

console.log(JSON.stringify(canvas));

Someone could help me?

@felipefranzim in order to extend objects you have to use classes. Do you need to add name to rect? You can do that by replacing the toObject function of rect.

  /**
   * Returns object representation of an instance
   * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
   * @return {Object} object representation of an instance
   */
  Rect.prototype.toObject = function<
    T extends Omit<Props & TClassProperties<this>, keyof SProps>,
    K extends keyof T = never
  >(propertiesToInclude: K[] = []): Pick<T, K> & SProps {
    return super.toObject([...RECT_PROPS, ...propertiesToInclude, 'name']);
  }

for example

Thank you @asturur! I think i undestood. If you dont mind, could send this same code in Javascript as I'm not so confident in TS?

The code below is exactly the code I was using in V5:

var rect = new fabric.Rect();

rect.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      name: this.name
    });
  };
})(rect.toObject);

canvas.add(rect);

@alwalxed
Copy link

alwalxed commented Aug 2, 2024

Can anyone look into this? I am having this weird issue after upgrading to v6: #10036

@MaximSemenov
Copy link

MaximSemenov commented Sep 14, 2024

I've upgraded from v3.6.6 to v6.4.2 and now it is silently not doing anything.

I see why it is not doing anything because when our product worked fine on v3.6.6 in Chrome DevTool I would see Canvas element in DOM highlighted for a second kinda reacting on adding things and now it is not doing anything as if I'm not working with it. I've fixed a lot of things to migrate us but it is still nothing.

How to debug it?

Some code chunks down below:

// Method for adding objects
    addAll(objects: fabric.Object[]) {
        let length = objects.length;
        for (let i = 0; i < length; i++) {
            this.add(objects[i]); // Method for adding 1 object
            if (objects[i] instanceof Stage) {
                this.add((<Stage>objects[i]).stageCenter);
            }
        }
        this.requestRenderAll();
    }
// Method for adding 1 object itself

    add(...object: fabric.Object[]): fabric.StaticCanvas {
        object.forEach((x) => {
            this.registry.register(x);
            this._objects.splice(this.getIndexToInsert(x), 0, x);
        });
        // @ts-ignore
        if (this._onObjectAdded) {
            object.forEach((x) => {
                // @ts-ignore
                this._onObjectAdded(x);
            })
        }
        this.renderOnAddRemove && this.requestRenderAll();
        return this;
    }

It looks like add method is overwrite the genuine fabric canvas add method...

Thanks for any help

@asturur
Copy link
Member Author

asturur commented Sep 15, 2024

I've upgraded from v3.6.6 to v6.4.2 and now it is silently not doing anything.

I see why it is not doing anything because when our product worked fine on v3.6.6 in Chrome DevTool I would see Canvas element in DOM highlighted for a second kinda reacting on adding things and now it is not doing anything as if I'm not working with it. I've fixed a lot of things to migrate us but it is still nothing.

How to debug it?

Some code chunks down below:

// Method for adding objects
    addAll(objects: fabric.Object[]) {
        let length = objects.length;
        for (let i = 0; i < length; i++) {
            this.add(objects[i]); // Method for adding 1 object
            if (objects[i] instanceof Stage) {
                this.add((<Stage>objects[i]).stageCenter);
            }
        }
        this.requestRenderAll();
    }
// Method for adding 1 object itself

    add(...object: fabric.Object[]): fabric.StaticCanvas {
        object.forEach((x) => {
            this.registry.register(x);
            this._objects.splice(this.getIndexToInsert(x), 0, x);
        });
        // @ts-ignore
        if (this._onObjectAdded) {
            object.forEach((x) => {
                // @ts-ignore
                this._onObjectAdded(x);
            })
        }
        this.renderOnAddRemove && this.requestRenderAll();
        return this;
    }

It looks like add method is overwrite the genuine fabric canvas add method...

Thanks for any help

Please open an a discussion with those requests. The migration issue is not the correct place. Also include where that code you added comes from, is it from a custom class? is it from fabric itself?

@EugenGedroyc
Copy link

I really didn't understand how to extend the toObject in V6, like the code below:

var rect = new fabric.Rect();

rect.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      name: this.name
    });
  };
})(rect.toObject);

canvas.add(rect);

rect.name = 'trololo';

console.log(JSON.stringify(canvas));

Someone could help me?

@felipefranzim in order to extend objects you have to use classes. Do you need to add name to rect? You can do that by replacing the toObject function of rect.

  /**
   * Returns object representation of an instance
   * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
   * @return {Object} object representation of an instance
   */
  Rect.prototype.toObject = function<
    T extends Omit<Props & TClassProperties<this>, keyof SProps>,
    K extends keyof T = never
  >(propertiesToInclude: K[] = []): Pick<T, K> & SProps {
    return super.toObject([...RECT_PROPS, ...propertiesToInclude, 'name']);
  }

for example

Thank you @asturur! I think i undestood. If you dont mind, could send this same code in Javascript as I'm not so confident in TS?

I need to add only the ID property, because when exporting to SVG(toSVG) it is there, but when exporting to JSON properties are not added at all set using the set() method. I also did not understand how it works: where to take RECT_PROPS and the object 'super' from.

fabric.Rect.prototype.toObject = function (propertiesToInclude = []) {
  const allProperties = [...RECT_PROPS, ...propertiesToInclude, 'name'];
  return super.toObject(allProperties);
};

@Rishi-AECInspire
Copy link

Can anybody help me with what is replacement of fabric.texturesize

@asturur
Copy link
Member Author

asturur commented Oct 11, 2024

I really didn't understand how to extend the toObject in V6, like the code below:

var rect = new fabric.Rect();

rect.toObject = (function(toObject) {
  return function() {
    return fabric.util.object.extend(toObject.call(this), {
      name: this.name
    });
  };
})(rect.toObject);

canvas.add(rect);

rect.name = 'trololo';

console.log(JSON.stringify(canvas));

Someone could help me?

@felipefranzim in order to extend objects you have to use classes. Do you need to add name to rect? You can do that by replacing the toObject function of rect.

  /**
   * Returns object representation of an instance
   * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
   * @return {Object} object representation of an instance
   */
  Rect.prototype.toObject = function<
    T extends Omit<Props & TClassProperties<this>, keyof SProps>,
    K extends keyof T = never
  >(propertiesToInclude: K[] = []): Pick<T, K> & SProps {
    return super.toObject([...RECT_PROPS, ...propertiesToInclude, 'name']);
  }

for example

Thank you @asturur! I think i undestood. If you dont mind, could send this same code in Javascript as I'm not so confident in TS?

I need to add only the ID property, because when exporting to SVG(toSVG) it is there, but when exporting to JSON properties are not added at all set using the set() method. I also did not understand how it works: where to take RECT_PROPS and the object 'super' from.

fabric.Rect.prototype.toObject = function (propertiesToInclude = []) {
  const allProperties = [...RECT_PROPS, ...propertiesToInclude, 'name'];
  return super.toObject(allProperties);
};

please look here #10071

especially this test

  test('with default custom properties', () => {
    FabricObject.customProperties = ['key2'];
    const obj = new FabricObject({ name: 'test1', key2: 'value2' });
    expect(obj.name).toBe('test1');
    expect(obj.key2).toBe('value2');
    const serialized = obj.toObject();
    expect(serialized.name).toBe(undefined);
    expect(serialized.key2).toBe('value2');
  });

@asturur
Copy link
Member Author

asturur commented Oct 11, 2024

Can anybody help me with what is replacement of fabric.texturesize

Please look at the config object.
import { config } from 'fabric';

look this file
https://github.com/fabricjs/fabric.js/blob/master/src/config.ts

@EugenGedroyc
Copy link

EugenGedroyc commented Oct 14, 2024

test('with default custom properties', () => {
FabricObject.customProperties = ['key2'];
const obj = new FabricObject({ name: 'test1', key2: 'value2' });
expect(obj.name).toBe('test1');
expect(obj.key2).toBe('value2');
const serialized = obj.toObject();
expect(serialized.name).toBe(undefined);
expect(serialized.key2).toBe('value2');
});

Thank you very much. This helped me to set custom properties for all objects:

fabric.FabricObject.customProperties = ['id'];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests