software-mansion / react-native-svg

SVG library for React Native, React Native Web, and plain React web projects.
MIT License
7.42k stars 1.12k forks source link

Android SVGs filled with black #668

Closed seanadkinson closed 5 years ago

seanadkinson commented 6 years ago

Hi there,

We just upgraded to RN 0.55.3, React 16.3.1, and RNSVG 6.3.1, and many of our SVGs are filled with black unexpectedly. This affects Android only.

For example, here is our HeartFilled component:

export default function HeartFilled({ height, width }: SvgProps) {
    return (
        <Svg height={height} width={width} viewBox="0 0 22 22">
            <Defs>
                <LinearGradient x1="-7.82094617%" y1="-9.7528458%" x2="128.388643%" y2="149.135801%" id="linearGradient-1">
                    <Stop stopColor="#E9350D" offset="0%"></Stop>
                    <Stop stopColor="#FE7B01" offset="86.0453351%"></Stop>
                    <Stop stopColor="#FF7F00" offset="91.3119513%"></Stop>
                    <Stop stopColor="#FF7F00" offset="100%"></Stop>
                </LinearGradient>
                <LinearGradient x1="-8.90729167%" y1="-16.3514254%" x2="160.036429%" y2="144.955742%" id="linearGradient-2">
                    <Stop stopColor="#E9350D" offset="0%"></Stop>
                    <Stop stopColor="#FF7F00" offset="91.3119513%"></Stop>
                    <Stop stopColor="#FF7F00" offset="100%"></Stop>
                </LinearGradient>
                <Path
                    d="M11.4074577,6.65193908 C11.3134123,6.8083037 11.1729108,6.89441754 11.01428,6.89441754 C10.8545161,6.89441754 10.7151477,6.8083037 10.6358323,6.67913293 C9.46536388,4.64525992 6.99525627,3.83624302 4.90472941,4.85147991 C2.68389871,5.92903603 1.73098104,8.65975133 2.77794409,10.9496997 C3.60395714,12.7558243 8.25297161,17.2235464 10.1780692,19.0285379 C10.3990192,19.2347579 10.6913531,19.3627956 11.01428,19.3627956 C11.3338077,19.3627956 11.6261415,19.2370241 11.8470915,19.0319372 C13.769923,17.2303449 18.4246028,12.7580904 19.251749,10.9496997 C20.298712,8.65975133 19.3469274,5.92903603 17.1238306,4.85147991 C15.0333037,3.83624302 12.5631961,4.64639299 11.4074577,6.65193908 Z"
                    id="path-3"></Path>
            </Defs>
            <G strokeWidth="1" fill="none" fillRule="evenodd">
                <G>
                    <G>
                        <Use fill="url(#linearGradient-1)" fill-rule="evenodd" href="#path-3"></Use>
                        <Path stroke="url(#linearGradient-2)" strokeWidth="2"
                              d="M11.0136254,5.458466 C12.5671321,3.51085788 15.2624723,2.83585096 17.5600028,3.9516167 C20.2756556,5.26791935 21.4326007,8.58466568 20.1611372,11.365648 C19.4144098,12.9982191 16.3994744,16.1369474 12.5273984,19.7648645 C12.1175789,20.1452611 11.5815696,20.3627956 11.01428,20.3627956 C10.4432567,20.3627956 9.90642442,20.1428884 9.49408527,19.758035 C5.61673614,16.1225923 2.61425407,12.9961597 1.86848906,11.365502 C0.597441995,8.58543046 1.75444639,5.26851425 4.4678818,3.95194438 C6.76989487,2.83400199 9.46224826,3.51315175 11.0136254,5.458466 Z"></Path>
                    </G>
                </G>
            </G>
        </Svg>
    );
}

To fix the issue, I just needed to remove the empty <G> elements towards the bottom:


export default function HeartFilled({ height, width }: SvgProps) {
    return (
        <Svg height={height} width={width} viewBox="0 0 22 22">
            <Defs>
                <LinearGradient x1="-7.82094617%" y1="-9.7528458%" x2="128.388643%" y2="149.135801%" id="linearGradient-1">
                    <Stop stopColor="#E9350D" offset="0%"></Stop>
                    <Stop stopColor="#FE7B01" offset="86.0453351%"></Stop>
                    <Stop stopColor="#FF7F00" offset="91.3119513%"></Stop>
                    <Stop stopColor="#FF7F00" offset="100%"></Stop>
                </LinearGradient>
                <LinearGradient x1="-8.90729167%" y1="-16.3514254%" x2="160.036429%" y2="144.955742%" id="linearGradient-2">
                    <Stop stopColor="#E9350D" offset="0%"></Stop>
                    <Stop stopColor="#FF7F00" offset="91.3119513%"></Stop>
                    <Stop stopColor="#FF7F00" offset="100%"></Stop>
                </LinearGradient>
                <Path
                    d="M11.4074577,6.65193908 C11.3134123,6.8083037 11.1729108,6.89441754 11.01428,6.89441754 C10.8545161,6.89441754 10.7151477,6.8083037 10.6358323,6.67913293 C9.46536388,4.64525992 6.99525627,3.83624302 4.90472941,4.85147991 C2.68389871,5.92903603 1.73098104,8.65975133 2.77794409,10.9496997 C3.60395714,12.7558243 8.25297161,17.2235464 10.1780692,19.0285379 C10.3990192,19.2347579 10.6913531,19.3627956 11.01428,19.3627956 C11.3338077,19.3627956 11.6261415,19.2370241 11.8470915,19.0319372 C13.769923,17.2303449 18.4246028,12.7580904 19.251749,10.9496997 C20.298712,8.65975133 19.3469274,5.92903603 17.1238306,4.85147991 C15.0333037,3.83624302 12.5631961,4.64639299 11.4074577,6.65193908 Z"
                    id="path-3"></Path>
            </Defs>
            <G strokeWidth="1" fill="none" fillRule="evenodd">
                <G fill="none" fillRule="evenodd">
                    <Use fill="url(#linearGradient-1)" fill-rule="evenodd" href="#path-3"></Use>
                    <Path stroke="url(#linearGradient-2)" strokeWidth="2"
                          d="M11.0136254,5.458466 C12.5671321,3.51085788 15.2624723,2.83585096 17.5600028,3.9516167 C20.2756556,5.26791935 21.4326007,8.58466568 20.1611372,11.365648 C19.4144098,12.9982191 16.3994744,16.1369474 12.5273984,19.7648645 C12.1175789,20.1452611 11.5815696,20.3627956 11.01428,20.3627956 C10.4432567,20.3627956 9.90642442,20.1428884 9.49408527,19.758035 C5.61673614,16.1225923 2.61425407,12.9961597 1.86848906,11.365502 C0.597441995,8.58543046 1.75444639,5.26851425 4.4678818,3.95194438 C6.76989487,2.83400199 9.46224826,3.51315175 11.0136254,5.458466 Z"></Path>
                </G>
            </G>
        </Svg>
    );
}

Is it expected that empty <G> nodes would fill background with black on Android, but not on IOS? On IOS, the elements are effectively fill="none".

The SVGs did not have a black background before upgrading. Previously, we were using RN 0.51.0, React 16.0.0, and RNSVG 5.5.1.

This is a simpler example, but I have many other SVGs that aren't as straightforward to fix. For example, it appears I have to specify fill="none" on any Circle nodes, or else they will have a black background on Android. Curious if this is a bug, or expected behavior.

Thanks!

reeli commented 6 years ago

some issue here

Amar-HBCC commented 6 years ago

This issue comes when there are nested G tags... I flattened the svg by removing extra nesting and it started working fine.

steven-luu commented 6 years ago

I encountered the same issue. Thanks for sharing your workarounds.

I ended up modifying our Svg such that the resulting , or , nodes have an explicit fill="none" applied.

As a data point, I had upgraded from 5.1.8 > 6.1.4.

msand commented 6 years ago

This is certainly a bug, I'm not currently working on any react-native project and won't have any time to investigate now, please feel free to look into it. Perhaps a git bisect on the commit history to identify the commit that causes it, and I (or someone else) might be able to fix it relatively quickly.

xinyer commented 6 years ago

@msand This issue also effected my project. Would you take some time to fix it?

pilot4u commented 6 years ago

I have this issue as well.

Ragnar-H commented 6 years ago

@msand I did some digging on this issue and it seems to be v0.54.0 of react-native that's causing this issue. Specifically it's https://github.com/facebook/react-native/commit/5649aed6d3223ec49c42416f242249eb0c4fd890

I found this by running react-native-svg-example (which uses react-native-svg@6.0.0-rc12), adding the HeartFilled component from @seanadkinson, and upgrading to v0.54.0.

To narrow in on the commit, replace react-native in your node_modules and build react-native from source, then use git bisect to find the offending commit.

I can't see why that commit would have this effect...any theories?

shakedOno commented 6 years ago

I found that if I have more than one component, on iOS it's enough to specify fill on the top most , but Android requires the inner most to specify its fill property.

So the following change fixed it for me:

<G fill='white'>
  <G>

To:

<G>
  <G fill='white>
msand commented 6 years ago

The ReadableArray was reporting size 0 for non-empty arrays, I re-wrote it using ArrayList instead, can you try the latest version and see if it's fixed?

Ragnar-H commented 6 years ago

@msand works. Good job :)

robvolk commented 5 years ago

I still have this issue with React Native v0.55.4 @msand. I have nested <G> elements, each of them specifies a clipPath that references a ClipPath in Defs. Each ClipPath sets fill explicitly.

Here is a truncated version of my SVG:

    <Svg height={height} id="Layer_1" width={height} viewBox="0 0 80 80" data-name="Layer 1">
      <Defs>
        <ClipPath id="clip-path">
          <Rect x="2.91" y="12.42" width="74.18" height="55.16" fill="none" />
        </ClipPath>
        <ClipPath id="clip-path-2">
          <Rect x="-49.4" y="-138.79" width="178.32" height="386.12" fill="none" />
        </ClipPath>
        <ClipPath id="clip-path-4">
          <Path
            d="....."
            fill="none"
            fillRule="evenodd"
          />
        </ClipPath>
      </Defs>
      <G clipPath="url(#clip-path)">
        <G clipPath="url(#clip-path-2)">
          <G clipPath="url(#clip-path)">
            <G clipPath="url(#clip-path-4)">
              <G clipPath="url(#clip-path)">
                <Rect height="59.92" fill="#fff" width="78.94" x="0.53" y="10.04" />
              </G>
            </G>
          </G>
        </G>
      </G>
    </Svg>

It renders fine on iOS, but not on Android. Any ideas? Thanks in advance!

msand commented 5 years ago

Please provide a complete replication, it's not possible to debug the code you posted.

robvolk commented 5 years ago

It's for a client, so I emailed it to you. Thanks!

msand commented 5 years ago

It seems the issue was related to using v6 of rnsvg in Expo, issue non-existent in v7. But could be worked around by simplifying the svg content to a single Path element (and setting a fill on that), removing all G, Rect, and ClipPath elements. Making it perform better (memory, cpu and gpu) and work universally.

msand commented 5 years ago

Closing this as the issue is fixed.

cmosboss commented 5 years ago

I found that if I have more than one component, on iOS it's enough to specify fill on the top most , but Android requires the inner most to specify its fill property.

This is 100% the issue a lot of the time. Android needs each element to have inline styles and this will work just fine on any version I have tested. Meaning that I got all my SVGs to work by simply editing them and nothing to do with this plugin.

CeamKrier commented 4 years ago

It seems the issue was related to using v6 of rnsvg in Expo, issue non-existent in v7. But could be worked around by simplifying the svg content to a single Path element (and setting a fill on that), removing all G, Rect, and ClipPath elements. Making it perform better (memory, cpu and gpu) and work universally.

I tried to render the path element as you suggested but still getting it filled with black.

<Svg
  style={{
    width: 300,
    height: Dimensions.get('window').height,
    justifyContent: 'center',
    alignSelf: 'center'
  }}
  viewBox="0 0 818 1192">
  <Path
    d="M64.6851 0.328928L65.3343 0.227903C70.2426 -0.481436 73.5798 0.335303 76.7711 4.52993C78.2921 6.52893 77.8231 9.54793 76.7711 11.5909C74.2481 16.4921 68.445 17.0017 63.0464 17.4758C61.1741 17.6402 59.3504 17.8003 57.7291 18.1379C51.5821 19.4169 45.4501 21.1579 39.6981 23.6919C33.8291 26.2779 28.3201 29.3369 22.9481 32.8299C18.0891 35.9909 13.6821 40.7419 8.13109 42.5809C7.88109 42.6639 7.58009 42.4399 7.59576 42.1749C7.99109 35.8619 13.2641 30.0669 17.3481 25.5709C22.0721 20.3719 27.8171 15.7559 33.8001 12.0859C39.9741 8.29993 46.6481 5.18293 53.5581 3.00893C57.1971 1.86393 60.9201 0.953928 64.6851 0.328928ZM170.069 4.01173C161.004 1.59673 145.641 -0.136272 139.461 8.90073C139.244 9.21773 139.459 9.71373 139.825 9.79573C149.132 11.8917 158.055 13.8077 166.861 17.7407C174.372 21.0969 180.475 25.6524 186.638 30.686L188.009 31.8121L190.151 33.5887C198.179 40.2677 208.86 29.9557 201.721 22.0187C193.751 13.1587 181.435 7.03773 170.069 4.01173ZM94.9638 47.2562C83.9368 39.2272 70.1108 35.2152 56.5218 35.3312C53.6798 35.3562 50.9168 35.5612 48.2258 35.9382C30.3678 34.0672 12.4588 49.6552 5.38279 65.6392C-3.78121 86.3422 -3.01521 118.73 21.7288 127.705C26.927 129.59 32.4683 130.427 37.9527 131.134L41.9353 131.637C49.3585 132.546 56.8901 133.208 64.3668 133.141C78.7508 133.014 90.1908 127.501 98.9448 116.067C106.744 105.882 113.776 92.9482 113.786 79.7932C113.796 66.2822 105.514 54.9392 94.9638 47.2562ZM212.162 100.318C208.623 111.012 200.906 119.247 190.156 122.867C179.502 126.456 167.653 125.148 156.762 123.208C154.38 122.783 151.965 122.315 149.555 121.768C151.527 122.99 153.27 124.71 154.937 126.528C157.403 129.217 159.639 132.05 160.317 135.416C160.99 138.755 159.93 141.295 157.996 143.213C155.021 146.162 150.222 147.751 146.158 148.629C137.056 150.596 127.939 150.29 118.882 148.273C116.57 147.759 115.001 146.519 114.121 144.901C113.052 142.937 112.964 140.494 113.578 138.268C114.191 136.044 115.516 133.994 117.439 132.859C119.022 131.925 121.002 131.669 123.249 132.416C127.759 133.917 132.237 134.911 137.001 135.026C139.017 135.073 141.047 135.013 143.061 134.828C144.199 134.724 145.335 134.579 146.465 134.398C145.799 133.512 145.153 132.609 144.522 131.698C143.775 130.621 143.049 129.529 142.355 128.419C140.349 125.206 138.678 121.904 137.21 118.418C136.739 117.301 136.303 116.179 135.884 115.054C135.823 114.892 135.763 114.729 135.703 114.567C135.574 114.458 135.445 114.349 135.318 114.239C132.447 111.755 130.04 108.695 128.337 104.905C123.727 94.6395 124.478 81.8966 127.275 71.2371C129.517 62.6929 134.465 54.7901 141.002 49.4212C142.143 47.5432 142.897 46.404 143.82 45.4446C147.577 41.5358 152.82 38.8996 157.936 37.296C169.362 33.7129 181.807 36.2836 191.493 43.1058C200.436 49.4048 207.437 58.8518 211.221 69.3589C214.804 79.3093 215.503 90.2234 212.162 100.318ZM79.4728 50.5622C62.4558 42.9242 41.7798 45.2112 25.2728 53.3622C18.7338 60.4962 13.9548 69.4872 12.0208 77.7412C9.95579 86.5522 10.2578 96.0432 13.3628 104.583C17.1538 115.008 26.4888 117.59 36.5588 119.192L40.4684 119.806L42.1086 120.055C52.0033 121.531 62.8209 122.679 72.3298 120.831C82.9272 118.77 89.6574 110.209 94.9545 101.432L95.2018 101.02C100.703 91.8232 105.308 80.6382 100.694 70.1002C96.7708 61.1432 88.2018 54.4802 79.4728 50.5622ZM161.106 51.5656C167.412 49.3996 174.073 49.9876 179.913 53.2236C192.592 60.2486 199.794 75.7386 198.323 89.9676C197.701 95.9906 195.301 102.091 190.213 105.685C184.371 109.811 176.733 109.976 169.763 109.492L168.408 109.389L163.311 108.964C156.698 108.384 149.291 107.384 144.398 103.218C139.035 98.6491 137.846 90.3099 137.72 83.4933L137.71 82.7138L137.708 81.9496C137.724 76.1826 138.535 70.3246 140.5 64.9076C142.186 65.1176 144.037 64.4856 145.095 62.9056L145.366 62.5171C147.463 59.6191 150.074 58.5323 152.869 56.3866L153.776 55.7006C156.049 54.0076 158.393 52.4974 161.106 51.5656ZM52.795 54.5381C62.166 49.7541 73.423 50.9531 81.361 56.9491C80.656 57.0871 79.962 57.2631 79.27 57.6101C77.469 58.5131 76.351 60.3211 75.925 62.2451C75.445 64.4201 76.572 66.4791 78.719 67.1651C80.587 67.7611 82.802 68.0341 84.537 66.8991C85.446 66.3051 86.081 65.5221 86.498 64.5361L86.557 64.3911L86.6303 64.2847L86.6581 64.2349C86.6645 64.216 86.6317 64.252 86.58 64.3331C86.633 64.2101 86.682 64.0871 86.731 63.9621C86.804 63.8131 86.874 63.6631 86.931 63.5081C87.032 63.4211 87.124 63.3241 87.217 63.2271C88.659 65.4461 89.791 67.9521 90.51 70.7401C95.124 88.6351 76.204 107.206 59.301 109.064C52.913 109.766 47.088 108.245 42.254 105.247C42.298 105.188 42.347 105.135 42.387 105.073C44.329 105.422 46.647 104.553 47.352 102.387C49.151 96.8621 47.306 90.3991 41.286 88.5941C37.412 87.4321 33.448 88.7161 30.679 91.3641C28.585 86.2391 27.836 80.4691 28.827 74.6901C30.225 66.5371 35.143 59.1901 42.797 55.7981C46.524 54.1451 49.736 53.7981 52.795 54.5381ZM151.767 65.1295L151.482 65.5789C147.663 71.7409 146.72 79.1059 148.675 85.5869C148.683 85.7066 148.695 85.8259 148.708 85.9451L148.797 86.6589C151.32 86.0129 154.008 86.5199 155.814 88.7309C156.539 88.7329 157.255 88.8919 157.833 89.2289L158.028 89.3502C159.797 90.517 160.098 92.6435 159.353 94.5037L159.274 94.688L159.288 94.662C159.347 94.5497 159.125 95.1893 159.1 95.2589L158.955 95.638C158.856 95.8895 158.751 96.1386 158.643 96.3859C158.211 97.3689 157.626 98.1629 156.915 98.9679C156.645 99.2739 156.332 99.5049 155.997 99.6829C160.161 102.975 165.591 104.581 171.021 104.026C176.886 103.427 181.769 100.467 184.937 96.1059C185.268 95.8159 185.603 95.5319 185.918 95.2179C193.721 87.4219 194.64 73.3679 187.989 64.6219C187.584 64.0909 187.159 63.6229 186.721 63.2029C186.535 63.8789 186.198 64.5359 185.715 64.9839C184.827 65.8099 183.745 66.3509 182.516 66.3729C181.678 66.3899 180.823 66.1669 180.096 65.7429C179.036 65.1239 178.253 64.1009 177.704 63.0219C177.198 62.0259 177.054 61.0239 177.301 59.9399C177.309 59.9069 177.319 59.8751 177.331 59.8439L177.405 59.6569C174.695 57.9899 171.395 57.2739 168.243 57.7019C167.531 57.2609 166.741 56.9209 165.935 56.7099C160.198 55.2069 154.663 60.6733 151.767 65.1295ZM59.1248 152.988C58.8718 152.829 58.5398 152.897 58.3298 153.091C56.4748 154.804 56.4508 157.175 55.7878 159.532C54.8718 162.79 53.8158 166.052 52.6748 169.237C50.4508 175.45 47.8918 181.968 43.8078 187.222L43.6421 187.44C40.1686 192.126 40.6221 198.728 46.5918 201.243C51.6778 203.387 56.7898 200.384 58.2048 195.53L58.2658 195.638C60.8528 189.485 62.9938 183.084 63.7368 176.457C64.4278 176.821 65.1148 177.18 65.7738 177.534L66.8531 178.109C70.8192 180.202 74.8814 182.115 79.0788 183.694C89.0058 187.428 99.2578 190.003 109.725 191.68C119.407 193.23 129.169 194.127 138.969 193.31C148.557 192.51 159.889 190.647 168.195 185.48C177.871 179.458 169.445 165.735 159.391 170.418C155.375 172.288 151.936 174.423 147.618 175.711C143.965 176.8 140.207 177.616 136.427 178.105C127.624 179.242 118.54 178.995 109.712 178.319C100.616 177.622 91.5228 176.23 82.5968 174.349L79.9264 173.798C76.3634 173.076 72.7932 172.39 69.2428 171.605C67.5708 171.235 65.8028 170.705 64.0128 170.239C63.9638 164.925 63.4518 155.724 59.1248 152.988Z"
    transform="translate(36.00021 35.99987)"
    id="🖍-Ink"
    fill="#000000"
    fill-rule="evenodd"
    stroke="none"
  />
</Svg>

I supposed to get that image

But I get this image

Versions

Any suggestion?

marcosdourado commented 11 months ago

I know this is very old, but it may help anyone who is searching for a solution, since searching on Google this issue is the first one. I spent the whole day with the same problem @CeamKrier , and after analyzing the project's source code a lot I realized that I made a silly mistake, the correct one is fillRule and not fill-rule.

so:

...
<Path d="..." fillRule="evenodd"
...
ghost commented 4 months ago

I had same kind of issue when I upgraded react-native-svg too.

And it was written in the What Changed here

What I did was just add

...
<Path d="..." fill="currentColor">
...

as the react-native-svg/USAGE.md says it's the way to fill the original color.

Before After
Screen Shot 2024-05-05 at 16 08 40 Screen Shot 2024-05-05 at 16 08 47