I have animated the SVG, to give a handwriting effect, I want to make the animation more seamless, as the letter "W" appears in the animation, it makes the other part of the letter appear as well, and I can't decrease the stroke-width as the rest of the part of the letter will not appear completely, please guide me along on what can be done.
As I cant upload the code here its SVG and exceeding more than 35,000 characters, so please do check the CodePen.
HTML Code
<defs>
<clipPath id="clip-path" transform="translate(0 0)">
<path id="w" d="M47.205,44.721c-.1.062-.191.119-.262.169a1.172,1.172,0,0,0-.192.17,1.237,1.237,0,0,0-.155.208,1.71,1.71,0,0,0-.13.285L42.677,55.6q-.354-.956-.708-1.9-.307-.8-.655-1.694t-.623-1.6L38.8,55.6Q37.7,52.9,36.825,50.73q-.37-.925-.739-1.818c-.247-.6-.467-1.134-.662-1.618s-.357-.883-.485-1.2-.2-.508-.223-.57a1.835,1.835,0,0,0-.293-.47,1.326,1.326,0,0,0-.539-.332H36.7a.519.519,0,0,0-.355.4.832.832,0,0,0,.093.539l2.836,7.18,1.077-3.3q-.215-.57-.493-1.247t-.532-1.279c-.17-.4-.313-.747-.432-1.04s-.187-.464-.208-.516a1.529,1.529,0,0,0-.223-.409,1.143,1.143,0,0,0-.532-.332h2.711a.5.5,0,0,0-.315.4,1.016,1.016,0,0,0,.07.539l.817,2.033.8-2.2a.886.886,0,0,0,.068-.479q-.039-.2-.347-.293h1.633a2.841,2.841,0,0,0-.254.17,1.007,1.007,0,0,0-.169.161,1.148,1.148,0,0,0-.124.185,2.582,2.582,0,0,0-.116.254l-1.155,3.034,1.556,4.313L45.652,45.6a1.01,1.01,0,0,0,.062-.533.513.513,0,0,0-.355-.346h1.849Z" style="fill: none" />
</clipPath>
</defs>
<g id="w-grp">
<g style="clip-path: url(#clip-path)">
<polyline class="logo-path m-1" id="w-path" points="35.084 43.989 39.663 55.599 38.796 55.599 38.609 55.136 42.916 43.989 38.968 43.989 43.484 55.599 42.677 55.597 42.474 55.101 46.67 43.989" style="fill: none;stroke: #191717;stroke-miterlimit: 10;stroke-width: 3px" />
</g>
</g>
CodePen: https://codepen.io/ToxifiedM/pen/MWKeERr
Linked Question 1: A JQuery Function For SVG, To Execute 2nd Animation As Soon As, 1st Animation Completes?
Linked Question 2: To Control SVG CSS Based Animation Using Jquery?
Linked Question 3: To Control The Speed Of Multiple SVG Elements Using Jquery?
This is how I would do it:
I'm using a polyline element that I am clipping with a V like path. In order to make the W I'm using the clipped polyline twice. I am animating the stroke-dashoffset of the use elements, the second element with a 1s delay
svg{width:300px;border:solid}
use{
stroke-dasharray: 255;
stroke-dashoffset: 255;
animation: dash 1s linear forwards;
}
use:nth-of-type(2){
animation-delay:1s
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
<svg viewBox="30 80 250 150">
<defs>
<clipPath id="clip">
<path id="V" xmlns="http://www.w3.org/2000/svg" d="M52,90L103,210 110,210 160,90 152,90 110,190 66,90 52,90" stroke="black" fill="none" />
</clipPath>
<polyline id="poly" points="58,85 107,203 156,85" stroke="red" fill="none" stroke-width="19" clip-path="url(#clip)" />
</defs>
<use xlink:href="#poly" x="0" />
<use xlink:href="#poly" x="50" />
</svg>
Related
I wanted to animated this dash line diamond but since it path d and I don't know how to make that work... I basically search some stuff like this one. https://codepen.io/MyXoToD/pen/xxrGdR?editors=1100 that I found in article in svg path d but I don't know how it works...Also my problem is just simple.
<svg width="119" height="30" viewBox="0 0 119 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M119 0V25H10.7735L6 29.7735L0.226501 24L6 18.2265L10.7735 23H117V0H119Z" fill="black"/>
</svg>
When it hovers it will animated from creating the diamond to the edge of line... and then it will stays there unless it unhover. Thats it.
Is this what you mean?
The existing path is a filled shape that incorporates the diamond. I had to separate the diamond out into its own path. Then change the rest of the path to a line.
Then when you hover, we apply an animation to the diamond. It gets moved along the line and up to the top right corner.
svg:hover .diamond {
animation: move 0.5s ease-in forwards;
}
#keyframes move {
0% {
transform: translate(0,0);
}
82% {
transform: translate(112px,0);
}
100% {
transform: translate(112px,-24px);
}
}
<svg width="119" height="30" viewBox="0 -6 124 36" fill="none" xmlns="http://www.w3.org/2000/svg">
<!-- the L-shaped path -->
<path fill-rule="evenodd" clip-rule="evenodd" d="M 118,0 V 24 H 6" fill="none" stroke="black" stroke-width="2"/>
<!-- the moving diamond -->
<path fill-rule="evenodd" clip-rule="evenodd" d="M 11.7735,24 L 6,29.7735 L 0.2265,24 L 6,18.2265 L 11.7735,24Z" fill="black" class="diamond"/>
</svg>
Is there any way to decrease svg path thickness? I have following icon in svg format but this icon is made by single path. Adjusting atrributes "fill" or "stroke-width" not working.
What I am trying to do is reduce thickness of visible border by half.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 32 32">
<g>
<path d="M24,14.059V5.584L18.414,0H0v32h24v-0.059c4.499-0.5,7.998-4.309,8-8.941C31.998,18.366,28.499,14.556,24,14.059z M17.998,2.413L21.586,6h-3.588V2.413z M2,30V1.998h14v6.001h6v6.06c-1.752,0.194-3.352,0.89-4.652,1.941H4v2h11.517 c-0.412,0.616-0.743,1.289-0.994,2H4v2h10.059C14.022,22.329,14,22.661,14,23c0,2.829,1.308,5.351,3.349,7H2z M23,29.883 c-3.801-0.009-6.876-3.084-6.885-6.883c0.009-3.801,3.084-6.876,6.885-6.885c3.799,0.009,6.874,3.084,6.883,6.885 C29.874,26.799,26.799,29.874,23,29.883z M20,12H4v2h16V12z" style="/* transform: scale(0.5, 0.5); *//* stroke: black; */"/>
<g>
<polygon points="28,22 24.002,22 24.002,18 22,18 22,22 18,22 18,24 22,24 22,28 24.002,28 24.002,24 28,24 "/>
</g>
</g>
</svg>
Is there any online editor which can do that? Or maybe there is some css tricks that I don't know?
Path thickness is negligible. Your path is not defining the lines you see, it is defining the border of those lines explicitly. You can see what the path describes by adding stroke="red". You can't decrease the thickness of the filled-in polygons by fiddling with the attributes alone. The only thing you can do without completely redoing the path is to use the background-colour stroke to erase part of the filled-in portion, though I'd argue it can't look as good as a hand-crafted icon:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 32 32">
<g>
<path stroke-width="1" stroke="white" d="M24,14.059V5.584L18.414,0H0v32h24v-0.059c4.499-0.5,7.998-4.309,8-8.941C31.998,18.366,28.499,14.556,24,14.059z M17.998,2.413L21.586,6h-3.588V2.413z M2,30V1.998h14v6.001h6v6.06c-1.752,0.194-3.352,0.89-4.652,1.941H4v2h11.517 c-0.412,0.616-0.743,1.289-0.994,2H4v2h10.059C14.022,22.329,14,22.661,14,23c0,2.829,1.308,5.351,3.349,7H2z M23,29.883 c-3.801-0.009-6.876-3.084-6.885-6.883c0.009-3.801,3.084-6.876,6.885-6.885c3.799,0.009,6.874,3.084,6.883,6.885 C29.874,26.799,26.799,29.874,23,29.883z M20,12H4v2h16V12z" style="/* transform: scale(0.5, 0.5); *//* stroke: black; */"/>
<g>
<polygon stroke-width="1" stroke="white" points="28,22 24.002,22 24.002,18 22,18 22,22 18,22 18,24 22,24 22,28 24.002,28 24.002,24 28,24 "/>
</g>
</g>
</svg>
I am trying create some kind of gauge animation. I added two simple gauges inside a rectangel . When I try to rotate a needle it doesn't rotate around its bottom part. Instead it rotates around another point even though I state to rotate around bottom center. What should I do to rotate the needle from bottom? Thanks.
EDIT:
Here is the animation I am trying to achieve
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<style>
#Gaugaetip2 {
animation: dance 2s infinite alternate;
}
#keyframes dance {
100% {
transform-origin: bottom center;
transform: rotate(-25deg);
}
}
</style>
</head>
<body>
<svg width="135px" height="135px" viewBox="0 0 135 135" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>test</title>
<defs>
<path d="M17.6298701,13.9630295 L17.6298701,4.43831169 L15.6298701,4.43831169 L15.6298701,13.9630295 C14.6733943,14.3565661 14,15.2976952 14,16.3961039 C14,17.8485411 15.177433,19.025974 16.6298701,19.025974 C18.0823073,19.025974 19.2597403,17.8485411 19.2597403,16.3961039 C19.2597403,15.2976952 18.5863459,14.3565661 17.6298701,13.9630295 L17.6298701,13.9630295 Z" id="path-1"></path>
<path d="M18.91403,13.9099151 L18.91403,4.38519729 L16.91403,4.38519729 L16.91403,13.9099151 C15.9575542,14.3034517 15.2841598,15.2445808 15.2841598,16.3429895 C15.2841598,17.7954267 16.4615928,18.9728596 17.91403,18.9728596 C19.3664671,18.9728596 20.5439001,17.7954267 20.5439001,16.3429895 C20.5439001,15.2445808 19.8705058,14.3034517 18.91403,13.9099151 L18.91403,13.9099151 Z" id="path-3"></path>
</defs>
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="test" transform="translate(-30.000000, -30.000000)">
<g transform="translate(30.000000, 30.000000)">
<rect id="background" fill="#4BBCE9" x="0" y="0" width="135" height="135" rx="8"></rect>
<g id="Gauge" transform="translate(5.136364, 8.642857)">
<g id="Group-3" transform="translate(0.149351, 0.383117)">
<ellipse id="Oval-3" stroke="#D8D8D8" fill="#FFFFFF" cx="16.6298701" cy="16.3961039" rx="15.7792208" ry="15.7792208"></ellipse>
<mask id="mask-2" fill="white">
<use xlink:href="#path-1"></use>
</mask>
<use id="Gaugaetip2" fill="#D8D8D8" xlink:href="#path-1"></use>
</g>
</g>
<g id="Gauge-Copy-3" transform="translate(95.551948, 9.642857)">
<ellipse id="Oval-3" stroke="#D8D8D8" fill="#FFFFFF" cx="15.7792208" cy="15.7792208" rx="15.7792208" ry="15.7792208"></ellipse>
<mask id="mask-4" fill="white">
<use xlink:href="#path-3"></use>
</mask>
<use id="Gaugetip" fill="#D8D8D8" transform="translate(17.914030, 11.679028) rotate(25.000000) translate(-17.914030, -11.679028) " xlink:href="#path-3"></use>
</g>
</g>
</g>
</g>
</svg>
</body>
</html>
Try adding the transform-origin to the element itself. As this is a fixed property that does not change over time, it shouldn't be part of the keyframes.
#Gaugaetip2 {
animation: dance 2s infinite alternate;
transform-origin: center 84%;
transform-box: fill-box;
}
#keyframes dance {
100% {
transform: rotate(-25deg);
}
}
I also adjusted the origin position a little to stay centered on the round part.
Result: https://jsfiddle.net/dowm6eff/
I want to implement a tooltip. The idea in its most simplicity is to show a rectangular, when hovered on a circle. How can I achieve that?
What I do not want is to show the rectangular when not hovered precisely on the circle.
Please check the example: https://codepen.io/EminDurak/pen/JXOVqv
SVG:
<svg width="800px" height="300px" viewBox="0 0 800 300" xmlns="http://www.w3.org/2000/svg">
<g x="282.7416666666667" y="252.6" width="3" height="3" class="tooltip-container">
<circle cx="200" cy="120" r="20" value="12" class="tooltip-circle"></circle>
<rect x="50" y="30" width="300" height="80" rx="4" ry="4" r="5" value="12" class="tooltip-box"></rect>
<text x="100" y="80" style="fill:black">Shouldn't appear when hovered here</text>
<text x="150" y="160" style="fill:black">Hover the circle</text>
</g>
</svg>
And the CSS (SCSS):
.tooltip-box {
fill: purple;
opacity: 0;
stroke-width: 1px;
}
.tooltip-container {
&:hover > * {
opacity: 1 !important;
}
}
So it turns out that the best solution to this problem is using display:none, instead of opacity:0. At the time of writing the question I had not checked which css selectors work for SVG; didn't think display would be one. But it is.
So this code below works:
<g x="282.7416666666667" y="252.6" width="3" height="3" class="tooltip-container">
<circle cx="200" cy="120" r="20" value="12" class="tooltip-circle"></circle>
<rect x="50" y="30" width="300" height="80" rx="4" ry="4" r="5" value="12" class="tooltip-box"></rect>
</g>
and css:
.tooltip-box {
fill: purple;
opacity: 0;
stroke-width: 1px;
}
.tooltip-container:hover > .tooltip-box {
opacity: 1;
}
Note: The reason I placed the <Text> element was just to indicate what I was trying to do. The main point is that when an svg element is set to display:none, the container <g> element's size is computed accordingly, so as if the svg element is not rendered at all. Then one can set the element to display: block on hovered to container <g> and consequentially be able to exercise, let's say, a tooltip function.
I have a SVG based app that makes heavy use of transformation such as translates, rotates and scales. While I have no issue in Firefox, in Chrome, the transform-origin property is not taken in account. It seems to apply the user-agent default value 0px 0px 0.
Here is an example (JSFiddle):
<svg width="400" height="400">
<defs>
<rect id="shape" width="200" height="200"/>
</defs>
<g transform="translate(100,100)">
<use xlink:href="#shape" style="stroke: lightgray; fill: transparent;"/>
<ellipse cx="100" cy="100" rx="3" ry="3" style="fill: black;"/>
<g transform="translate(0,0) scale(0.5) rotate(45)" style="transform-origin: 100px 100px;">
<use xlink:href="#shape" style="stroke: black; fill: transparent;"/>
</g>
</g>
</svg>
As you can see Chrome applies all transformation from top left corner of the shape regardless of the defined origin while Firefox respects the defined origin.
Am I missing something about how transform-origin works with SVG?
Does anyone actually found a way to fix this without compensating with translates?
I am answering to my own question in order to clarify entirely what is going on with transform-origin properties on the SVG 1.1 transform functions and how to overcome this issue in Chrome 48.
First of all, transform-origin is a pure CSS 3 property, it is not related to SVG 1.1 at all. Despite the fact that transform sounds a lot like transform-origin, they apply to different systems. transform exists in both CSS 3 and SVG 1.1 but have separate implementations. transform-origin only exists in CSS 3 and therefore it is not supposed to influence SVG 1.1. The fact that transform-origin has no influence on SVG in Chrome 48 is expected.
So why transform-origin does apply to SVG in Firefox 44? Well the reason is not exactly clear, but it seems that it is part of the ongoing effort from Mozilla to slowly bring support for SVG 2 in Firefox. Indeed with SVG 2, everything will become a CSS 3 transform (no separate implementation) and SVG will therefore get support for transform-origin. I found out about this in the excellent article about the SVG coordinate systems from Sara Soueidan.
Now how can that be overcome in Chrome 48. It is fairly simple but if you want to apply translate(), scale() and rotate() all the same time, you will still need to calculate the offset induced by the scaling and compensate it in your translation.
As Bobby Orndorff mentioned in his answer, it is actually possible to provide the center of rotation to the rotate() function by providing extra x and y parameters. This is already a great improvement. But unfortunately the scale() function does not support such a thing and will always scale from the top left corner of its parent. Therefore you will still have to correct your translation in order to simulate a scale around a center.
Here is the final solution that works on Chrome 48 and Firefox 44:
<svg width="400" height="400">
<defs>
<rect id="shape" width="200" height="200"/>
</defs>
<g transform="translate(100,100)">
<use xlink:href="#shape" style="stroke: lightgray; fill: transparent;"/>
<ellipse cx="100" cy="100" rx="3" ry="3" style="fill: black;"/>
<g transform="translate(50,50) scale(0.5) rotate(45, 100, 100)">
<use xlink:href="#shape" style="stroke: black; fill: transparent;"/>
</g>
</g>
</svg>
The example is mixed CSS transform-origin with a SVG transform. While CSS transform and SVG transform are similar, there are differences. For example, CSS transform can be 2D and 3D while SVG transform is only 2D. CSS transform rotate function accepts the angle as a number combined with an unit (e.g. degs, grad, rad, turn) while SVG transforms accepts the angle as a number (with implied unit of degrees) along with optional second and third parameters (x, y) representing the origin of rotation.
To get the example to work in FireFox and Chrome, you could use a CSS transform instead of a SVG transform. For example...
<svg width="400" height="400">
<defs>
<rect id="shape" width="200" height="200"/>
</defs>
<g transform="translate(100,100)">
<use xlink:href="#shape" style="stroke: lightgray; fill: transparent;"/>
<ellipse cx="100" cy="100" rx="3" ry="3" style="fill: black;"/>
<g style="transform: translate(0,0) scale(0.5) rotate(45deg); transform-origin: 100px 100px;">
<use xlink:href="#shape" style="stroke: black; fill: transparent;"/>
</g>
</g>
</svg>
To get the example to work in FireFox, Chrome, and IE, you could use the SVG transform rotate function with the optional second and third parameters instead of a CSS transform-origin. For example...
<svg width="400" height="400">
<defs>
<rect id="shape" width="200" height="200"/>
</defs>
<g transform="translate(100,100)">
<use xlink:href="#shape" style="stroke: lightgray; fill: transparent;"/>
<ellipse cx="100" cy="100" rx="3" ry="3" style="fill: black;"/>
<g transform="translate(0,0) scale(0.5) rotate(45,200,200)">
<use xlink:href="#shape" style="stroke: black; fill: transparent;"/>
</g>
</g>
</svg>