svg rect radius with filter - html

I ran into a problem that rect with rx specified doesn't work after applying filter to rect
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
<defs>
<filter id="floodFilter" filterUnits="userSpaceOnUse">
<feFlood
flood-color="#488764"
flood-opacity="1"
result="background"
/>
<feBlend mode="normal" in="SourceGraphic" in2="background" />
</filter>
<linearGradient id="animation">
<stop offset="0" stop-color="rgba(248, 222, 86, 0)"/>
<stop offset="100%" stop-color="#65ae83"/>
</linearGradient>
</defs>
<rect width="100" height="200" filter="url(#floodFilter)" fill="url(#animation)" rx="8">
<animate attributeType="XML" attributeName="x" from="-100" to="100" dur="1s" repeatCount="indefinite"/>
</rect>
</svg>
So the question is how to apply the filter and keep the rx for the rectangle?
UPD: I can't use the fill attribute because fill is used for animation
UPD2: Added more examples with fill and filter and animation

Try using a background rect with rounded corners:
<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">
<defs>
<linearGradient id="animation">
<stop offset="0" stop-color="rgba(248, 222, 86, 0)"/>
<stop offset="100%" stop-color="#65ae83"/>
</linearGradient>
</defs>
<rect width="200" height="200" rx="8" fill="#65ae83" />
<rect width="100" height="200" fill="url(#animation)" rx="8">
<animate attributeType="XML" attributeName="x" from="0" to="100" dur="1s" repeatCount="indefinite"/>
</rect>
</svg>

Related

How to partially fill an svg path using percentage value? [duplicate]

I have a jsfiddle here - http://jsfiddle.net/apbuc773/
I'd like to create a star using svg.
I'd like to stroke the outside of the star. In my example the stroke is on every line which dissects the inner shape.
Also is it possible to half fill the star shape.
I'd like to use this for a star rating but I need half and maybe quarter fills.
<svg height="210" width="500">
<polygon points="100,10 40,198 190,78 10,78 160,198" style="fill:red;stroke:blue;"/>
</svg>
You can alternatively do this with a filter. Here is one that animates the fill:
<svg height="210" width="500">
<defs>
<filter id="fillpartial" primitiveUnits="objectBoundingBox" x="0%" y="0%" width="100%" height="100%">
<feFlood x="0%" y="0%" width="100%" height="100%" flood-color="red" />
<feOffset dy="0.5">
<animate attributeName="dy" from="1" to=".5" dur="3s" />
</feOffset>
<feComposite operator="in" in2="SourceGraphic" />
<feComposite operator="over" in2="SourceGraphic" />
</filter>
</defs>
<polygon filter="url(#fillpartial)" points="165.000, 185.000, 188.511, 197.361, 184.021, 171.180,
203.042, 152.639,
176.756, 148.820,
165.000, 125.000,
153.244, 148.820,
126.958, 152.639,
145.979, 171.180,
141.489, 197.361,
165.000, 185.000" style="fill:white;stroke:red;" />
</svg>
Here is a example: http://jsfiddle.net/apbuc773/11/
Gradient can be used like this:
<svg height="210" width="500">
<defs>
<linearGradient id="half">
<stop offset="0%" stop-color="red" />
<stop offset="50%" stop-color="red" />
<stop offset="50%" stop-color="white" />
<stop offset="100%" stop-color="white" />
</linearGradient>
</defs>
<g fill="url(#half)" stroke="blue" stroke-width="2">
If you don't want to change your polygon points, just apply this polygon twice: one time with stroke and one time without.
I've noticed the comment of the accepted answer, and here is how you fill an custom shape:
<svg width="100" height="100" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<clipPath id="heart">
<path d="M81.495,13.923c-11.368-5.261-26.234-0.311-31.489,11.032C44.74,13.612,29.879,8.657,18.511,13.923 C6.402,19.539,0.613,33.883,10.175,50.804c6.792,12.04,18.826,21.111,39.831,37.379c20.993-16.268,33.033-25.344,39.819-37.379 C99.387,33.883,93.598,19.539,81.495,13.923z"/>
</clipPath>
</defs>
<rect x="0" y="0" fill="rgb(217,217,217)" width="100%" height="100%" clip-path="url(#heart)" />
<rect x="0" y="50%" fill="red" width="100%" height="100%" clip-path="url(#heart)" />
</svg>

Fill SVG from bottom right to top left

I am trying to create a animation that fills my SVG from bottom right to top left after 2 seconds, what I have now is that it fills from right to left right when the page loads:
<div id="home" class="section" style="height:100vh;background:pink;">
<div class="background">
<svg viewBox="0 0 1366 768">
<defs>
<clipPath id="a" transform="translate(7)">
<rect class="a" width="1366" height="768" />
</clipPath>
<linearGradient id="animation">
<stop offset="0" stop-color="#ffffff">
<animate dur="1s" attributeName="offset" fill="freeze" from="0" to="1" begin="2.5s;" />
</stop>
<stop offset="0" stop-color="rgba(0,0,0,0)">
<animate attributeName="offset" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<g id="line">
<path class="c" fill="url(#animation)" d="M-7,0V768H1027.27l3.28-5.74c-3.1-5-4.9-11.68-6.45-15.93a5,5,0,0,1-.31-1.8c-.59-.57-1.19-1.12-1.77-1.71-4.19-4.3-8.13-8.78-12.31-13a5.41,5.41,0,0,1-2.41-1.24c-4-3.5-7.81-7.21-11.48-11-5.46-4.43-11-8.81-16.38-13.28-4.44-3.66-8.52-7.74-12.59-11.83l-1-1c-6.4-4.7-12.8-10.09-17.69-16.33-3.17-2.59-6.44-5.07-9.84-7.37-6.36-4.28-13.79-6.62-20.08-11-6.63-4.57-10.46-11.16-13.91-18.25A55.54,55.54,0,0,0,889,619.33c-6.11-5.14-12.61-9.88-18.16-15.64a78,78,0,0,1-12.74-18.42c-7.73-14.85-12.53-30.54-10.76-47.38,1.9-18,8.79-34.68,13.49-52,1.5-5.52,3.18-10.45,6.24-14.93a5.66,5.66,0,0,1,1.46-2c.62-.76,1.28-1.51,2-2.25,1.74-1.78,3.61-3.39,5.52-5,2.54-8.39,5.63-16.95,11.57-22.85s14.36-8.35,21.46-12.53l3.7-3.57a5.36,5.36,0,0,1,2.39-5.47l6-4,.13-.08a5.88,5.88,0,0,1,.86-1.14l.3-.28a56.64,56.64,0,0,1,6.64-8.71,65.33,65.33,0,0,1,12.5-9.54,117.79,117.79,0,0,1,21.82-11.11c2.33-2.18,4.67-4.3,7-6.36a5.65,5.65,0,0,1,1.71-1.05c10.21-9.09,20.39-18.22,30.84-27,23.11-19.45,53.32-31.79,67.9-59.69,3.29-6.31,5.61-13.11,9.27-19.24a42.87,42.87,0,0,1,8.74-10.4,4.6,4.6,0,0,1,1.48-3.27c12.36-12.17,26.31-22.61,38.52-35,9.54-9.64,17.38-20.78,26.94-30.43a125.77,125.77,0,0,1,28.08-21.42,5.51,5.51,0,0,1,3.16-3.15,78.09,78.09,0,0,1,8.24-2.51c24.36-10.73,51.73-14.36,78.2-11.67l.37.06a4.68,4.68,0,0,1,3.1-1.06,4.55,4.55,0,0,1,4.55,3.25c14-.7,28.06-1.53,41.63,1.59A41,41,0,0,1,1351,176.34a108.65,108.65,0,0,1,10.4,6.73L1366,175V0Z"
transform="translate(7)" />
<path class="d" d="M1034.5,770.5a125.59,125.59,0,0,0-17-32c-12.32-16.72-25.68-25.84-33-31-6-4.23-59.88-42.55-100-90-13.64-16.14-20.57-24.48-26-38-15-37.48-3.73-73.65,0-85,8.68-26.45,23-43.26,35-57,19-21.82,33.56-29.9,67-54,33.68-24.27,55.39-39.91,77-60,40.56-37.69,35.94-49.35,81-96,34.18-35.39,51.27-53.08,79-65,7.79-3.35,76-31.44,140,2a142.06,142.06,0,0,1,31,22l7.5,7.5"
transform="translate(7)" />
</g>
<polyline class="c" points="1373 175 1373 184.22 1370.37 179.61" />
</svg>
</div>
</div>
How can I make it so that it fills from bottom right to top left after 2 seconds?
begin changes the animation start time and set the initial offset to be the same as the start animation value as the animation won't apply before its start time.
You can either adjust x1, y1, x2, y2 of the gradient or set gradientTransform="rotate(45)" though you'd probably want a scale transform too as the shape you're filling isn't square.
<svg viewBox="0 0 1366 768">
<defs>
<clipPath id="a" transform="translate(7)">
<rect class="a" width="1366" height="768" />
</clipPath>
<linearGradient id="animation" x1="0" y1="0" x2="100%" y2="100%">
<stop offset="1" stop-color="#580073">
<animate dur="2s" begin="2s" attributeName="offset" fill="freeze" from="1" to="0" />
</stop>
<stop offset="1" stop-color="#fff">
<animate dur="2s" begin="2s" attributeName="offset" fill="freeze" from="1" to="0" />
</stop>
</linearGradient>
</defs>
<g id="line">
<path class="c" fill="url(#animation)" d="M-7,0V768H1027.27l3.28-5.74c-3.1-5-4.9-11.68-6.45-15.93a5,5,0,0,1-.31-1.8c-.59-.57-1.19-1.12-1.77-1.71-4.19-4.3-8.13-8.78-12.31-13a5.41,5.41,0,0,1-2.41-1.24c-4-3.5-7.81-7.21-11.48-11-5.46-4.43-11-8.81-16.38-13.28-4.44-3.66-8.52-7.74-12.59-11.83l-1-1c-6.4-4.7-12.8-10.09-17.69-16.33-3.17-2.59-6.44-5.07-9.84-7.37-6.36-4.28-13.79-6.62-20.08-11-6.63-4.57-10.46-11.16-13.91-18.25A55.54,55.54,0,0,0,889,619.33c-6.11-5.14-12.61-9.88-18.16-15.64a78,78,0,0,1-12.74-18.42c-7.73-14.85-12.53-30.54-10.76-47.38,1.9-18,8.79-34.68,13.49-52,1.5-5.52,3.18-10.45,6.24-14.93a5.66,5.66,0,0,1,1.46-2c.62-.76,1.28-1.51,2-2.25,1.74-1.78,3.61-3.39,5.52-5,2.54-8.39,5.63-16.95,11.57-22.85s14.36-8.35,21.46-12.53l3.7-3.57a5.36,5.36,0,0,1,2.39-5.47l6-4,.13-.08a5.88,5.88,0,0,1,.86-1.14l.3-.28a56.64,56.64,0,0,1,6.64-8.71,65.33,65.33,0,0,1,12.5-9.54,117.79,117.79,0,0,1,21.82-11.11c2.33-2.18,4.67-4.3,7-6.36a5.65,5.65,0,0,1,1.71-1.05c10.21-9.09,20.39-18.22,30.84-27,23.11-19.45,53.32-31.79,67.9-59.69,3.29-6.31,5.61-13.11,9.27-19.24a42.87,42.87,0,0,1,8.74-10.4,4.6,4.6,0,0,1,1.48-3.27c12.36-12.17,26.31-22.61,38.52-35,9.54-9.64,17.38-20.78,26.94-30.43a125.77,125.77,0,0,1,28.08-21.42,5.51,5.51,0,0,1,3.16-3.15,78.09,78.09,0,0,1,8.24-2.51c24.36-10.73,51.73-14.36,78.2-11.67l.37.06a4.68,4.68,0,0,1,3.1-1.06,4.55,4.55,0,0,1,4.55,3.25c14-.7,28.06-1.53,41.63,1.59A41,41,0,0,1,1351,176.34a108.65,108.65,0,0,1,10.4,6.73L1366,175V0Z"
transform="translate(7)" />
<path class="d" d="M1034.5,770.5a125.59,125.59,0,0,0-17-32c-12.32-16.72-25.68-25.84-33-31-6-4.23-59.88-42.55-100-90-13.64-16.14-20.57-24.48-26-38-15-37.48-3.73-73.65,0-85,8.68-26.45,23-43.26,35-57,19-21.82,33.56-29.9,67-54,33.68-24.27,55.39-39.91,77-60,40.56-37.69,35.94-49.35,81-96,34.18-35.39,51.27-53.08,79-65,7.79-3.35,76-31.44,140,2a142.06,142.06,0,0,1,31,22l7.5,7.5"
transform="translate(7)" />
</g>
<polyline class="c" points="1373 175 1373 184.22 1370.37 179.61" />
</svg>

Svg fill animation for the given path

I am trying to animate an arrow from left to right.The code of my arrow's path is given below:
<svg id="svg_circle" width="100%" height="100%" viewBox = '0 0 450 400'>
<g transform = "translate(0,0)">
<path class="path" stroke="#F0F0F0" fill="#fff" stroke-width="1" opacity="1" d="m34.97813,21.70979l-33.55223,0.47088l-0.0394,-13.57138l34.2665,-0.47295l-0.0208,-7.14282l14.50618,14.42226l-14.95643,15.04345l-0.20382,-8.74944z" id="svg_1">
<animate id="project_anim1" attributeName="fill" from="#fff" to="#4DAF4C" begin="1s" dur="1s" fill="freeze" repeatCount="1"></animate>
</path>
</g>
</svg>
The above is the svg path content of my arrow.
Kindly anyone help me how to fill the path from left to right. Waiting for quick response
You can do this by just animating the <stop>s in a <linear gradient>.
<svg id="svg_circle" width="100%" height="100%" viewBox = '0 0 450 400'>
<defs>
<linearGradient id="left-to-right">
<stop offset="0" stop-color="#4DAF4C">
<animate dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
<stop offset="0" stop-color="#fff">
<animate dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<path class="path" stroke="#F0F0F0" fill="url(#left-to-right)" stroke-width="1" opacity="1" d="m34.97813,21.70979l-33.55223,0.47088l-0.0394,-13.57138l34.2665,-0.47295l-0.0208,-7.14282l14.50618,14.42226l-14.95643,15.04345l-0.20382,-8.74944z" id="svg_1" />
</svg>
How this works is that we have a linear gradient representing an abrupt change from green to white. The <animation> elements move the position, of that abrupt change, from the left of the arrow (offset=0) to the right (offset="1").
Note that SVG <animate> elements will not work in IE. If you need to support IE, you will need to use the FakeSmile library or use a different method (such as a JS animation library).
Building upon andreas' answer. You can cover your arrow with a shape that is animated to uncover it.
<svg id="svg_circle" width="450" height="400" viewBox='0 0 450 400'>
<path class="path" stroke="#F0F0F0" fill="#fff"
stroke-width="1" opacity="1" id="svg_1"
d="m34.97813,21.70979l-33.55223,0.47088l-0.0394,
-13.57138l34.2665,-0.47295l-0.0208,-7.14282
l14.50618,14.42226l-14.95643,15.04345l-0.20382,
-8.74944z">
<animate id="project_anim1" attributeName="fill"
from="#fff" to="#4DAF4C" begin="0s" dur="3s"
fill="freeze" repeatCount="indefinite" />
</path>
<rect x="0" y="0" width="53" height="34" fill="#fff">
<animate attributeType="XML" attributeName="x"
from="0" to="53" begin="0s" dur="3s"
repeatCount="indefinite" />
<animate attributeType="XML" attributeName="width"
from="53" to="0" begin="0s" dur="3s"
repeatCount="indefinite" />
</rect>
</svg>
I don't think this is possible with the fill attribute. But instead, you can invert your SVG path to a rectangle with a triangle like hole. Now you just need a second element behind that path, where you can simply animate the scale in x-direction, to fill the hole from left to right.
Here is an image showing the technique:
An here is a working example:
<svg width="100%" height="100%" viewBox='0 0 450 400'>
<rect x="0" y="0" width="1" height="22" style="fill: black;" >
<animateTransform attributeName="transform" type="scale" from="1 1" to="50 1" begin="0s" dur="2s" repeatCount="indefinite" />
</rect>
<path fill="#ffffff" d="M0,0v29.8h86V0H0z M6.5,25V5.5L48.8,25H6.5z"/>
</svg>
Note: The answer was updated from triangle to arrow, I won't update my answer as the technique is the same for every shape.
<svg id="svg_circle" width="100%" height="100%" viewBox = '0 0 450 400'>
<defs>
<linearGradient id="left-to-right">
<stop offset="0" stop-color="#4DAF4C">
<animate dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
<stop offset="0" stop-color="#fff">
<animate dur="2s" attributeName="offset" fill="freeze" from="0" to="1" />
</stop>
</linearGradient>
</defs>
<path class="path" stroke="#F0F0F0" fill="url(#left-to-right)" stroke-width="1" opacity="1" d="m34.97813,21.70979l-33.55223,0.47088l-0.0394,-13.57138l34.2665,-0.47295l-0.0208,-7.14282l14.50618,14.42226l-14.95643,15.04345l-0.20382,-8.74944z" id="svg_1" />
</svg>

SVG radialGradient spreadMethod not rendering properly

I'm just learning the SVG format and am trying to create a radial gradient with a reflect spreadMethod, but my browsers (Chrome, Firefox, IE) all seem to be rendering it incorrectly. As you can see in the screenshot below from the MDN gradients tutorial page, only the default value, Pad, seems to work. The left, titled "Screenshot" is how they're stating it should look and the right, titled "Live sample" is how my browser actually renders it. repeat and reflect have hard, non-gradient edges.
It also behaves this way in my own attempts. Here is the code from the "Live Sample":
<svg width="220" height="220" version="1.1" xmlns="http://www.w3.org/2000/svg">
<defs>
<radialGradient id="GradientPad" cx="0.5" cy="0.5" r="0.4" fx="0.75" fy="0.75" spreadMethod="pad">
<stop offset="0%" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</radialGradient>
<radialGradient id="GradientRepeat" cx="0.5" cy="0.5" r="0.4" fx="0.75" fy="0.75" spreadMethod="repeat">
<stop offset="0%" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</radialGradient>
<radialGradient id="GradientReflect" cx="0.5" cy="0.5" r="0.4" fx="0.75" fy="0.75" spreadMethod="reflect">
<stop offset="0%" stop-color="red"></stop>
<stop offset="100%" stop-color="blue"></stop>
</radialGradient>
</defs>
<rect x="10" y="10" rx="15" ry="15" width="100" height="100" fill="url(#GradientPad)"></rect>
<rect x="10" y="120" rx="15" ry="15" width="100" height="100" fill="url(#GradientRepeat)"></rect>
<rect x="120" y="120" rx="15" ry="15" width="100" height="100" fill="url(#GradientReflect)"></rect>
<text x="15" y="30" fill="white" font-family="sans-serif" font-size="12pt">Pad</text>
<text x="15" y="140" fill="white" font-family="sans-serif" font-size="12pt">Repeat</text>
<text x="125" y="140" fill="white" font-family="sans-serif" font-size="12pt">Reflect</text>
</svg>
What can cause this?

Two svg's below each other, only the first visible?

I just started with SVG. simple things like
<svg>
<defs>
<linearGradient id="Gradient">
<stop offset="0" stop-color="white" stop-opacity="0" />
<stop offset="1" stop-color="white" stop-opacity="1" />
</linearGradient>
<mask id="Mask">
<rect x="0" y="0" width="200" height="200" fill="url(#Gradient)" />
</mask>
</defs>
<rect x="0" y="0" width="200" height="200" fill="#222" mask="url(#Mask)" />
</svg>
In this jsfiddle I have this svg with on other one. However, it only shows the one first defined. Can someone explain why and how to fix this ? Thnx!