Question

I want to fill a rect with a gradient of all the colors of a source group. I am sure there is a filter for this but I am not able to build one getting the job done.

<svg width="100" height="100">
    <defs>
        <filter id="f1">
          <feBlend in="SourceGraphic" in2="url(#line)"/>
        </filter>
    </defs>
    <g id="line">
        <line x1="10" y1="10" x2="20" y2="20" stroke="red"/>
        <line x1="20" y1="20" x2="30" y2="10" stroke="orange"/>
        <line x1="30" y1="10" x2="40" y2="20" stroke="green"/>
        <line x1="40" y1="20" x2="50" y2="10" stroke="blue"/>
    </g>
    <g id="rect" filter="url(#f1)">
        <rect x="10" y="30" width="40" height="40" stroke="black" stroke-width="2"/>
    </g>
</svg>   

The goal is that my rect get filled from left to right with the colors of the source lines (red,orange,green and blue). Of corse the source colors are not allways the same :-) I have tried several versions of feBlend, feFlood and feColorMatrix without any luck.

Was it helpful?

Solution

You can't just reference an object within a filter, you have to import it with feImage first - doing this is not supported on Firefox and sizing is occasionally wonky on IE. You should also put your fill pattern into your defs. Here is a larger version that works on safari/chrome - adding feTile so you can see the effect a little more clearly:

<svg width="400px" height="400px">
    <defs>

    <g id="line">
        <line x1="10" y1="10" x2="20" y2="20" stroke="red"/>
        <line x1="20" y1="20" x2="30" y2="10" stroke="orange"/>
        <line x1="30" y1="10" x2="40" y2="20" stroke="green"/>
        <line x1="40" y1="20" x2="50" y2="10" stroke="blue"/>
    </g>
        <filter id="f1" x="0%" y="0%" height="100%" width="100%">
            <feImage xlink:href="#line" width="50" height="20" result="myPattern"/>
            <feTile in="myPattern" result="tilePattern"/>
            <feBlend mode="normal" in="tilePattern" in2="SourceGraphic"/>
        </filter>
    </defs>

    <g id="rect" filter="url(#f1)">
        <rect x="10" y="30" width="300" height="300" stroke="black" stroke-width="2"/>
    </g>
</svg> 

Now, if you actually want to convert these colors to gradients, you'll have to do that in JavaScript. There is, in theory, a way to do it in a filter by using fillPaint and strokePaint, but these are supported in IE and Firefox only. I'm also not entirely sure what effect you're trying to accomplish, posting an image of what you're trying to do would be helpful.

OTHER TIPS

It is not clear to me what exactly the effect is that you want to achieve. Is this the sort of effect you are after?

http://jsfiddle.net/t9Bfb/

<svg width="100%" height="100%" viewBox="0 0 60 60">
    <defs>
        <linearGradient id="f1">
          <stop offset="0.125" stop-color="red"/>
          <stop offset="0.275" stop-color="orange"/>
          <stop offset="0.625" stop-color="green"/>
          <stop offset="0.875" stop-color="blue"/>
        </linearGradient>
    </defs>
    <g id="rect" fill="url(#f1)">
        <rect x="10" y="30" width="40" height="40" stroke="black" stroke-width="2"/>
    </g>
    <g id="line">
        <line x1="10" y1="10" x2="20" y2="20" stroke="red"/>
        <line x1="20" y1="20" x2="30" y2="10" stroke="orange"/>
        <line x1="30" y1="10" x2="40" y2="20" stroke="green"/>
        <line x1="40" y1="20" x2="50" y2="10" stroke="blue"/>
    </g>
</svg>   
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top