Gradient fill SVG after button click on HTML page - css

Is possible to fill SVG by gradient colors after a button is clicked on the page? I read a lot of articles here, but none helped me. I need the gradient colors only in css (The best option).
Here's an example where I need to apply for "metalic colors" - http://web-stranky.org/pro_dementa/
I would be grateful for any help.

Svg yet not support CSS3 gradient property, although you can fill gradient in svg by defining gradient in svg and using fill property to attain gradient fill in svg.
<svg height="150" width="400">
<defs>
<linearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" style="stop-color:rgb(255,255,0);stop-opacity:1" />
<stop offset="100%" style="stop-color:rgb(255,0,0);stop-opacity:1" />
</linearGradient>
</defs>
<ellipse cx="200" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>
for more details
http://www.w3schools.com/svg/svg_grad_linear.asp

Related

Is it possible to animate a linear gradient gradientTransform property of an svg image

I have a simple outer circle svg created with the following code
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns="http://www.w3.org/2000/svg"
id="Layer_1"
data-name="Layer 1"
viewBox="0 0 260 260">
<style>
.class1 {
fill-opacity:1;
fill:url(#grayGradient);
}
</style>
<defs>
<linearGradient id="grayGradient"
gradientUnits="userSpaceOnUse"
x1="0" y1="130" x2="260" y2="130">
<stop offset="0" style="stop-color:#919191;stop-opacity:1;" />
<stop offset="1" style="stop-color:#919191;stop-opacity:0;" />
</linearGradient>
</defs>
<title>outer circle</title>
<path
d="M130,0A130,130,0,1,0,260,130,130,130,0,0,0,130,0Zm.36,235a105,105,0,1,1,105-105A105,105,0,0,1,130.36,235Z"
class="class1" />
</svg>
I'm trying to make this look like an indeterminate progress circle, so I want to rotate the gradient around the path of the circle. I know that if I add a gradientTransform=rotate() attribute to the linearGradient, it will move the position of the gradient in the circle.
Is it possible to animate the gradientTransform so that it will appear that the circle is spinning?
I'm very new to svg. Perhaps there is a better way to achieve the effect I'm looking for? I do need to use an svg image that has the same shape.
Thanks for any and all suggestions...
Just add inside <linearGradient> ... </linearGradient> this string:
<animateTransform
attributeName="gradientTransform"
type="rotate"
from="0 130 130"
to="360 130 130"
dur="1s"
repeatCount="indefinite"
/>
But it won't work in IE and Safari.

How do I absolute center a responsive svg background?

I'm trying to achieve the following result:
The body has a black background and a fixed height of the browser window. The graphic is a simple SVG with 50px margins on each side. This ratio should stay consistent as the browser resizes.
Implement the fixed-width black border as the stroke around the svg rectangle, which itself takes up the full width & height of the window. Something like this should do the trick for you (the snippit won't reder it properly so don't try running it in place--copy the code out to a separate file or to your page):
<svg xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="bgGradient">
<stop offset="0%" stop-color="#fe7b47" />
<stop offset="100%" stop-color="#8cbef7" />
</linearGradient>
</defs>
<rect x="0" y="0" width="100vw" height="100vh" fill="url(#bgGradient)" stroke="#000000" stroke-width="100px" />
</svg>

Is it possible to have two strokes on an SVG element?

I have some SVG elements (rectangles). When I double click on these I add a class to the rectangle.
This class is like so :
.highlighted {
stroke: green;
stroke-width : 3px;
}
Basically a green border. I tried the class like this :
.highlighted {
border: 3px solid green;
}
But it doesn't work as I'm working with SVG not HTML.
My question is, is it possible to have multiple strokes on one SVG rectangle element ?
At present the answer is no.
You would need a second rectangle to create the other 'stroke'.
There is hope however
Extract from the W3 spec
SVG 2 supports multiple strokes, which we will need updated wording to handle in this specification.
As for borders...they do not apply to SVG internal elements such as paths and rectangles etc....only the full SVG itself.
It is possible to have multiples borders on a div (with outline and border), but not on SVG.
You can to try with multiple paths.
My SVG knowledge is pretty minimal, but I think it should be possible to achieve these results using SVG Vector Effects.
"Vector effects allows stroking to be applied multiple times."
http://dev.w3.org/SVG/modules/vectoreffects/master/SVGVectorEffectsPrimer.html
Also, read this, please:
https://svgwg.org/specs/strokes/#SpecifyingStrokeAlignment
I don't know how to do it with a rectangle element but I can think of a way for circle and ellipse elements
<svg height="150" width="500">
<defs>
<radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style="stop-color:rgb(255,255,255)" />
<stop offset="20%" style="stop-color:rgb(255,255,255)" />
<stop offset="20%" style="stop-color:rgb(100,255,255)" />
<stop offset="40%" style="stop-color:rgb(100,255,255)" />
<stop offset="40%" style="stop-color:rgb(50,5,255)" />
<stop offset="60%" style="stop-color:rgb(50,5,255)" />
<stop offset="60%" style="stop-color:rgb(50,50,25)" />
<stop offset="80%" style="stop-color:rgb(50,50,25)" />
<stop offset="80%" style="stop-color:rgb(250,0,0)" />
<stop offset="100%" style="stop-color:rgb(250,0,0)" />
</radialGradient>
</defs>
<circle cx="70" cy="70" r="55" fill="url(#grad1)" />
<ellipse cx="250" cy="70" rx="85" ry="55" fill="url(#grad1)" />
</svg>

Re-using SVG gradient via CSS

So I know I can swap out a gradient fill on an svg with css, something like;
<svg width="100" height="50" version="1.1" xmlns="http://www.w3.org/2000/svg">
<style type="text/css">
rect{fill:url(#GradientSwap1)}
</style>
<defs>
<linearGradient id="GradientSwap1">
<stop offset="5%" stop-color="#F00" />
<stop offset="95%" stop-color="#999" />
</linearGradient>
</defs>
<rect width="100" height="50"/>
</svg>
and using ng-class I can swap out more than one of these gradients, except I can only get it to work if I include the <linearGradient> in the defs embedded into each SVG.
My question is, and what I can't seem to figure out. Is there a way to pull these gradient defs out of the SVG and make them into a resource I can use in others? Like in the .NET / XAML world, it would be really easy for me to pull them out, throw them in a resource dictionary, and use the same ones all over the place for whatever I like.
So is there an html5/css3/angular approach to the same conundrum? The idea of having to have to multiple SVG's with potentially multiple of the same Gradient defs reiterated for every single one just sounds wrong.
You should be able to define the gradient once and then call it in the CSS to apply anywhere. You could apply to all svgs or give it a class.
<svg>
<defs>
<linearGradient id="GradientSwap1">
<stop offset="5%" stop-color="#F00"></stop>
<stop offset="95%" stop-color="#999"></stop>
</linearGradient>
</defs>
<section>
<svg class="icon shape-facebook">
<path d="M28.3,62V35.2h-5.5v-9.4h5.6v-7.7c0,0,0.3-9.8,9.8-9.8s9.5,0,9.5,0v9.2H42.1c0,0-2.699,0-2.699,2.7c0,2.7,0,5.8,0,5.8H48
l-1.1,9.4H39.6V62H28.3z"></path>
</svg>
<svg class="icon shape-heart" x="0" y="0">
<path d="M35.645,59.413c0,0,26.949-19.601,26.949-34.12c0-16.752-22.049-22.047-26.949-1.674
c-4.9-20.373-26.95-15.078-26.95,1.674C8.695,39.812,35.645,59.413,35.645,59.413z"></path>
</svg>
.shape-heart { fill: url('#GradientSwap1'); }
http://jsfiddle.net/v6osyy5v/1/

Creating a linear gradient SVG filter

Essentially I'm trying to create an gradient alpha mask in using SVG and CSS (like this), and since the mask property is no longer on the standards track I'm exploring the filter route.
I've created a vertical alpha mask in Sketch, with the top being 0% #000000 and the bottom being 100% #000000, then exported it as an SVG and tweaked it using guidance from this O' Reilly article. It now looks like this:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<!-- Start by creating our vertical linear gradient -->
<linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="alphaLinear">
<stop offset="0%" style="stop-color: #000000; stop-opacity: 0%;" />
<stop offset="100%" style="stop-color: #000000; stop-opacity: 100%;" />
</linearGradient>
<!-- Create a rectangle and apply the gradient as its fill -->
<rect id="boxRect" x="0" y="0" width="100%" height="200" style="fill: url(#alphaLinear);" />
<!-- Using that rectangle, we'll create a filter -->
<filter id="alphaGrad">
<feImage xlink:href="#boxRect" result="grad"/>
<feDisplacementMap scale="10" xChannelSelector="R" yChannelSelector="G" in="SourceGraphic" in2="grad"/>
</filter>
</defs>
<use id="gradientBox" fill="url(#alphaGradient)" xlink:href="#boxRect"></use>
</svg>
My knowledge of SVG isn't the greatest so I'm suspecting this is where I've gone wrong.
Next, I applied the filter using filter (and -webkit-filter) along with referencing the filter ID #alphaGrad:
-webkit-filter: url('http://blahblah.com/alphagradient.svg#alphaGrad');
But, of course, this it doesn't work. Can anyone help me get the hang of this? Or is this even possible? If not, can someone recommend a method of how to achieve this?
Thanks in advance!
Update: here's a pretty basic fiddle of what I'm doing...
There are many errors and misconceptions in your example (why did you think a displacementMap would help you?)
Why don't you start from the code below - pure SVG using an SVG mask and an SVG image.
<svg width="600px" height="600px" viewbox="0 0 600 600">
<defs>
<linearGradient id="alphaLinear">
<stop offset="0%" stop-color="#FFFFFF" stop-opacity="0%" />
<stop offset="100%" stop-color="#999999" stop-opacity="100%" />
</linearGradient>
<mask id="Mask">
<rect x="0" y="0" width="600" height="600" fill="url(#alphaLinear)" />
</mask>
</defs>
<image xlink:href="http://upload.wikimedia.org/wikipedia/commons/7/71/Anadama_bread_(1).jpg" width="600" height="600" x="0" y="0" preserveAspectRatio="xMinYMin meet" mask="url(#Mask)"/>
</svg>
Few remarks:
SVG (and CSS) opacity value is not percertentual range but 0.0 - 1.0 range.
Mentioned mask property appears to be just prefixed in Webkit and unprefixed in Gecko.
If your target environment is HTML + CSS, you might not necessarily need SVG: you could get similar effect using linear-gradient and RGBA
background-image: linear-gradient(to bottom, rgba(0,0,0,1) 0%,rgba(0,0,0,0) 50%); on some overlay (pseudo) element. pointer-events: none; could be useful then.

Resources