Animating an SVG ellipse path with CSS translate - html

I'm kind of new to SVG animation and have been trying to animate an ellipse path in an SVG I designed using the CSS translate function as documented on CSS Tricks
Here is the svg code for the ellipse itself
<ellipse id="halo" class="halo_path" transform="rotate(-71.04 448.99 166.502)" cx="449" cy="166.5" rx="63" ry="234.3" />
What I'm trying to do is get it to rise a couple of pixels and come down (as a loop) but when I added the CSS for the #keyframe:
.halo_path {
transform: rotate(109deg);
fill: none;
stroke: #D9CC29;
stroke-width: 25.0519;
stroke-miterlimit: 10;
transform-origin: center;
animation: move_halo 2s infinite;
animation-direction: alternate-reverse;
}
#keyframes move_halo {
0% {
transform: translate(0, 5px);
}
100% {
transform: translate(0, -10px);
}
}
...what happens in that the animation works but the ellipse path becomes straight like this:
I'd really appreciate if I can get it to animate up and down but at the original angle which I designed the ellipse to look like which was like this:
PS-I'm looking to achieve this without JS or jQuery.

Move the animation to a parent element so it doesn't overwrite the ellipse's transform.
html, body, svg {
width: 100%;
height: 100%;
}
ellipse {
transform: rotate(109deg);
fill: none;
stroke: #D9CC29;
stroke-width: 25.0519;
stroke-miterlimit: 10;
transform-origin: center;
}
.halo_path {
animation: move_halo 2s infinite;
animation-direction: alternate-reverse;
}
#keyframes move_halo {
0% {
transform: translate(0, 5px);
}
100% {
transform: translate(0, -10px);
}
}
<svg viewBox="0 0 1000 400">
<g class="halo_path" >
<ellipse cx="449" cy="166.5" rx="63" ry="234.3" />
</g>
</svg>

Related

CSS - Animate only selected elements svg

I am trying to animate some elements of an image in svg. To test the animation I first tried to insert in the svg only the element to animate
in order to see if the animation works well, it is the case, here is the code :
HTML :
<svg xmlns="http://www.w3.org/2000/svg" width="244" height="149.388" viewBox="-15 -320 244 149.388">
<g id="off" transform="translate(-1090, -390)">
<g transform="translate(-28.904 -320.214)" >
<path id="note-double-1" d="M1114.926,434.328l5.138-22.688,22.647,1.41c-.05.226-.093.412-.133.6q-2.918,12.882-5.824,25.761a5.089,5.089,0,0,1-3.018,3.727,7.907,7.907,0,0,1-9.016-2.153c-2.277-2.776-1.476-6.41,1.8-7.774a7.7,7.7,0,0,1,8.184,1.341c.1.083.205.172.31.245h.067l3.237-14.3c-1.28-.081-2.527-.164-3.772-.245-4.355-.272-8.713-.535-13.066-.821-.412-.029-.524.113-.61.49-1.4,6.229-2.861,12.445-4.2,18.686a5.393,5.393,0,0,1-4.558,4.48,7.783,7.783,0,0,1-8.129-3.455,4.664,4.664,0,0,1,1.414-6.408,7.077,7.077,0,0,1,6.186-.777,8.54,8.54,0,0,1,1.767.758A17.8,17.8,0,0,1,1114.926,434.328Z"/>
</g>
</g>
</svg>
CSS :
#note-double-1 {
/*overflow: hidden;*/
transform: translateY(0px);
animation: float 6s ease-in-out infinite;
}
#keyframes float {
0% {
transform: translateY(0px);
}
50% {
transform: translateY(-10px);
}
100% {
transform: translateY(0px);
}
}
But, when I add all the extra 'path' lines in the svg tag, nothing is displayed. To avoid too long message, here is a jsfiddle link :
https://jsfiddle.net/qsxjwm0u/2/
Thanks for your help,
Have a nice evening

Animating SVG icon on hover

I'm attempting to animate an SVG line icon ONLY on hover. I'd like it to be static when not hovered. I've worked out how to animate the drawing effect, and I can get it kind of working on hover.. however when it's going between the 'from' and 'to' keyframes, the dashes get smaller and it doesn't create the smooth drawing effect I was hoping for. I am doing this purely HTML/CSS.
.bell_line:hover {
animation: draw 3s linear forwards;
}
#keyframes draw {
from {
stroke-dashoffset:92;
stroke-dasharray: 92;
}
to {
stroke-dashoffset:0;
stroke-dasharray: 0;
}
}
<div class="bell_line" style="margin-left: 100px;margin-top: 100px;">
<svg class="bell_line" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60.85 38.83">
<g data-name="bell_line" fill="none" stroke="#000" stroke-linecap="round" stroke-miterlimit="10">
<path class="bell_line" d="M18.43 28.41l5.38-14.11v-3a5.62 5.62 0 0111.23 0v3l5.33 14.11zM29.38 5.67V.5M29.38 33.2v5.13"/>
</g>
</svg>
</div>
Would transition solve your issue? I usually find it a simpler solution for hover states.
Your css would end up looking like this,
.bell_line {
fill: none;
stroke: black;
stroke-dashoffset: 0;
stroke-dasharray: 0;
transition: stroke-dashoffset 2s ease;
}
.bell_line:hover {
stroke-dashoffset: 92;
}
OR if you want to animate two states (in your case draw off draw on) you will need to create an animation that draws off the dashoffet by its halfway point, then redraws it by it's completion.
Like so,
#keyframes draw {
0% {
stroke-dashoffset: 0;
}
50% {
stroke-dashoffset: 90;
}
100% {
stroke-dashoffset: 180;
}
}
.bell_line {
fill: none;
stroke: black;
stroke-dashoffset: 0;
stroke-dasharray: 90;
}
.bell_line:hover {
animation: draw 2s linear forwards;
}
Here we only animate the dashoffset to produce the animation effect then reset the
Here's a working example,
https://stackblitz.com/edit/react-bell-line
https://react-bell-line.stackblitz.io
Also just be mindful that the hover state is on the path. You could always make the hover state on the svg then point to the path.
svg:hover > .bell_line
This would just mean you can create a larger area to target with the mouse.

CSS keyframes (animation) not functioning in safari

I am currently facing some issues with CSS's #keyframes, as they do not seem to work to work on Safari browser. They are working fine on Chrome, though.
I have checked with the list of WebKit CSS extensions, but I do not seem to have any luck with it.
.app-loading {
}
.app-loading .spinner {
height: 200px;
width: 200px;
animation: rotate 2s linear infinite;
-webkit-animation: rotate 2s linear infinite;
transform-origin: center center;
-webkit-transform-origin: center center;
position: absolute;
top: 0;
bottom: 10;
margin: auto;
}
.app-loading .spinner .path {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
-webkit-animation: dash 1.5s ease-in-out infinite;
stroke-linecap: round;
stroke: #ddd;
}
#keyframes rotate {
100% {
transform: rotate(360deg);
}
}
#-webkit-keyframes rotate {
100% {
-webkit-transform: rotate(360deg);
}
}
#keyframes dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}
#-webkit-keyframes dash {
0% {
stroke-dasharray: 1, 200;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -35px;
}
100% {
stroke-dasharray: 89, 200;
stroke-dashoffset: -124px;
}
}
<div class="app-loading">
<svg class="spinner" viewBox="25 25 50 50">
<circle class="path" cx="50" cy="50" r="20" fill="none" stroke-width="2" stroke-miterlimit="10" />
</svg>
</div>
I have also created a demo on JSfiddle.
I understand there are many similar questions out there, but none of them seem to be solving the issue I am facing right now:
1) CSS Keyframe animations safari
2) CSS3 animation not working in safari
Would appreciate some help over here. Thanks!
EDIT 1:
What other things I've tried - replacing the -webkit-animation shorthand with the below
-webkit-animation-name: rotate;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-webkit-animation-fill-mode: infinite;
In Safari the shorthand notation does not work.
So this will not work :
-webkit-animation: rotate 2s linear infinite;
Instead try writing your animation in full form like this :
-webkit-animation-name: rotate;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-timing-function: linear;
-webkit-animation-fill-mode: infinite;
Do the same to your other animation as well and see if it works
I faced the same problem with Safari, using expanded properties for Keyframes, and what fixed the problem for me was using the absolute strict shorthand definition:
/* #keyframes duration | timing-function | delay |
iteration-count | direction | fill-mode | play-state | name */
animation: 3s ease-in 1s 2 reverse both paused slidein;
Note that the keyframe name is at the end of the definition, I think that could be the problem.
Source: https://developer.mozilla.org/en-US/docs/Web/CSS/animation
Please also note that recent versions of Safari don't use -webkit- prefix so there's no need to add that if your platform doesn't aim for retrocompatibility.

Css rotate element 360 back and forth

As the question says I'd like to rotate an icon 360 degrees one way the rotate back the other repeatedly. Going one direction is easy enough what I don't understand is stopping and going the other direction.
#loading {
-webkit-animation: rotation 2s infinite linear;
}
#-webkit-keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
}
}
<i id="loading" class="material-icons">autorenew</i>
I have tried creating another rotation going the other direction but it doesn't seem to apply.
#-webkit-keyframes rotationBackwards {
from {
-webkit-transform: rotate(359deg);
}
to {
-webkit-transform: rotate(0deg);
}
}
Transformation doesn't apply on inline elements. You have to make your element a block-level element instead (See Transformable Elements on the specifications - If you include the Martial Icons, this will be set by default).
The Animation itself can simply be done with a rotation to 360 degrees for the first half (50%) and a rotation back to 0 degrees for the second half. Mind that the duration of the animation splits into both directions (given your 2s animation, every direction will take 1s).
#loading {
display: inline-block;
animation: rotation 2s infinite linear;
}
#keyframes rotation {
50% {
transform: rotate(360deg);
}
100% {
transform: rotate(0deg);
}
}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<i id="loading" class="material-icons">autorenew</i>
Here is another idea by simply using alternate value of animation-direction and by keeping your initial animation:
#loading {
animation: rotation 2s infinite linear alternate;
}
#keyframes rotation {
/*from {
transform: rotate(0deg); no needed to define this
}*/
to {
transform: rotate(360deg);
}
}
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<i id="loading" class="material-icons">autorenew</i>

SVG text with ‘stroke-dashoffset’ CSS animation not working in Firefox

The following animation works fine in Chrome and Opera, but it doesn't work in Mozilla Firefox. I can't figure out why.
Can someone please help me to fix the problem? What is wrong with my CSS?
#text-logo {
font-family: 'Shrikhand', cursive;
stroke-dashoffset: 100%;
stroke-dasharray: 100%;
-moz-animation: draw 8s forwards ease-in;
-webkit-animation: draw 8s forwards ease-in;
animation: draw 8s forwards ease-in;
background-clip: text;
}
#keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
#-webkit-keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
#-moz-keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
<div class="draw_text">
<svg width="1092" height="220">
<text x="150" y="200" fill="#fff" stroke="#333" id="text-logo" stroke-width="2" font-size="95">WHO I AM ?</text>
</svg>
</div>
Units have to match in Firefox so if the base is a percentage unit then the animated value must be in percentages too.
There's no such thing as a -moz-animation or -moz-keyframes and any prefixed animations should be placed before the unprefixed version. I've fixed that too below.
#text-logo {
font-family: 'Shrikhand', cursive;
stroke-dashoffset: 100%;
stroke-dasharray: 100%;
-webkit-animation: draw 8s forwards ease-in;
animation: draw 8s forwards ease-in;
background-clip: text;
}
#-webkit-keyframes draw {
100% {
stroke-dashoffset: 0%;
}
#keyframes draw {
100% {
stroke-dashoffset: 0%;
}
}
}
<div class="draw_text">
<svg width="1092" height="220">
<text x="150" y="200" fill="#fff" stroke="#333" id="text-logo" stroke-width="2" font-size="95">WHO I AM ?</text>
</svg>
</div>
Setting stroke-dashoffset: 100% looks like a neat thing, but 100% of what? The canonical definition is:
If a percentage is used, the value represents a percentage of the current viewport …
… the percentage is calculated as the specified percentage of sqrt((actual-width)**2 + (actual-height)**2))/sqrt(2).
Firefox seems to not implement that. Setting px lengths makes it work:
#text-logo {
font-family: 'Shrikhand', cursive;
stroke-dashoffset: 1114px;
stroke-dasharray: 1114px;
-moz-animation: draw 8s forwards ease-in;
-webkit-animation: draw 8s forwards ease-in;
animation: draw 8s forwards ease-in;
background-clip: text;
}
#keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
#-webkit-keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
#-moz-keyframes draw {
100% {
stroke-dashoffset: 0;
}
}
<div class="draw_text">
<svg width="1092" height="220">
<text x="150" y="200" fill="#fff" stroke="#333" id="text-logo" stroke-width="2" font-size="95">WHO I AM ?</text>
</svg>
</div>