Closed hqw567 closed 2 months ago
import * as fabric from 'fabric'
import { useEffect, useRef } from 'react'
import dataJson from './data.json'
const App = () => {
const canvasRef = useRef()
useEffect(() => {
if (!canvasRef.current) return
const canvas = new fabric.Canvas(canvasRef.current)
dataJson.objects.forEach((item) => {
// issues 1: When I have a custom attribute with "type" in it, I get an error `Error: fabric: No class registered for any`
//
// Comment the following code to see the error
delete item.myData.type
})
// issues 2: When using it in react, there will still be an error message `TypeError: Cannot read properties of undefined (reading 'clearRect')`
canvas.loadFromJSON(dataJson).then(() => {
canvas.requestRenderAll()
})
return () => {
canvas.dispose()
}
}, [])
return (
<canvas
width={document.body.clientWidth}
height={document.body.clientHeight}
ref={canvasRef}
/>
)
}
export default App
https://github.com/fabricjs/fabric.js/blob/8219e923770a3105eddb3c96dd945368582d07a1/src/util/misc/objectEnlive.ts#L158-L166 bug1: The issue here is that during import, it loops through each property and checks if it is an object. If it is, it then checks for a type. Hmm... I think the source code should add an error check.
bug2: The issue is with asynchronous operations. You can solve it by making the following modifications.
const controller = new AbortController();
canvas.loadFromJSON(dataJson, undefined, { signal: controller.signal }).then(() => {
canvas.requestRenderAll()
}).catch(e => {
console.error(e.message ?? "aborted");
});
return () => {
controller.abort();
canvas.dispose()
}
// let flag = false;
// canvas.loadFromJSON(dataJson).then(() => {
// if (flag) return false;
// canvas.requestRenderAll();
// })
// return () => {
// flag = true;
// canvas.dispose()
// }
@zhe-he Thanks for the reply, but issues 1 is still not solved in the latest version.
myData.type
When I have a custom attribute with "type" in it, I get an error Error: fabric: No class registered for any
@zhe-he View online
@hqw567 The second-to-last commit's code is good, but the last commit's code was reverted, and the main branch merged the reverted code. So I am also quite confused.
let me see maybe i misunderstood how i used the class registry
Yes sorry i should have added 'hasClass' rather than getClass. I ll fix it quickly
@asturur I have upgraded to v6.2.0, The problem is still not solved. There is a new error reported when my custom attribute "myData": { "type": "text" }
Uncaught TypeError: Cannot read properties of undefined (reading 'split')
at _Io._splitTextIntoLines (fabric.js?v=32e06e8c:5297:19)
at _Io._splitText (fabric.js?v=32e06e8c:5007:21)
at _Io.initDimensions (fabric.js?v=32e06e8c:5011:10)
at new _Io (fabric.js?v=32e06e8c:5000:216)
at fabric.js?v=32e06e8c:2155:16
at async Promise.all (/index 0)
at async Promise.all (/index 49)
at async Promise.all (/index 0)
at async Promise.all (/index 0)
{
"version": "6.0.2",
"objects": [
{
"fontSize": 50,
"fontWeight": "normal",
"fontFamily": "Times New Roman",
"fontStyle": "normal",
"lineHeight": 1.16,
"text": "fabric issues",
"charSpacing": 0,
"textAlign": "left",
"styles": [],
"pathStartOffset": 0,
"pathSide": "left",
"pathAlign": "baseline",
"underline": false,
"overline": false,
"linethrough": false,
"textBackgroundColor": "",
"direction": "ltr",
"minWidth": 20,
"splitByGrapheme": false,
"type": "Textbox",
"version": "6.0.2",
"originX": "left",
"originY": "top",
"left": 50,
"top": 50,
"width": 119.458,
"height": 122.04,
"fill": "black",
"stroke": null,
"strokeWidth": 1,
"strokeDashArray": null,
"strokeLineCap": "butt",
"strokeDashOffset": 0,
"strokeLineJoin": "miter",
"strokeUniform": false,
"strokeMiterLimit": 4,
"scaleX": 1,
"scaleY": 1,
"angle": 0,
"flipX": false,
"flipY": false,
"opacity": 1,
"shadow": null,
"visible": true,
"backgroundColor": "lightgrey",
"fillRule": "nonzero",
"paintFirst": "fill",
"globalCompositeOperation": "source-over",
"skewX": 0,
"skewY": 0,
"myData": {
"type": "text"
}
}
]
}
Well... the new logic now allows custom types to build internal objects. If your type value is 'rect' or 'text', it will be parsed as 'Rect' and 'Text'. So your type values should avoid these.
Or at least they have to serialize differently. I m not sure how you handle unwanted mutations when you restore properties that are custom objects.
Can this problem be solved once and for all? @asturur
The current version supports it. Just don't use 'type' with values that are already used by fabricJS classes ( 'rect', 'text', 'image' and so on ). Or if you really have to do that change the type in the normal fabricJS classes and register them with a different name.
CheckList
Version
6.0.2
In What environments are you experiencing the problem?
Chrome
Node Version (if applicable)
None
Link To Reproduction
https://github.com/hqw567/fabric-issues-react
Steps To Reproduce
Expected Behavior
Custom attributes contain any attributes without error
Actual Behavior
When I have a custom attribute with "type" in it, I get an error
Error: fabric: No class registered for any
Error Message & Stack Trace
No response