Fabric.js: SVG Image cropped with fabric.Image.fromURL

Created on 31 Jan 2019  路  35Comments  路  Source: fabricjs/fabric.js

Version

2.4.6

Test Case

https://jsfiddle.net/kbcn4mpd/

Information about environment

Tested on Chrome 71.

Steps to reproduce

See fiddle.
I try to add an image to the canvas, using fabric.Image.fromURL() or new fabric.Image(). This image is a SVG file but I don't want to be able to manipulate objects inside this SVG, I just need to manipulate this SVG as a whole image.

Expected Behavior

The canvas should show the entire image (french flag).

Actual Behavior

The image appears, but is cropped: we can only see the upper left corner. I you remove the canvas' height attribute, then it appears correctly but then I am not able to correctly size the canvas.

bug clipPath svg_parser

Most helpful comment

In fact, this exact cropping issue is relevant starting from 2.4.0 which introduced the breaking change.
My solution was to downgrade to 2.3.6 in the meantime. It appears to affect a large group of SVGs. For example, almost every svg from here: https://github.com/twitter/twemoji

All 35 comments

In fact, this exact cropping issue is relevant starting from 2.4.0 which introduced the breaking change.
My solution was to downgrade to 2.3.6 in the meantime. It appears to affect a large group of SVGs. For example, almost every svg from here: https://github.com/twitter/twemoji

@RoeyMaor Thank you for the advise of downgrading to 2.3.6. I was having issues loading SVGs there were converted from .ai files. After downgrading I am no longer having issues and I can finally move on with my life!

@RoeyMaor in your opinion which is the commit from 2.3.6 to 2.4.0 that introduced the bug?

https://jsfiddle.net/6gbq7kfv/ with 2.3.6 behaves same to me.

@asturur This is weird, when I use versions bigger than 2.3.6 many SVGs are messed up like this:
capture
and when using 2.3.6 they are fine:
capture2
I am using the latest chrome. perhaps this is even not the same bug, I assumed it is.

I narrowed the possibilities for the culprit commit to one of the following:
https://github.com/fabricjs/fabric.js/commit/ffe01ab9f60c45fdf2f8418aa7ea6a84fdd52b8d
https://github.com/fabricjs/fabric.js/commit/513233bf7836a1863107e2fba92b24e5240c716a
https://github.com/fabricjs/fabric.js/commit/2a476e4277d7c531e7b050418168e1097a9e7dba

@RoeyMaor If you add width and height attributes to svg then there will be no cropped
https://jsfiddle.net/DenBogdanov/0Luqkm2g/

What behavior is expected without the SVG object size set?

@0ro Your example uses 2.3.6, so it is not a counter example, Iv'e said that since 2.4.0 the bug was introduced. If adding the width and height attributes to the svg tag itself is the solution as you said, then this in itself is another bug, as the proportions for correct display should be inferred from the viewbox in case the width and the height aren't specified in the svg tag itself. Many svgs do not use these attributes

The latest version in which the test case in issue runs correctly is 1.7.22
https://jsfiddle.net/DenBogdanov/qr67an39/
Since version 2.0.0, svg images are cropped
https://jsfiddle.net/DenBogdanov/qr67an39/1/

image

so this is a bug ^^^ and i think it can be fixed.

image

this way seems working, i wonder how to detect this beahviour by code. i have to apply to the clipPath the transformation of parent groups.

to solve this properly we need an overhauled parser.
Or we need to note down the partial transformation of an element when the clipPath is declared.
This is a note for me as soon as i have a couple of hours to dedicate to this fix.

Maybe is better to invest them in a new svg parser that maints groups

@asturur, If this is caused by not applying transformations to clipPath, then as I said the bug was introduced by one of these commits: (before them it did not exist, tested with the same svg as you showed here):
ffe01ab
513233b
2a476e4

Will there be a fix for this? (or a new svg parser?? 馃槈 )

It works fine in Fabric 2.7.0 using Safari on the Mac, but not in Chrome (if that is important)

Sourcefile is:

https://github.com/twitter/twemoji/blob/gh-pages/svg/1f171.svg

Here's what I get on Safari 12.0.1/Mac Fabric 2.7.0:
image

Same code on Chrome 73.0.3683.75/Mac Fabric 2.7.0
image

Please also note, that the second layer ('B') is not showing

If I let Fabric group the elements it looks like this:
image

svg parser is one of the funny things for me, and one of the things i would like to work on.
Didn't have much time march and april for a series of reasons.
Fabric is still actively developed used and improved, but time is few.

Sounds familiar 馃槉
Anyway - Fabric is a really cool thing (even if there are some things like the above). 鉂わ笍

Yeah consider that parsing an svg, with all the svg capabilities is a non trivial task. The more functionalities we enable from SVG the more weird combination arrives.
I'm very happy with the current state of svg parsing.

Me too! And - interestingly - the above results show fine in Safari, but wrong in Chrome; so it seems that (besides parsing svg) more things are involved

for me is broken in the latest safari too
image

Has there been any progress on this? Looks like its been about 8 months since this was reported and seems like a pretty major issue thats still going on

if i remember correctly this requires a full new svg parser logic.

Getting the same issue with version 2.4.6 when trying to load SVG using fabric.Image.fromURL

Is there any workaround?

Here is the fiddle
https://jsfiddle.net/satendra02nov/3p0uvsjr/6/

@satendra you can use fabric.loadsvgfromurl but that will give you a path object instead of an image. If you dont need it to be an image object, then this will at least load the full picture on canvas for you. Unfortunately all we can do right now.

I dont know why one parser works and the other doesnt, but would it be possible to use the loadsvgfromurl to get the path object and then convert it to an image after that? Or is that basically what image.fromurl is doing already? I havent looked at the parser code myself to see

image.fromUrl shoud draw the svg as an image, with no details loss on zoom and 0 compatibility issues.

The other creates a group of objects.

If you do not need to let someone else ungroup the group and manipulate every single path on the canvas, loading it as an image is a solution

i think this has been partially fixed.
Anyone has the SVG files that have been used in the screenshot in the thread?

yes this one is one of them. also the jester i need.

Sorry - I was off for a couple of days...
Here's the other one:
https://github.com/twitter/twemoji/blob/gh-pages/svg/1f0cf.svg

i think this problem has been solved in current master!

Still having issues with version latest version 3.5.1. The SVG below renders properly on 2.3.6 which is what I've been using for quite some time. The difference between the two photos are on the right side of the image.

Test SVG Logo
Rendered fabric on 2.3.6
Rendered fabric on 3.5.1

Not sure what is wrong because the images you provide are really small and i can't understand if something is rendered bad.

this is how latest fabric renders the object:
image

this is how the browser renders it:
image

The images looks very similar to me.

Hmm interesting - this is what I did even for a simple test and still came to same conclusion:

  1. Go to http://fabricjs.com/kitchensink.
  2. Click on "Clear Canvas"
  3. Go to "Load SVG"
  4. Copy & Paste entireSVG content
  5. Click on "Load as Group"

This is what I got as a result:
maui_fabric 3 5 0_site_kitchensink

the website could not include last commits

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bevacqua picture bevacqua  路  4Comments

zhangzhzh picture zhangzhzh  路  4Comments

amancqlsys picture amancqlsys  路  5Comments

guettli picture guettli  路  4Comments

raichu picture raichu  路  4Comments