fabricjs / fabric.js

Javascript Canvas Library, SVG-to-Canvas (& canvas-to-SVG) Parser
http://fabricjs.com
Other
29.04k stars 3.51k forks source link

🧐 Breaking changes for fabric 6.0 #8299

Open asturur opened 2 years ago

asturur commented 2 years ago

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

Collection

Canvas and StaticCanvas

Object

Text

Polyline Polygon Path

Group

Controls

Serialization

Brushes

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

Animation

Utils

Misc

Sara-Sultan commented 1 year ago

@ShaMan123 I also wonder how to check target from Event on object as it is unkown type canvas.on('object:scaled', e=>{ let target = e.target; }

Error Msg: Property 'target' does not exist on type 'unkown'.

ShaMan123 commented 1 year ago

That event is deprecated. object:modified instead and check for the action or actionName if you need

ShaMan123 commented 1 year ago

@bladerunner2020 please post your good comment in the relative thread #8899 and remove from this one

jiayihu commented 1 year ago

A list of a few breaking changes not listed yet (I'll update this list as we migrate to fabric v6):

abdussami-tayyab commented 1 year ago

How can we initialize a Canvas in React and ensure that the fabric.Canvas object is available in methods outside useEffect as well? Sorry I struggle with that, and would like some help there as this version provides interaction with group which I very importantly need.

Thanks for all the efforts you guys are putting and good luck!

bladerunner2020 commented 1 year ago

How can we initialize a Canvas in React...

Though it's not clear what do you mean by 'outside useEffect', I would suggest to look at the article, that helped us a lot to setup React-wrapper for fabric: https://binarapps.com/integrate-fabric-js-canvas-drawing-library-with-react-app-via-uncontrolled-component/

ShaMan123 commented 1 year ago

take a look at https://github.com/fabricjs/fabric.js/blob/master/.codesandbox/templates/next/pages/index.tsx

vinkovsky commented 1 year ago

How can we initialize a Canvas in React and ensure that the fabric.Canvas object is available in methods outside useEffect as well? Sorry I struggle with that, and would like some help there as this version provides interaction with group which I very importantly need.

Thanks for all the efforts you guys are putting and good luck!

You can wrap your canvas component with React Context

abdussami-tayyab commented 1 year ago

Thank you @vinkovsky @ShaMan123 and @bladerunner2020 .

Pardon my lack of knowledge working with ReactJS, I followed @ShaMan123 's link (even though it's Typescript and I would like JS) and got it working somehow. However, @bladerunner2020 , your solution causes an issue of canvas already initialised already mentioned in #8899 .

Happy to help provide more info if it helps.

asturur commented 1 year ago

added breaking changes from #8930

hanna-becker commented 1 year ago

Are there any breaking changes with free drawing? I'm migrating my v5 app to v6 and can't get it working just by setting isDrawingMode on the canvas to true. (It worked in my v5 app.)

ShaMan123 commented 1 year ago

Yes, thanks! Canvas#freeDrawingBrush is not set by default. so just canvas.freeDrawingBrush = new PencilBrush()

hanna-becker commented 1 year ago

Yes, thanks! Canvas#freeDrawingBrush is not set by default. so just canvas.freeDrawingBrush = new PencilBrush()

This worked. Thank you!

abdussami-tayyab commented 1 year ago

@asturur and @ShaMan123 I will start off by saying that first of all thank you for this version, it automatically helps resolve a lot of issues for me at work (most importantly object manipulation in groups (although it breaks for nested groups but that's not the purpose of this comment))

The issue is documented in this CodeSandbox (my original version is beta7 but this sandbox only had beta1), but it's also appearing here. The issue is that when I save JSON in my Firestore database (via canvas.toJSON) and try to load it via loadFromJSON, it just... throws many strange errors. Sometimes it would say No class registered for Group and sometimes it would say can't set _set on null e.

What is weird that I did not face any issue of this sort on v5 but it's breaking for v6. @ShaMan123 is it also the right way I have setup code in React in your opinion?

Happy to provide more info if needed!

edit: there's also the issue that it sometimes works fine locally and also loads the objects on canvas, but they're invisible, only when I click them do they become visible.

ShaMan123 commented 1 year ago

I didn't look into your sandbox but it is probably #9009 Open a dedicated issue next time

asturur commented 1 year ago

Added: https://github.com/fabricjs/fabric.js/pull/9018/

duydodevgithub commented 1 year ago

Hi @ShaMan123 @asturur , do you have ETA for the v6 release and not sure if we have a documentation for it yet? I am working on upgrading from v2x to v5, maybe I will wait for v6 since it has Promise support. Thank you so much for this version !

hanna-becker commented 1 year ago

I noticed that the type support for canvas.getActiveObject() is off. I was chasing down a bug because I was unaware it returned a Promise. Usually my IDE warns me about unhandled promises, but it didn't for this one, and jumping into the definition shows me this, which can't be right:

  getActiveObject(): FabricObject | undefined {
    return this._activeObject;
  }
ShaMan123 commented 1 year ago

I noticed that the type support for canvas.getActiveObject() is off. I was chasing down a bug because I was unaware it returned a Promise. Usually my IDE warns me about unhandled promises, but it didn't for this one, and jumping into the definition shows me this, which can't be right:

  getActiveObject(): FabricObject | undefined {
    return this._activeObject;
  }

It is correct, no promise

kyun commented 1 year ago

Hi, I am going to start new project with fabric.js and typescript. My question is which version should I use in production? v6 beta or v5 ? I am afraid to migrate v5 to v6. At the same time, I am not sure it is right to use beta version in production. Please give me advice.

ShaMan123 commented 1 year ago

We are working on v6 for our projects. Typescript in v6 only. The amount of fixes in v6 is overwhelming. Since you are starting, v6 is the right choice IMO - you decide

bladerunner2020 commented 1 year ago

We use 6 beta in prod. So far so good)

hanna-becker commented 1 year ago

Same here. We started a new project with v6 a month ago and it's running in production now. No regrets so far.

thisisdice commented 1 year ago

How can we use fabric.util.addClass?

Tried converting some class based examples from the fabric js website but Im running into issues.

import React, { useEffect, useRef } from 'react';
import * as fabric from 'fabric';

const AnimatedCross = ({ canvas }) => {
  const crossRef = useRef(null);

  useEffect(() => {
    const Cross = fabric.util.createClass(fabric.Object, {
      objectCaching: false,
      initialize: function (options) {
        this.callSuper('initialize', options);
        this.animDirection = 'up';

        this.width = 100;
        this.height = 100;

        this.w1 = this.h2 = 100;
        this.h1 = this.w2 = 30;
      },

      animateWidthHeight: function () {
        const interval = 2;

        if (this.h2 >= 30 && this.h2 <= 100) {
          const actualInterval = this.animDirection === 'up' ? interval : -interval;
          this.h2 += actualInterval;
          this.w1 += actualInterval;
        }

        if (this.h2 >= 100) {
          this.animDirection = 'down';
          this.h2 -= interval;
          this.w1 -= interval;
        }
        if (this.h2 <= 30) {
          this.animDirection = 'up';
          this.h2 += interval;
          this.w1 += interval;
        }
      },

      _render: function (ctx) {
        ctx.fillRect(-this.w1 / 2, -this.h1 / 2, this.w1, this.h1);
        ctx.fillRect(-this.w2 / 2, -this.h2 / 2, this.w2, this.h2);
      },
    });

    const cross = new Cross({ top: 100, left: 100 });
    crossRef.current = cross;
    canvas.add(cross);

    const animate = () => {
      cross.animateWidthHeight();
      cross.dirty = true;
      canvas.renderAll();
      requestAnimationFrame(animate);
    };

    animate();
  }, [canvas]);

  return null;
};

export default AnimatedCross;
ShaMan123 commented 1 year ago

@thisisdice I have removed your comment since it is spamming, proof is you couldn't see my previous comment

moved to native classes => no more createClass

Originally posted by @ShaMan123 in https://github.com/fabricjs/fabric.js/issues/8299#issuecomment-1427028792

@asturur please update the desc to include classes and prototype changes (props, ownDefaults, etc.)

ShaMan123 commented 1 year ago

@abdussami-tayyab open an issue, reproduce it properly. Bugs are to be fixed, not worked around.

ShaMan123 commented 1 year ago

ActiveSelection is a constant ref on canvas canvas.setActiveObject(new ActiveSelection()) will break selection #9066

enriqueerrando commented 1 year ago

Hi @ShaMan123 !!

How is the beta going? Is it close to the v6 release?

Thanks in advance!

ShaMan123 commented 1 year ago

V6 is doing good Unfortunately timelines are not available. Everyone, including the team, wants it out already. I encourage everyone to move to beta now as it requires work and a change of some points in mindset. Contributions are welcome always. Testing is becoming easier thanks to playwright so contributing might become easier as well hopefully.

chau-a-nguyen commented 1 year ago

Is playwright used for e2e testing and/or more? Is there a main page for V6 for status, getting started, API, installing, running locally for contributing, examples, best implemented editors, etc.?

ShaMan123 commented 1 year ago

Is playwright used for e2e testing and/or more?

hmmm. I don't know. We just introduced it. I have been experimenting the past few days. Have any suggestions?

Is there a main page for V6 for status, getting started, API, installing, running locally for contributing, examples, best implemented editors, etc.?

There is this ticket. The README.md and CONTRIBUTING.md are pretty much up to date, if not or if irrelevant please say so/PR.

Ping me if that is not enough, I'd be happy to lend a hand.

ShaMan123 commented 1 year ago

For the greater community:

We want to wrap up the TS migration and we need help.

Contributions are needed!

Current task is to type the remaining files and address TS errors. Contributors can search for files with @ts-nocheck and get to work. Open a draft PR with the title chore(TS): [SCOPE] once you get started stating which files you wish to address so people don't work on the same thing. Then when you are done, move it out of the draft state and review it and then one of us will review as well. Be sure to check for open PRs before you start working. If someone wishes to do it all go ahead.

Thanks!

chau-a-nguyen commented 1 year ago

Is playwright used for e2e testing and/or more?

hmmm. I don't know. We just introduced it. I have been experimenting the past few days. Have any suggestions?

Typically used for e2e testing, could be used to automate other things in the browser. Would suggest to use shared/reusable page objects. https://playwright.dev/docs/pom

hsbtr commented 1 year ago

Initialization threw an error

trying to initialize a canvas that has already been initialized at CanvasDOMManager.createLowerCanvas
hsbtr commented 1 year ago

Initialization threw an error

trying to initialize a canvas that has already been initialized at CanvasDOMManager.createLowerCanvas

The problem was finally found to be caused by executing react useEffect twice

hsbtr commented 1 year ago

It is recommended to export the options types of Rect Circle Line and other classes in fabric.ts, because importing the declaration files of these classes alone will trigger eslinet prettier warnings

image

At the same time, the options of canvas lack the type declaration

image

ShaMan123 commented 1 year ago

@hsbtr You should open an issue for this. Object options are now exported Exporting canvas options is a todo

hanna-becker commented 1 year ago

When using canvas.loadFromJSON how can we handle images with outdated src properties returning 404s? I tried using the method's reviver arguments to handle this gracefully, but it looks like the callback is running when it's already too late.

ShaMan123 commented 1 year ago

Please do not abuse this ticket, we do not want to lock it. Use the appropriate channels (issues, discussions etc.)

jiayihu commented 1 year ago
sukbearai commented 1 year ago

什么时候能实现?

jamesshaw1987 commented 1 year ago

A few notes from my migration from v5 to v6:

jiayihu commented 1 year ago

什么时候能实现?

他们正在修复最后的错误,几周后应该就可以了

zhengguorong commented 1 year ago

I use 6.x in my project and everything looks good, but EraserBrush can not be use. finially, I rollback to 5.x version 😭

ShaMan123 commented 1 year ago

@zhengguorong subscribe to #8499

mindmind commented 1 year ago

Hey, do you have plans to implement kinda cornerBorderScaleFactor for changing the width of control borders? If yes, then I can try to contribute. My team really need it.

tasnim-reza commented 1 year ago

Trying to use "fabric": "v6.0.0-beta13" with Angular 15, getting the following error, do you know what is wrong?

image

jiayihu commented 1 year ago

Trying to use "fabric": "v6.0.0-beta13" with Angular 15, getting the following error, do you know what is wrong?

I'd recommend using skipLibCheck in the tsconfig.json to avoid TS type checking the libs, including fabric. For the toObject issue you can see https://github.com/fabricjs/fabric.js/pull/9014

asturur commented 1 year ago

Hey, do you have plans to implement kinda cornerBorderScaleFactor for changing the width of control borders? If yes, then I can try to contribute. My team really need it.

Open a discussion or a feature request with a screenshot of what you would like to get. Some of the answers could include that you can simply make your control render function with zero issues.

chrisp018 commented 1 year ago

FYI. There is a break when upgrade the nextjs version from 13.4.19 to 13.5.1 for case using useEffect. My solution for now is revert next to previous version. Please refer to the screenshot for error message: image

export default function Studio() {
  useEffect(() => {
    const canvas = new fabric.Canvas("canvas", {
      height: 500,
      width: 800,
      backgroundColor: "#ededed",
    })
  }, [])

  return (
    <div>
      <canvas id="canvas" className="h-[500px] w-[800px]" />
    </div>
  )
}

package.json

{
  ...
  "dependencies": {
    ...
    "fabric": "^6.0.0-beta13",
    "next": "13.5.1",
    ...
  },
}