fabricjs / fabric.js

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

[Bug]: svg not display correctly #9047

Open genie88 opened 1 year ago

genie88 commented 1 year ago

CheckList

Version

6.0.0-beta9

In What environments are you experiencing the problem?

Chrome

Node Version (if applicable)

None

Link To Reproduction

Vanilla template >= v6

Steps To Reproduce

visit https://codepen.io/genie88/pen/VwVPpdx , and svg not display correctly

Expected Behavior

svg display correctly

image

Actual Behavior

svg not display correctly

image

Error Message & Stack Trace

No response

herrstrietzel commented 1 year ago

I think part of the problem are invalid style properties like xand y (and mybe the really bloated style attributes). These are not applicable for <path> elements – the browsers svg rendering ignore these.
But fabric.js seems to interpret these properties while drawing the elements to canvas.

I could reproduce and fix this error by cleaning up SVG style properties.

See codepen example
and a more advanced helper example

Problems in input SVG file

The exporting application/app/API (used to generate the example file) has severe issues that should also be filed as bug reports/feature requests.
Apparently (almost) the whole range of css properties is applied to all elements and included in the SVG output file – resulting in a massive overhead but also in parsing and rendering (Also causing optimizers like SVG/O or vecta nano to either fail or crash).
The vast majority of these style properties are either not applicable for most SVG elements or doesn't have any effect on SVG rendered elements: e.g border or any style property applied to a <title> element.
The aforementioned overhead also results in an approximately 33x increase in file size.

Possible extra validation steps for fabric.js

Frankly, I don't think fabric.js should include too much sanitizing.
But it might add an extra check for crucial attributes related to positioning that are only applicable to certain elements like:

['svg', 'use', 'rect', 'image', 'text', 'tspan', 'textPath']

and omit/ignore any CSS x,y,width,height property values applied to other elements.