Home > other >  color of svg not appearing in png version
color of svg not appearing in png version

Time:09-16

so I have a style in the svg image and I am using that to change the fill using javascript with a random colors function and that works fine. but when I need the svg to be in png format after the color is changed, the changed colors colors are not retained for the PNG but the original colors are kept instead

<style type="text/css">
:root{
    --back:#662D91;
    --shadow:0.28;
    --highlight:#F3B4AE;
    --stomach:#EA8A82;
    --lightHigh:#FEE9E5;
    --lasso:#9B5D12;
    --gloves:#29A6DE;--glovesStroke:#000674;--gloves2:#29A6DE;--gloves3:#1C7FC9;--gloves4:#1D7DC6;--gloves5:#1C7DC4;
    --hatBelow:#DB8556;
    --hatBelow2:#8A3C13;
    --hatInner:#8C4017;
    --hatInner2:#934A24;
    --hatInner3:#9D5C3A;
    --stripe:#8A7454;
    --stripeEnd:#382000;

}
    .st0{fill:var(--back);}
    .st1{opacity:var(--shadow);}
    .st2{fill:var(--highlight);}
    .st3{fill:var(--stomach);}
    .st4{fill:var(--lightHigh);}
    .st5{fill:var(--lasso);}
    .st6{filter:url(#Adobe_OpacityMaskFilter);}
    .st7{filter:url(#Adobe_OpacityMaskFilter_1_);}
    .st8{clip-path:url(#SVGID_3_);mask:url(#SVGID_4_);fill:url(#SVGID_5_);}
    .st9{opacity:0.7;clip-path:url(#SVGID_3_);fill:url(#SVGID_6_);}
    .st10{fill:url(#SVGID_10_);}
    .st11{fill:#FFD2B3;}
    .st12{fill:#EEBD9C;}
    .st13{fill:#FFE3CE;}
    .st14{fill:#AF7B6E;}
    .st15{fill:var(--gloves);stroke:var(--glovesStroke);stroke-miterlimit:10;}
    .st16{fill:var(--gloves2);}
    .st17{fill:var(--gloves3);}
    .st18{fill:var(--gloves4);}
    .st19{fill:var(--gloves5);}
</style>

this is the style element in my svg and I am changing it using this

  root.style.setProperty('--back',colors[0]);

the colors is an array of colors that I get my randomly making a color using a script in the svg help plz so this is how i am converting svg to png

<script>
var svgString = new XMLSerializer().serializeToString(document.querySelector('svg'));
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var DOMURL = self.URL||self.webkitURL||self;
var img = new Image();
var svg = new Blob([svgString],{type: "image/svg xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);
img.onload = function(){
ctx.drawImage(img,0,0);
var png = canvas.toDataURL("image/png");
document.querySelector('#png-container').innerHTML = '<img src="' png '"/>';
DOMURL.revokeObjectURL(png);
};
img.src = url;
</script>

CodePudding user response:

Edit: Took a minute to thing about it, and it makes sense that it doesn't work. svg blob only includes svg tag contents and hence has no idea there's a CSS variable set on html tag outside of it. Styles applied with :root are defined within SVG, so when you yank it out of HTML context, I assume :root points to the svg tag itself.

Not sure why it works this way, but when using canvas CSS variables set on ancestors of svg tag seem to be ignored. What you can do to fix this is set inline styles on either svg tag itself or its children.

Here's a reproduction with a fix, don't mind changes to the JS code, it does the exact same thing yours does just but sets CSS variable on svg tag instead of html.

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>SVG thingy</title>
  </head>
  <body>
    <svg
      viewBox="0 0 10 10"
      xmlns="http://www.w3.org/2000/svg"
    >
      <style>
        :root {
          --color: red;
        }

        circle {
          fill: var(--color);
        }
      </style>

      <circle
        cx="5"
        cy="5"
        r="4"
      />
    </svg>

    <canvas></canvas>

    <div id="png-container"></div>

    <script>
      const root = document.documentElement; // html tag
      // root.style.setProperty('--color', 'black'); // Doesn't work

      const svgElement = document.querySelector('svg');
      svgElement.style.setProperty('--color', 'black'); // Works
      
      const svgString = new XMLSerializer().serializeToString(document.querySelector('svg'));
      const svgBlob = new Blob([svgElement.outerHTML], { type: 'image/svg xml;charset=utf-8' });
      const url = URL.createObjectURL(svgBlob);
      
      const canvasElement = document.querySelector('canvas');
      const ctx = canvasElement.getContext('2d');
      
      const img = new Image();
      img.src = url;
      img.onload = () => {
        ctx.drawImage(img, 0, 0);
        const png = canvasElement.toDataURL('image/png');
        document.querySelector('#png-container').innerHTML = '<img src="'   png   '"/>';
        URL.revokeObjectURL(png);
      };
    </script>
  </body>
</html>
  • Related