Philip Grabenhorst
Philip Grabenhorst

Reputation: 161

JavaScript Canvas SVG linear gradient rendering on Chrome

So the details of this question are a bit obtuse. Here is what my team is trying to do... We are using Figma to create SVGs. These SVGs are relatively simplistic, but we are using them to create animations in the body of our application. Our application is based around the HTML5 Canvas. Once an image file is loaded it is drawn on the Canvas using the CanvasRenderingContext2D.drawImage() method. Here's the kicker. Some SVGs just don't appear. Others do appear. Some might appear partially. Here is the issue that brings me to StackOverflow (though hopefully, I'll be able to provide an answer for it, shortly). Some SVGs use a linear-gradient generated by Figma, but those linear gradients don't render at all in the JS Canvas. What's worse is that this issue is only happening on Chrome! I tried the same process in Safari, and it does work.

So, here's the thing: has anyone encountered this browser-specific sort of SVG issue with linear gradients, and, if so, how did you fix it?

I suspect the answer lies in the format of the linearGradient tag. Here are two versions of the same file, one from Figma and one from Inkscape (the one from Inkscape works).

Figma

<defs>
<linearGradient id="paint0_linear_338:2881" x1="400" y1="0" x2="400" y2="800" gradientUnits="userSpaceOnUse">
<stop stop-color="#99CCFF" stop-opacity="0.6"/>
<stop offset="0.864583" stop-color="#87C3FF" stop-opacity="0.1"/>
</linearGradient>
<clipPath id="clip0_338:2881">
<rect width="800" height="800" fill="white"/>
</clipPath>
</defs>

Inkscape

<defs
     id="defs1024">
    <linearGradient
       inkscape:collect="always"
       id="MAINGRAD">
      <stop
         style="stop-color:#99ccff;stop-opacity:0.60000002"
         offset="0"
         id="stop2574" />
      <stop
         style="stop-color:#87c3ff;stop-opacity:0.1"
         offset="1"
         id="stop2576" />
    </linearGradient>
    <clipPath
       id="clip0_338:2881">
      <rect
         width="800"
         height="800"
         fill="white"
         id="rect1021" />
    </clipPath>
    <linearGradient
       inkscape:collect="always"
       xlink:href="#MAINGRAD"
       id="linearGradient3482"
       gradientUnits="userSpaceOnUse"
       x1="399.724"
       y1="2.1855699e-08"
       x2="399.724"
       y2="800" />
  </defs>

Upvotes: 1

Views: 339

Answers (1)

Philip Grabenhorst
Philip Grabenhorst

Reputation: 161

The issue turned out to be relatively simple. The Canvas in Chrome seems to be sensitive to IDs containing certain formats. I used the following tool to simplify the exported Figma file format.

pip install scour
scour -i input.svg -o output.svg --shorten-ids

Scour simply parses the file and replaces each unique ID with the shortest string possible. In this case, replacing paint0_linear_338:2881 with a. This was the only change required to fix the problem, and I suspect the issue was the colon. I wouldn't be surprised if updates in future Chrome versions fix this bug.

(Current Chrome Version: 94.0.4606.81 (Official Build) (arm64))

Upvotes: 1

Related Questions