How to set up gulp-svgmin in the safest way? - svg

does anyone know how to use gulp-svgmin?
I tested it with a simple svg file, but the output removed the clipPath and mask tags
input:
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="hex-v" clipPathUnits="objectBoundingBox"><!--objectBoundingBox is important, so that the points becomes percentage values inside the element clipped-->
<polygon points=".25 0, .75 0, 1 .5, .75 1, .25 1, 0 .5"/>
</clipPath>
<clipPath id="hex-h" clipPathUnits="objectBoundingBox"><!--objectBoundingBox is important, so that the points becomes percentage values inside the element clipped-->
<polygon points=".5 0, 1 .25, 1 .75, .5 1, 0 .75, 0 .25"/>
</clipPath>
<radialGradient id="gradient" r="1">
<stop stop-color="white" offset="50%"/>
<stop stop-color="black" offset="70%"/>
</radialGradient>
<mask id="masking" maskUnits="objectBoundingBox" maskContentUnits="objectBoundingBox">
<rect width="1" height="1" fill="url(#gradient)"/>
</mask>
</defs>
</svg>
output:
<svg xmlns="http://www.w3.org/2000/svg"><defs><radialGradient id="a" r="1"><stop stop-color="#fff" offset="50%"/><stop offset="70%"/></radialGradient></defs></svg>
So I assume it's because there are some options I should set for the svgmin?
I want svgmin to minify the files in the safest way possible, so I don't get unexpected results.
Or is there a different gulp plugin I can use?
Thanks

Related

How to have image inside svg background with radialGradient

I have svg element with some image inside it. I tried clipPath, but the results were not as expected
here's the code
<svg width="5396" height="829" enable-background="new" version="1.1" viewBox="0 0 1427.7 219.34" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="headera" cx="-334.2" cy="-79.465" r="713.85" gradientTransform="matrix(.35196 -.0011319 .0010719 .334 127.5 106)" gradientUnits="userSpaceOnUse">
<stop stop-color="#9d6173" offset="0"/>
<stop stop-color="#594b4f" offset="1"/>
</radialGradient>
<clipPath id="dodol">
<rect x="36.286" y="108.01" width="0" height="0" fill-opacity="0" stroke="#453030" stroke-linecap="round" stroke-linejoin="round" stroke-width=".052917"/>
<path d="m-535.38 77.813v6.0476c2.9078 113.15 92.911 174.65 152.71 167.82 169.93-23.912 248.91 44.042 387.75 45.474 56.339-1.17 204.04-22.034 204.04-22.034 78.053-5.4634 100.32 22.158 142.53 22.034 181.38-0.15553 205.7-119.12 449.25-127.14 104.33-1.7411 90.846-92.203 90.846-92.203z" fill="url(#headera)"/>
</clipPath>
</defs>
<g transform="matrix(1 0 0 .99999 535.38 -77.81)">
<rect x="36.286" y="108.01" width="0" height="0" fill-opacity="0" stroke="#453030" stroke-linecap="round" stroke-linejoin="round" stroke-width=".052917"/>
<path d="m-535.38 77.813v6.0476c2.9078 113.15 92.911 174.65 152.71 167.82 169.93-23.912 248.91 44.042 387.75 45.474 56.339-1.17 204.04-22.034 204.04-22.034 78.053-5.4634 100.32 22.158 142.53 22.034 181.38-0.15553 205.7-119.12 449.25-127.14 104.33-1.7411 90.846-92.203 90.846-92.203z" fill="url(#headera)"/>
</g>
<image clip-path="url(#dodol)" preserveAspectRatio="xMaxYMid meet" width="643px" height="50%" x="250" y="20" xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png"/>
</svg>
the problem with the code is I can't resize the image as it should and some of the outgoing image that exceeds the svg element remains visible
what i want to achive is
the svg shape appears as the background for the image inside it
the image appereance clipped by svg shape
I can adjust the position and size of the image
thanks
I'm not very sure this is what you need. Please take a look.
The main idea is that you have to put the image inside the transformed group.
Also I've removed some useless elements (rects with width and height 0). Also instead of using the same path twice I'm reusing it with <use>
Yet another thing: I've changed the image size so that it keeps it's width/height ratio. It may not be what you want.
<svg viewBox="0 0 1427.7 219.34" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="headera" cx="-334.2" cy="-79.465" r="713.85" gradientTransform="matrix(.35196 -.0011319 .0010719 .334 127.5 106)" gradientUnits="userSpaceOnUse">
<stop stop-color="#9d6173" offset="0"/>
<stop stop-color="#594b4f" offset="1"/>
</radialGradient>
<clipPath id="dodol">
<path id="thePath" d="m-535.38 77.813v6.0476c2.9078 113.15 92.911 174.65 152.71 167.82 169.93-23.912 248.91 44.042 387.75 45.474 56.339-1.17 204.04-22.034 204.04-22.034 78.053-5.4634 100.32 22.158 142.53 22.034 181.38-0.15553 205.7-119.12 449.25-127.14 104.33-1.7411 90.846-92.203 90.846-92.203z" />
</clipPath>
</defs>
<g transform="matrix(1 0 0 .99999 535.38 -77.81)">
<use xlink:href="#thePath" fill="url(#headera)"/>
<image clip-path="url(#dodol)" width="600" height="529" x="250" y="20" xlink:href="https://mdn.mozillademos.org/files/6457/mdn_logo_only_color.png"/>
</g>
</svg>

SVG — radial gradient with a smooth edged cutout

I'm trying to create a SVG background image like this (two colors, radial gradient, S-shape cutout with smooth edges):
It's quite easy to create a radial gradient (e.g. using this tool):
<!-- SVG syntax -->
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">
<radialGradient id="g920" gradientUnits="userSpaceOnUse" cx="5.408560311284047%" cy="0%" r="93.04166277718278%">
<stop stop-color="#ed1c24" offset="0.1"/><stop stop-color="#003663" offset="1"/>
</radialGradient>
<rect x="-50" y="-50" width="101" height="101" fill="url(#g920)" />
</svg>
but is it possible to add the cutout too?
Lennis' answer was close. But you would get better results by combining the fill and the filter in one element, rather than try to use a blurry white shape to hide part of the gradient.
Note that the blur will affect any edge of the shape, including the top, left and right. So you need to make sure those edges are well away from (outside of) the edge of the SVG viewport.
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">
<defs>
<radialGradient id="g" gradientUnits="userSpaceOnUse" cx="5.4%" cy="0%" r="93%">
<stop stop-color="#ed1c24" offset="0.1"/>
<stop stop-color="#003663" offset="0.8"/>
</radialGradient>
<filter id="f1" x="0" y="0">
<feGaussianBlur in="SourceGraphic" stdDeviation=".05" />
</filter>
</defs>
<path id="svg_1" d="M -0.5,-0.5
L 1.5,-0.5
L 1.5,0.5
L 1,0.5
C 1,0 0.6,0.1 0.5,0.25
C 0.4,0.4 0.1,0.4 0,0.25
L -0.5,0.25
Z"
fill="url(#g)" filter="url(#f1)"/>
</svg>
You could use a blur on a white element to make it look like a cutout.
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">
<defs>
<radialGradient id="g" gradientUnits="userSpaceOnUse" cx="5.4%" cy="0%" r="93%">
<stop stop-color="#ed1c24" offset="0.1"/>
<stop stop-color="#003663" offset="1"/>
</radialGradient>
<filter id="f1" x="0" y="0">
<feGaussianBlur in="SourceGraphic" stdDeviation=".05" />
</filter>
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#g)" />
<path id="svg_1" fill="white" d="m-0.1,0.5 l0,0.55l1.15,0l0,-0.53495c0,0 -0.1,-0.1 -0.5,0c-0.3,0.1 -0.5,0 -0.5,0l-0.1,0z" filter="url(#f1)"/>
</svg>
You could also try a meshgradient, it's in the svg 2.0 spec. At the moment no browser supports it that I know off.

Fading edges of line/rect

I have an svg <g> in which I have a line (can be rect too.. have tried both). This inner element has a fill/stroke that can rotate from 8 different colors or patterns. The shape is 5px height, with a dynamic width, and I should support fading left, right or both edges.
I would like to achieve this without creating extra elements on the svg and some how apply a mask/gradient but it seems I cannot get it to work.
Since the shape's X and Y, color, and width can change, I have not found a consistent way to make this happen without creating new elements with a bunch of color combinations. Does anyone have an idea on how to achieve this in the most simple and scalable way?
UPDATE
After Paul suggestion i created a fiddle to represent some how the scenario i have:
https://jsfiddle.net/0tnc9mq5/
So multiplelines/rects in same svg with different colors, positions and dimensions. What would be the way to apply some of those fades to some of those elements? How would i implement Paul's suggestion? Is there any other approach?
Thanks
Here is one way to do it, using masks to produce the fading ends. The fades are fixed in this example to be 10% of the length of the line.
We create a shared SVG that contains <symbol> elements for each of the three variants you need. That only needs to appear once in your HTML.
Then anywhere you want one of the separators, include the mini SVG corresponding to the separator you desire. You can set the width, height and colour of the separator using CSS.
svg.sep {
width: 500px;
height: 5px;
}
.one {
color: red;
}
.two {
color: green;
}
.three {
color: blue;
}
<svg width="0" height="0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient id="gleft">
<stop offset="0%" stop-color="black"/>
<stop offset="10%" stop-color="white"/>
</linearGradient>
<linearGradient id="gright">
<stop offset="90%" stop-color="white"/>
<stop offset="100%" stop-color="black"/>
</linearGradient>
<linearGradient id="gboth">
<stop offset="0%" stop-color="black"/>
<stop offset="10%" stop-color="white"/>
<stop offset="90%" stop-color="white"/>
<stop offset="100%" stop-color="black"/>
</linearGradient>
<mask id="mleft">
<rect width="1" height="1" fill="url(#gleft)"/>
</mask>
<mask id="mboth">
<rect width="1" height="1" fill="url(#gboth)"/>
</mask>
<mask id="mright">
<rect width="1" height="1" fill="url(#gright)"/>
</mask>
<symbol id="left" viewBox="0 0 1 1" preserveAspectRatio="none">
<rect width="1" height="1" fill="currentColor" mask="url(#mleft)"/>
</symbol>
<symbol id="both" viewBox="0 0 1 1" preserveAspectRatio="none">
<rect width="1" height="1" fill="currentColor" mask="url(#mboth)"/>
</symbol>
<symbol id="right" viewBox="0 0 1 1" preserveAspectRatio="none">
<rect width="1" height="1" fill="currentColor" mask="url(#mright)"/>
</symbol>
</defs>
</svg>
<p> Lorem ipsum dolor sit</p>
<svg viewBox="0 0 1 1" preserveAspectRatio="none" class="sep one">
<use xlink:href="#left"/>
</svg>
<p> Lorem ipsum dolor sit</p>
<svg viewBox="0 0 1 1" preserveAspectRatio="none" class="sep two">
<use xlink:href="#right"/>
</svg>
<p> Lorem ipsum dolor sit</p>
<svg viewBox="0 0 1 1" preserveAspectRatio="none" class="sep three">
<use xlink:href="#both"/>
</svg>

SVG arc with conical gradient [duplicate]

Is there a way to do an 'angular gradient' in SVG?
(I don't know the official term -- it's the kind of gradient you see in color-pickers, where it varies by angle.)
SVG seems to support only linear and radial gradients, but I'm thinking there might be some way to use a transform to simulate what I want.
thanks!
...10 years later...
CSS now supports conical gradients, although browser support is mixed at the time of writing this.
You could apply a <clipPath /> to a <foreignObject /> whose contents use a CSS conical gradient to achieve the desired effect.
https://codepen.io/eastonium/pen/abOpdEm
There's no standard support to do angular (conical) gradients.
But see http://wiki.inkscape.org/wiki/index.php/Advanced_Gradients#Conical_gradient for some approximation methods (source code not included, though). Examples on that link do not work.
Here is how to do it using patterns: https://jsfiddle.net/prozoroff/8eodzrke/
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="800" width="800">
<defs>
<linearGradient id="Gradient1" gradientTransform="rotate(90)">
<stop offset="0%" stop-color="#ff0000"/>
<stop offset="100%" stop-color="#00ff00"/>
</linearGradient>
<linearGradient id="Gradient2" gradientTransform="rotate(90)">
<stop offset="0%" stop-color="#0000ff"/>
<stop offset="100%" stop-color="#00ff00"/>
</linearGradient>
<pattern id="Pattern" x="0" y="0" width="600" height="600" patternUnits="userSpaceOnUse">
<g transform="rotate(0, 300, 300)">
<rect shape-rendering="crispEdges" x="0" y="0" width="300" height="600" fill="url(#Gradient1)"/>
<rect shape-rendering="crispEdges" x="300" y="0" width="300" height="600" fill="url(#Gradient2)"/>
</g>
</pattern>
</defs>
<path id='arc5' style="stroke: url(#Pattern);" fill='transparent' stroke-width='60' d='M 364 58 A 250 250 0 1 1 235 58'/>
</svg>
In my answer to this similar question, I used six linear gradients to approximate a conical gradient. If you are only needing the gradient for the stroke/perimeter of a circle, rather than the fill, then it should be a good enough approximation.
svg multiple color on circle stroke
Here is a possible vector conical gradient, but only VML (+IE) can do it...:
http://midiwebconcept.free.fr/Demos/degradeconique.htm
If you dig into this page, you'll find code that approximates a conic gradient in SVG by drawing it as a series of 1 degree arcs.
Add a patern with 100% width and height so its just a one repetition pattern
<div style="width:100px">
<svg viewBox="0 0 35 35" style="transform: scale(1) rotate(-90deg)">
<defs>
<pattern
id="p1"
patternUnits="userSpaceOnUse"
width="100%"
height="100%"
patternTransform="rotate(90)"
>
<image href="https://blogs.igalia.com/dpino/files/2020/06/conic-gradient.png" width="36" height="36" />
</pattern>
</defs>
<g>
<circle
cx="50%"
cy="50%"
stroke-width="2"
r="15.915"
stroke-dasharray="89, 100"
stroke="url(#p1)"
fill="none"
/>
</g>
</svg>
</div>
http://en.wikipedia.org/wiki/File:Blended_colour_wheel.svg uses an innovative technique to approximate it.

SVG angular gradient

Is there a way to do an 'angular gradient' in SVG?
(I don't know the official term -- it's the kind of gradient you see in color-pickers, where it varies by angle.)
SVG seems to support only linear and radial gradients, but I'm thinking there might be some way to use a transform to simulate what I want.
thanks!
...10 years later...
CSS now supports conical gradients, although browser support is mixed at the time of writing this.
You could apply a <clipPath /> to a <foreignObject /> whose contents use a CSS conical gradient to achieve the desired effect.
https://codepen.io/eastonium/pen/abOpdEm
There's no standard support to do angular (conical) gradients.
But see http://wiki.inkscape.org/wiki/index.php/Advanced_Gradients#Conical_gradient for some approximation methods (source code not included, though). Examples on that link do not work.
Here is how to do it using patterns: https://jsfiddle.net/prozoroff/8eodzrke/
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" height="800" width="800">
<defs>
<linearGradient id="Gradient1" gradientTransform="rotate(90)">
<stop offset="0%" stop-color="#ff0000"/>
<stop offset="100%" stop-color="#00ff00"/>
</linearGradient>
<linearGradient id="Gradient2" gradientTransform="rotate(90)">
<stop offset="0%" stop-color="#0000ff"/>
<stop offset="100%" stop-color="#00ff00"/>
</linearGradient>
<pattern id="Pattern" x="0" y="0" width="600" height="600" patternUnits="userSpaceOnUse">
<g transform="rotate(0, 300, 300)">
<rect shape-rendering="crispEdges" x="0" y="0" width="300" height="600" fill="url(#Gradient1)"/>
<rect shape-rendering="crispEdges" x="300" y="0" width="300" height="600" fill="url(#Gradient2)"/>
</g>
</pattern>
</defs>
<path id='arc5' style="stroke: url(#Pattern);" fill='transparent' stroke-width='60' d='M 364 58 A 250 250 0 1 1 235 58'/>
</svg>
In my answer to this similar question, I used six linear gradients to approximate a conical gradient. If you are only needing the gradient for the stroke/perimeter of a circle, rather than the fill, then it should be a good enough approximation.
svg multiple color on circle stroke
Here is a possible vector conical gradient, but only VML (+IE) can do it...:
http://midiwebconcept.free.fr/Demos/degradeconique.htm
If you dig into this page, you'll find code that approximates a conic gradient in SVG by drawing it as a series of 1 degree arcs.
Add a patern with 100% width and height so its just a one repetition pattern
<div style="width:100px">
<svg viewBox="0 0 35 35" style="transform: scale(1) rotate(-90deg)">
<defs>
<pattern
id="p1"
patternUnits="userSpaceOnUse"
width="100%"
height="100%"
patternTransform="rotate(90)"
>
<image href="https://blogs.igalia.com/dpino/files/2020/06/conic-gradient.png" width="36" height="36" />
</pattern>
</defs>
<g>
<circle
cx="50%"
cy="50%"
stroke-width="2"
r="15.915"
stroke-dasharray="89, 100"
stroke="url(#p1)"
fill="none"
/>
</g>
</svg>
</div>
http://en.wikipedia.org/wiki/File:Blended_colour_wheel.svg uses an innovative technique to approximate it.

Resources