I have an SVG group that contains several shapes, and these shapes use a gradient defined with <g fill="url(#myGradient)"...
. I want to apply transformations (e.g., scaling, rotation, translation) to the group, but I need the gradient to remain fixed relative to the screen (viewport).
Currently, when I apply transformations to the group, the gradient gets affected as well, even though I used gradientUnits="userSpaceOnUse". How can I ensure the gradient stays fixed in place and does not move or rotate with the transformed group?
<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="myGradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="200" y2="0">
<stop offset="0%" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
</defs>
<g fill="url(#myGradient)" transform="translate(200, 200) rotate(0)">
<rect x="0" y="0" width="300" height="80"></rect>
<rect x="0" y="100" width="300" height="80"></rect>
</g>
</svg>
with rotate(0)
-> the blue color of the gradient is at right
with rotate(90)
-> the blue color of the gradient is at bottom
What adjustments should I make to ensure the gradient stays fixed relative to the screen and does not transform along with the group?
Move the shapes to be rendered with the gradient in a <mask>
element. Apply the gradient to a recttangle filling your complete canvas, and then cut out the shapes by applying the mask.
<svg width="400" height="400" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="myGradient" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="200" y2="0">
<stop offset="0%" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</linearGradient>
<mask id="shapes" fill="white">
<g transform="translate(200, 200) rotate(90)">
<rect x="0" y="0" width="300" height="80"></rect>
<rect x="0" y="100" width="300" height="80"></rect>
</g>
</mask>
</defs>
<rect width="100%" height="100%" fill="url(#myGradient)" mask="url(#shapes)">
</rect>
</svg>