Search code examples
svggradient

Can a two-dimensional gradient be created (or faked) in SVG?


I'm trying to create a color-picker which must dynamically generate its images and figured it would be a whole lot easier to generate SVG than a raster image. Unfortunately, I can't figure out how to represent the big, two-dimensional gradient which will form the centerpiece of the picker.

For example, if the currently selected axes are blue and green, I need to paint a square which has the lower-left corner black, the upper-left blue, the lower-right green, and the upper-right cyan.

If there's a way to accomplish this by overlaying two linearGradient-filled squares and playing with their opacity, I wasn't able to work it out. I also tried creating a gradient whose start end end colors were other gradients (hoping I was being clever), but all that got me was a "big black nothing". Google searches have thus far gotten me nowhere.

I'd hate to resort to a stack of 256 1-pixel high gradients, both because of the increase in size and complexity and because I suspect it wouldn't resize well. Perhaps someone with a bit more working knowledge of SVG can suggest something


Solution

  • This is possible using the mix-blend-mode style attribute:

    <svg xmlns="http://www.w3.org/2000/svg" width="256" height="256">
      <defs>
        <linearGradient id="black-to-green" gradientTransform="rotate(0)">
          <stop offset="0"  stop-color="#000000" />
          <stop offset="100%" stop-color="#00ff00" />
        </linearGradient>
        <linearGradient id="black-to-blue" gradientTransform="rotate(90)">
          <stop offset="0"  stop-color="#0000ff" />
          <stop offset="100%" stop-color="#000000" />
        </linearGradient>
      </defs>
      <rect x="0" y="0" width="256" height="256" fill="url('#black-to-green')" />
      <rect x="0" y="0" width="256" height="256" fill="url('#black-to-blue')" style="mix-blend-mode: screen" />
    </svg>

    Documentation: https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode