I am trying to create an svg file with a circle that has a tapered stroke that fades, meaning the stroke width will be the thickest (say 20px) with the original color and will be the thinnest (say 3px) on the opposite side where the color has faded. I was able to create the circle with color fading with the gradient tool, but I am struggling to figure out how to change the stroke width
Here's the code I have so far, which I created in Photoshop and exported to svg.
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="500" viewBox="0 0 500 500">
<defs>
<style>
.cls-1 {
fill: none;
stroke-width: 20px;
stroke: url(#a);
}
</style>
<linearGradient id="a" x1="255.5" y1="240" x2="255.5" y2="51" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="rgba(96,0,0,1)"/>
<stop offset="1" stop-color="rgba(96,0,0,.1)"/>
</linearGradient>
</defs>
<circle class="cls-1" cx="255.5" cy="255.5" r="184.5"/>
</svg>
Here's an image of what I am trying to do.
Sorry, one more favor. I am trying to create an icon, so it will have four of these circles with different colors, with one fading to the top as shown, another fading to the bottom, and the other two to each of the sides. I will really appreciate it if you can also show me how to rotate :)
Thank you in advance.
Regards,
Mike
I would draw a bigger circle with a hole inside. In this case I'm using a mask. You can also draw a holloed path. In both cases you are using the gradient as a fill not as a stroke
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="500" height="500" viewBox="0 0 500 500">
<defs>
<style>
.cls-1 {
fill: url(#a);
}
</style>
<linearGradient id="a" x1="255.5" y1="240" x2="255.5" y2="51" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="rgba(96,0,0,1)"/>
<stop offset="1" stop-color="rgba(96,0,0,.1)"/>
</linearGradient>
<mask id="m">
<circle id="c1" cx="255.5" cy="255.5" r="184.5" fill="white" />
<circle fill="black" cx="255.5" cy="245.5" r="164.5"/>
</mask>
</defs>
<circle cx="255.5" cy="255.5" r="184.5" class="cls-1" mask="url(#m)" />
</svg>
And this is an example where I'm using a holloed path instead of the masked circle. Please note that in this case I'm centering the path atound the point x=0 y=0.
<svg width="500" height="500" viewBox="-250 -250 500 500">
<defs>
<style>
.cls-1 {
fill: url(#a);
}
</style>
<linearGradient id="a" y1="200" y2="-200" x1="0" x2="0" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="rgba(96,0,0,1)"/>
<stop offset="1" stop-color="rgba(96,0,0,.1)"/>
</linearGradient>
</defs>
<path class="cls-1" d="M184.5,0A184.5,184.5 0 0 1 -184.5,0A184.5,184.5 0 0 1 184.5,0M164.5,-10A164.5,164.5 0 0 0 -164.5,-10A164.5,164.5 0 0 0 164.5,-10"/>
</svg>
I am trying to create an icon, so it will have four of these circles
with different colors, with one fading to the top as shown, another
fading to the bottom, and the other two to each of the sides. I will
really appreciate it if you can also show me how to rotate
The first circle rotates clockwise
<animateTransform
attributeName="transform"
type="rotate"
values="0 150 150;360 150 150"
begin="svg1.click"
dur="10s"
repeatCount="indefinite"
/>
The second circle rotates counterclockwise.
Since the top circle is set to the opacity parameter fill-opacity: 0.5;
then the effect of changing the thickness of the stroke is created
Added gradient animation to both circles:
<animate
attributeName="stop-color"
dur="1.5s"
values="red;yellow;red"
repeatCount="indefinite"
/>
The text Click me has been added for demonstration it can be removed.
Below is the complete code:
.container {
width:50%;
height:50%;
}
svg {
background:black;
}
#path1 {
fill:url(#gradl);
stroke:none;
fill-opacity:1;
}
#path2 {
fill:url(#grad2);
stroke:none;
fill-opacity:0.5;
}
#crc1 {
stroke:none;
fill:black;
}
#txt1 {
fill:url(#grad2);
}
<div class="container">
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 300 300" >
<defs>
<linearGradient id="gradl" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="red" stop-opacity="0.9">
<animate
attributeName="stop-color"
dur="1.5s"
values="red;yellow;red"
repeatCount="indefinite"
/>
</stop>
<stop offset="100%" stop-color="yellow">
<animate
attributeName="stop-color"
dur="1.5s"
values="yellow;red;yellow" repeatCount="indefinite"
/>
</stop>
</linearGradient>
<linearGradient id="grad2" gradientUnits="objectBoundingBox" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="lime">
<animate
attributeName="stop-color"
dur="1.5s"
values="lime;purple;lime"
repeatCount="indefinite"
/>
</stop>
<stop offset="100%" stop-color="purple">
<animate
attributeName="stop-color"
dur="1.5s"
values="purple;lime;purple" repeatCount="indefinite"
/>
</stop>
</linearGradient>
</defs>
<path id="path1" d="M71.9 78.4C90.8 58.1 122.9 50.7 150.6 51.5c26.2 0.7 54.9 10.5 72.8 29.7 16.9 18.1 22.9 45.8 23.4 70.6 0.5 25.1-3.2 54.4-20.7 72.4-18.5 19.1-49.4 24.5-76 24.3-25.4-0.2-54.4-6.3-72.4-24.3C59.5 205.8 53.9 176.5 53 150.8 52.2 125.9 55 96.7 71.9 78.4Z" >
<animateTransform
attributeName="transform"
type="rotate"
values="0 150 150;360 150 150"
begin="svg1.click"
dur="10s"
repeatCount="indefinite"
/>
</path>
<path id="path2" transform="rotate(45 150 150)"
d="M71.9 78.4C90.8 58.1 122.9 50.7 150.6 51.5c26.2 0.7 54.9 10.5 72.8 29.7 16.9 18.1 22.9 45.8 23.4 70.6 0.5 25.1-3.2 54.4-20.7 72.4-18.5 19.1-49.4 24.5-76 24.3-25.4-0.2-54.4-6.3-72.4-24.3C59.5 205.8 53.9 176.5 53 150.8 52.2 125.9 55 96.7 71.9 78.4Z" >
<animateTransform
attributeName="transform"
type="rotate"
values="360 148 148;0 148 148"
begin="svg1.click"
dur="10s"
repeatCount="indefinite" />
</path>
<circle id="crc1" cx="150" cy="150" r="90" />
<text id="txt1" x="80" y="160" font-size="36" font-weight="700" > Click me </text>
</svg>
</div>
I have to write a code that circles should go under some paths with below SVG
<g>
<g>
<path class="st0" d="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
s128.09-48.95,176.91-0.13"/>
</g>
<g>
<path class="st0" d="M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
c-48.89-48.89-128.09-48.95-176.91-0.13"/>
</g>
</g>
<circle r="20" fill="blue">
<animateMotion dur="5s" repeatCount="indefinite"
path="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
s128.09-48.95,176.91-0.13 M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
c-48.89-48.89-128.09-48.95-176.91-0.13" />
https://codepen.io/lzwdct/pen/poRYVXZ
Imagine the paths are like driveway, and the circle passes under the path(like bridge) it should not appear under the bridge.
Is there any way to implement it?
The way SVG mask works is a bit strange. The element it's applied to will only be rendered where the mask is white and where the mask is black (or just not white) it will be hidden. Another strange effect of SVG masks is that if you are animating an element and apply a mask to the element being animated then the mask will move with the element.
To account for the first part is simple, just add a white rect the size of the SVG itself inside the mask and use smaller black shapes to mask. The way to work around the moving mask is to apply the mask not to the element being animated but to a <g> tag that wraps the element(s) being animated.
If you want the circles to go 'under' a section and then 'over' that same section however, then you'll need to do some animating inside the mask as well. In this example I'm using animateTransform inside the mask's rect child (the black part that does the masking) to shrink it after the circles pass 'under' the bridge, you could just as easily use CSS keyframes though.
I suggest strongly that you also cut down the viewbox since your visual elements are so small compared to the available space, in the example I just estimated but the best way is to re-render your graphics in Illustrator and crop the artboard better to your objects.
Also most of the additional markup produced by Illustrator is not needed if the SVG will be inline in HTML. You can lose pretty much everything except the viewBox as shown in my example since those other attributes are mostly only used when the SVG is rendered as an image, hope this helps.
svg {
max-width: 500px;
}
.st0,
.st1 {
fill: none;
stroke: #8ea5ae;
stroke-width: 50;
stroke-miterlimit: 10;
}
.st1 {
stroke-linecap: round
}
.st2 {
fill: none;
stroke: #758992;
stroke-width: 50;
stroke-miterlimit: 10;
}
<svg viewBox="0 0 1015 855">
<mask id="myMask">
<!-- Pixels under white are rendered -->
<rect x="0" y="0" width="1015" height="855" fill="white" />
<!-- Pixels under black are hidden -->
<rect class="moveme" x="315" y="335" height="150" width="150" transform="rotate(45 395 395)">
<animateTransform attributeName="transform"
attributeType="XML"
type="scale"
keyTimes="0; 0.25999; 0.26; 1"
values="1; 1; 0; 0"
dur="5s"
additive="sum"
repeatCount="indefinite"/>
</rect>
</mask>
<path class="st0" d="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
s128.09-48.95,176.91-0.13" />
<path class="st1" d="M683.19,30.7L258.92,454.97c-29.29,29.29-76.78,29.29-106.07,0c-29.29-29.29-29.29-76.78,0-106.07
c29.29-29.29,76.78-29.29,106.07,0" />
<path class="st2" d="M753.9,101.42c0,0-424.26,424.26-424.26,424.26c-68.34,68.34-179.15,68.34-247.49,0s-68.34-179.15,0-247.49
s179.15-68.34,247.49,0" />
<path class="st0" d="M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91 c-48.89-48.89-128.09-48.95-176.91-0.13" />
<path class="st2" d="M329.63,278.19L753.9,702.46c29.29,29.29,76.78,29.29,106.07,0c29.29-29.29,29.29-76.78,0-106.07 s-76.78-29.29-106.07,0" />
<path class="st1" d="M258.92,348.9c0,0,424.26,424.26,424.26,424.26c68.34,68.34,179.15,68.34,247.49,0s68.34-179.15,0-247.49 s-179.15-68.34-247.49,0" />
<!-- Group the circles and apply the mask to the group, not the circles -->
<g mask="url(#myMask)">
<circle r="20" fill="blue">
<animateMotion dur="5s" repeatCount="indefinite" path="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
s128.09-48.95,176.91-0.13 M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
c-48.89-48.89-128.09-48.95-176.91-0.13" />
</circle>
<circle r="20" fill="blue">
<animateMotion dur="5s" repeatCount="indefinite" path="M753.9,101.42c0,0-424.26,424.26-424.26,424.26c-68.34,68.34-179.15,68.34-247.49,0s-68.34-179.15,0-247.49
s179.15-68.34,247.49,0 M329.63,278.19L753.9,702.46c29.29,29.29,76.78,29.29,106.07,0c29.29-29.29,29.29-76.78,0-106.07
s-76.78-29.29-106.07,0" />
</circle>
<circle r="20" fill="blue">
<animateMotion dur="5s" repeatCount="indefinite" path="M683.19,30.7L258.92,454.97c-29.29,29.29-76.78,29.29-106.07,0c-29.29-29.29-29.29-76.78,0-106.07
c29.29-29.29,76.78-29.29,106.07,0 M258.92,348.9c0,0,424.26,424.26,424.26,424.26c68.34,68.34,179.15,68.34,247.49,0s68.34-179.15,0-247.49
s-179.15-68.34-247.49,0" />
</circle>
</g>
<!-- uncomment the rect below to visualize the animation applied to the mask -->
<!-- <rect x="315" y="335" height="150" width="150" fill="#f00" opacity=".1" transform="rotate(45 395 395)">
<animateTransform attributeName="transform"
attributeType="XML"
type="scale"
keyTimes="0; 0.25999; 0.26; 1"
values="1; 1; 0; 0"
dur="5s"
additive="sum"
repeatCount="indefinite"/>
</rect>-->
</svg>
Failing to understand why only one quadrant is showing red color rather than the entire viewable area of the SVG? The same rect outside of use covers the entire area, what am I missing?
svg {
height: 50vmin;
border: solid 1px black;
transform: scale(1, -1);
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -1 2 2">
<defs>
<symbol id="quadrant">
<rect x="-1" y="-1" width="2" height="2" fill="#f00"/>
</symbol>
</defs>
<rect x="-1" y="-1" width="2" height="2" fill="#0f0"/>
<use xlink:href="#quadrant" />
</svg>
The use element doesn't have x or y attributes so it starts at 0,0 and not -1, -1 as the prior rect does.
The symbol doesn't have a viewBox so the symbol displays from 0, 0 to 100%, 100% i.e. 1, 1 (since that's where the root viewBox says 100% maps to).
svg {
height: 50vmin;
border: solid 1px black;
transform: scale(1, -1);
}
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="-1 -1 2 2">
<defs>
<symbol id="quadrant" viewBox="-1 -1 2 2">
<rect x="-1" y="-1" width="2" height="2" fill="#f00"/>
</symbol>
</defs>
<rect x="-1" y="-1" width="2" height="2" fill="#0f0"/>
<use x="-1" y="-1" xlink:href="#quadrant" />
</svg>
The alternative would be to just make the symbol's overflow: visible but I wouldn't recommend it as overflow: visible has terrible performance.
Trying to position a battery indicator within a parent SVG.The SVG <svg viewBox="0 0 24 24"> element has a path for the battery and a text element showing the percentage.Its being positioned with a couple of css transforms and text attributes.The text is correctly positioned when opening in chrome/firefox but goes offshoot in safari.
<text
text-anchor="middle"
dominant-baseline="middle"
style="transform:translate(50%,98%) scale(.2);
font:700 13px sans-serif;fill:#deba78"
>24.2%</text>
Codepen https://codepen.io/niwsa/pen/rNNBKEg?editors=1000
Wrap the <text> element into a <g> element and apply the CSS transform on that, it happens to work currently even in Safari. This way, it's still CSS, so CSS transitions, animations, custom properties, selector based styling, continuous font scaling etc. work.
Instead of translating the text you may give the text some attributes like x and y. Instead of scaling the text you may change the font-size.
For the path you may choose svg transforms like this:
body {
width: 200px;
}
.bg {
fill: #beeb1b;
}
.cap {
fill: #aaa8a9;
}
.trunk {
fill: #231f20;
}
<svg xmlns="http://www.w3.org/2000/svg" tabindex="0" viewBox="0 0 351.33 722" aria-labelledby="bottletitle bottledesc" role="img">
<title id="bottletitle">
Bottle
</title>
<desc id="bottledesc">
Bottle with battery indicator inside
</desc>
<g data-name="Layer 4" class="bg">
<rect width="351.33" height="722" rx="23.33" ry="23.33"/>
</g>
<g data-name="Layer 3" class="cap">
<rect x="146.81" y="60.9" width="57.71" height="73.67"/>
</g>
<g data-name="Layer 2" class="trunk">
<path d="M173,153.25h57.75V223s1.08,25.33,30.41,56c27.06,28.29,35.34,60.33,35,71.33-.21,7,0,324.67,0,324.67s-3.33,7.33-9.33,7.33H117.12s-9-.33-9-6.66v-325s-.33-33,30.34-67c0,0,34.33-32.67,34.33-60.67S173.33,153.63,173,153.25Z" transform="translate(-26.46 -18.67)"/>
</g>
<svg viewBox="0 0 24 24">
<defs>
<linearGradient id="lg" x1="0.5" y1="1" x2="0.5" y2="0">
<stop offset="0%" stop-opacity="1" stop-color="#2ecc71"/>
<stop offset="24.2%" stop-opacity="1" stop-color="#2ecc71"/>
<stop offset="24.2%" stop-opacity="0" stop-color="#2ecc71"/>
<stop offset="100%" stop-opacity="0" stop-color="#2ecc71"/>
<animate attributeName="y2" from="1" to="0" dur="500ms" repeatCount="2s" fill="freeze"/>
</linearGradient>
</defs>
<path fill="url(#lg)" d="M15.67 4H14V2h-4v2H8.33C7.6 4 7 4.6 7 5.33v15.33C7 21.4 7.6 22 8.33 22h7.33c.74 0 1.34-.6 1.34-1.33V5.33C17 4.6 16.4 4 15.67 4z" stroke="#fff" transform="scale(.5,.5) rotate(90,12 12) translate(45,-12)"/>
<text text-anchor="middle" dominant-baseline="middle" style="font:700 2.5px sans-serif;fill:#deba78" x="12" y="23">
24.2%
</text>
</svg>
</svg>
This may be a duplicate of a similar question asked by Ruby several years ago, but following the suggestions posted has not resulted in a solution for me. Of course it could be me that is the problem.
I am trying to generate cycloid curves (circles rotating around other curves) BUT I would like to create the curve of a circle rotating around an ellipse - not a circle.
I can animate a circle to follow an elliptical path.
I can animate a circle to rotate about its center.
I need to do both animations simultaneously, but my object follows a path somewhere else in my viewbox.
html, body, svg {
width: 100%;
height: 100%;
}
<svg viewBox="0 0 700 700">
<path id="OUT" d="M200,250
a220,110 0 1,0 600,0
a220,110 0 1,0 -600,0"
style="fill:none;stroke:#ccc; stroke-width:2" />
<g id="CC">
<circle r=40 cx=200 cy=250 fill="none" stroke="black" stroke- width="2"/>
<g id="C1">
<circle r=5 cx=200 cy=250 fill="green"/>
</g>
<circle cx="240" cy="250" r="3" fill="blue" />
</g>
<animateTransForm
xlink:href="#CC"
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 200 250" to="360 200 250" begin="1s" dur="10s"
additive="sum" />
<animateTransform
xlink:href="#CC"
attributeName="transform"
attributeType="XML"
type="rotate"
mpath xlink:href="#OUT"
from="0 300 250" to="360 300 250"
begin="1s" dur="10s" fill="freeze"
additive="sum"/>
</svg>
Hopefully this will give someone an idea of my effort, and trigger a solution. Many thanks.
www.softouch.on.ca
you just need to use animateMotion to apply line animation on any
shape just set so animation can know in which line it has to walk
because of transform translate issue i manually set transform
translate, it will work without setting transform translate in
circle
i used css key frame animation to rotate small circle and both
animation not working at a time so i added one layer(as <g> tag)
inside main <g> tag
html, body, svg {
width: 100%;
height: 100%;
}
<svg width="500" height="500" viewBox="0 0 1000 1000" >
<def>
<style>
#-webkit-keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
}
}
#extrag{
transform-origin: left;
animation: rotation 5s infinite linear;
transform-origin: 201px 250px;
}
</style>
</def>
<path id="OUT" d="M200,250
a220,110 0 1,0 600,0
a220,110 0 1,0 -600,0"
style="fill:none;stroke:#ccc; stroke-width:2" />
<g id="CC" transform="translate(-190,-245)">
<g id="extrag">
<circle r=40 cx=200 cy=250 fill="none" stroke="black" stroke-width="2"/>
<g id="C1" >
<circle r=5 cx=200 cy=250 fill="green"/>
</g>
<circle cx="240" cy="250" r="3" fill="blue">
</circle>
</g>
<animateMotion
xlink:href="#CC"
attributeName="motion"
attributeType="XML"
additive="sum"
dur="6s"
repeatCount="indefinite">
<mpath xlink:href="#OUT"/>
</animateMotion>
</g>
</svg>