javascriptreactjshtml5-canvasfabricjs

FabricJS Add Image classList Error - Unable to add an image


I am creating a canvas based tool using FabricJS within a React App. I am using the latest NPM Package 6.4.3 and I am struggling to add an image to the canvas. Very recently they have switched to TypeScript and what used to be 'fabric.image.fromUrl' to add an image to the canvas has changes to 'FabricImage'. When I try to implement this I get an error stating 'TypeError: Cannot read properties of null (reading 'classList') at Qo.setElement'. I have implemented the other new method 'FabricText' in exactly the same way and it works totally fine.

This is the full error stack taken from my codePen example that is linked below. Image.ts is part of the FabricJS repo (src/shapes/Image.ts):

Uncaught TypeError: Cannot read properties of null (reading 'classList')
    at n.setElement (Image.ts:236:13)
    at new n (Image.ts:205:10)
    at pen.js?key=pen.js-5015e621-c65c-5079-a72d-17f3c0ea1cfa:35:23
    at Mb (react-dom.production.min.js:111:280)
    at Yh (react-dom.production.min.js:121:327)
    at R (react.production.min.js:11:265)
    at va (react.production.min.js:12:403)
    at react.production.min.js:25:14

and this is the stacktrace from my dev environment, as you can see the codepen stacktrace gives more information but the error is the same:

TypeError: Cannot read properties of null (reading 'classList')
    at Qo.setElement (http://localhost:3000/static/js/bundle.js:160422:172)
    at new Qo (http://localhost:3000/static/js/bundle.js:160415:251)
    at http://localhost:3000/static/js/bundle.js:11400:23
    at commitHookEffectListMount (http://localhost:3000/static/js/bundle.js:82913:30)
    at commitPassiveMountOnFiber (http://localhost:3000/static/js/bundle.js:84406:17)
    at commitPassiveMountEffects_complete (http://localhost:3000/static/js/bundle.js:84378:13)
    at commitPassiveMountEffects_begin (http://localhost:3000/static/js/bundle.js:84368:11)
    at commitPassiveMountEffects (http://localhost:3000/static/js/bundle.js:84358:7)
    at flushPassiveEffectsImpl (http://localhost:3000/static/js/bundle.js:86243:7)
    at flushPassiveEffects (http://localhost:3000/static/js/bundle.js:86195:18)

Having looked in the FabricJS repo for information or to see if there were any existing issues but as this is a very recent change, there is no mentionof this issue. I have also raised an issue on the FabricJS Repo and I am waiting for a response. In the meantime, I wanted to aks the Stack Overflow collective to see if anyone has come across this or could point out my error.

The error occurs when it is trying to as a class to the element classlist?? I originally assumed that it could not access the image but having looked at the FabricJS code it has already created the element and complete a number of tasks on it so it must have the image object.

I have created a codepen in React using the 6.4.3 FabricJS NPM Package and you can see the exact error by right clicking and looking at the console output, you will see the error mentioned above.

https://codepen.io/hedlro/pen/poMNOZq?editors=0110

If you comment out the image add section (lines 35 to 44) you will see that it works and creates the canvas and places a rectangle and text on the canvas.

The text uses the similarly renamed method 'FabricText' which works.

Below is the new TypeScript method to add an image, or at least what I think the correct syntax is:

const backImg = new FabricImage(testImage, {
              left: 0,
              top: 0,
              height: 400,
              width: 500,
              selectable: false,
              hasControls: false,
              hasBorders: false
              })
canvas.add(backImg).setActiveObject(backImg);

Below is the new typescript method for adding text to the canvas which works. I have based the code for the image on the code below as they both have new methods.

const recttext = new FabricText('Printable Area', {
                  fontSize: 14,
                  fontFamily: 'sans-serif',
                  left: 253,
                  top: 80,
                  fill: 'rgba(0,0,0,0.3)',
                  selectable: false,
                  hasControls: false,
                  hasBorders: false
                  });
                  
canvas.add(recttext);

My question is ' Have I got the syntax wrong or am I missing something that I should be sending through. I have checked the tyoescript interfaces for the method but nothing is standing out as required. It may be me making a mistake but at the moment there is minimal documentation for the change so I have no way of checking if I have. Any help would be greatly appreciated.


Solution

  • Thanks DocAmx for your answer.

    I managed to fix my issue by using the following code. The key to my issue was creating a new image object and assigning the imported image as the source. This fixed the null reference error I was getting when Fabic was trying to read the image details:

    const testImgObj = new Image(500, 400)
    testImgObj.src = selectedMerch.images[0].images[0].name;
    const backImg = new FabricImage(testImgObj, {
        left: 0,
        top: 0,
        height: 500,
        width: 600,
        selectable: false,
        hasControls: false,
        hasBorders: false,
        cornerStrokeColor: "#ff0098"
    });
    canvas.add(backImg);
    canvas.setActiveObject(backImg);