31

I've seen a few questions dancing around this, so I hope this isn't too redundant. Ideally, I'd like an image/svg+xml which scales to 100% of it's container. Colorzilla gets me a great start with a data:image/svg+xml

<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">
  <linearGradient id="grad-ucgg-generated" gradientUnits="userSpaceOnUse" x1="0%" y1="0%" x2="100%" y2="0%">
    <stop offset="0%" stop-color="#ffffff" stop-opacity="0"/>
    <stop offset="100%" stop-color="#ff0000" stop-opacity="1"/>
  </linearGradient>
  <rect x="0" y="0" width="1" height="1" fill="url(#grad-ucgg-generated)" />
</svg>

Note: the width="100%" height="100%" I'd like to take this gradient and rotate it by, say 65deg The HTML5 canvas API provides a great way for me to build this image and then use .toDataURL() PNG to polyfill IE8 and IE7, but I'd like something scalable for IE9.

So the goal is to replicate this:

background: linear-gradient(bottom, rgba(239, 239, 214,0) 0%, rgba(239, 239, 214,.8) 100%),
linear-gradient(left,  rgba(239, 239, 214,0) 60%,rgba(207, 223, 144,1) 100%),
linear-gradient(right, rgba(239, 239, 214,0) 0%,rgba(239, 239, 214,1) 60%),
linear-gradient(top, rgba(239, 239, 214,0) 60%,#cfdf90 100%);
}

with an image/svg+xml that's 100% width and height.

I did try out http://svg-edit.googlecode.com but the interface was less than intuitive for the types of editing I wanted to do. Thanks!

Serge S.
  • 4,855
  • 3
  • 42
  • 46
bodine
  • 1,763
  • 4
  • 19
  • 28

4 Answers4

57

To rotate the gradient you can e.g use the 'gradientTransform' attribute, like this:

<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" 
 viewBox="0 0 1 1" preserveAspectRatio="none">
  <linearGradient id="grad-ucgg-generated" gradientUnits="userSpaceOnUse" 
   x1="0%" y1="0%" x2="100%" y2="0%" gradientTransform="rotate(65)">
    <stop offset="0%" stop-color="#ffffff" stop-opacity="0"/>
    <stop offset="100%" stop-color="#ff0000" stop-opacity="1"/>
  </linearGradient>
  <rect x="0" y="0" width="1" height="1" fill="url(#grad-ucgg-generated)" />
</svg>
Rúnar Berg
  • 4,229
  • 1
  • 22
  • 38
Erik Dahlström
  • 59,452
  • 12
  • 120
  • 139
14

Please note that the gradientTransform attribute rotates the gradient according to it's anchor point at 0,0. To rotate it from the 'center' you need to calculate the proper percentages for x1, y1, x2 and y2. A simple PHP example:

// Rotation can be 0 to 360
$pi = $rotation * (pi() / 180);
$coords = array(
    'x1' => round(50 + sin($pi) * 50) . '%',
    'y1' => round(50 + cos($pi) * 50) . '%',
    'x2' => round(50 + sin($pi + pi()) * 50) . '%',
    'y2' => round(50 + cos($pi + pi()) * 50) . '%',
)
Giel Berkers
  • 2,852
  • 3
  • 39
  • 58
  • 7
    Easier to set the rotate origin in the gradientTransform surely as the two additional arguments to the rotate – Robert Longson Sep 17 '15 at 20:53
  • Could you provide an example on how to set the rotate origin? – Giel Berkers Sep 18 '15 at 07:28
  • 3
    in gradientTransform="rotate(90, 50, 30)" the origin of the rotation would be 50, 30 – Robert Longson Sep 19 '15 at 06:13
  • 2
    @Robert actually in SVG it's different than CSS which is the format you have there with commas. In the SVG spec it says transform paramaters are "(deg [x y])" separated by space, not comma. So, your example might work with gradientTransform="rotate(90 50 30)", but if you wrote it in CSS with inline transform= it would indeed be with commas as you had it. Tricky little difference had me stuck for a while on that one. Reference: https://css-tricks.com/transforms-on-svg-elements/ – OG Sean Aug 25 '17 at 00:02
  • 3
    @OGSean Per https://www.w3.org/TR/SVG/coords.html#TransformAttribute - scroll down to the BNF see this bit... "rotate" wsp* "(" wsp* number ( **comma**-wsp number **comma**-wsp number )? wsp* ")" – Robert Longson Aug 25 '17 at 06:14
  • 1
    @RobertLongson with Chrome I seem to be able to get both ways to work, my mistake. – OG Sean Sep 04 '17 at 02:46
  • 4
    To rotate the gradient from its center (makes it easier to get the expected result) when `gradientUnits` is `userSpaceOnUse` (default), use `rotate( 0.5 0.5)`. – cdoublev Apr 27 '21 at 06:53
  • @cdoublev's comment needs to be seen! I spent hours trying to figure this out how to rotate around the centre before realising there was 'two more' comments. – Harry Jan 12 '23 at 13:16
12

Giel Berkers' solution in Javascript would be:

// angle can be 0 to 360
var anglePI = (angle) * (Math.PI / 180);
var angleCoords = {
    'x1': Math.round(50 + Math.sin(anglePI) * 50) + '%',
    'y1': Math.round(50 + Math.cos(anglePI) * 50) + '%',
    'x2': Math.round(50 + Math.sin(anglePI + Math.PI) * 50) + '%',
    'y2': Math.round(50 + Math.cos(anglePI + Math.PI) * 50) + '%',
}
Hooman Askari
  • 1,486
  • 16
  • 30
7
<linearGradient gradientTransform="rotate(65)">
Henrik Albrechtsson
  • 1,707
  • 2
  • 17
  • 17