Using CSS animation, I am adding a 'wobble' effect to each letter in a word. Each letter is made up of an SVG group <g>. However, as you can see in the example, the effect gets more extreme with each letter, whereas I want a consistent 'wobble' per letter (the same effect on each letter). How can this be acheived?
Note: I have not included the SVG source code, to keep the question tidy. It can be seen in the example if needed.
Thanks.
SCSS
// Logo
.logo {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
z-index: 1;
width: 260px;
display: block;
// SVG
svg {
display: block;
width: 100%;
overflow: visible;
g {
fill: transparent;
transition: all 300ms ease-in-out;
#keyframes wobble {
0% { transform: rotate(0) translate3d(0, 0, 0) }
25% { transform: rotate(2deg) translate3d(1px, 0, 0) }
50% { transform: rotate(-1deg) translate3d(0, -1px, 0) }
75% { transform: rotate(1deg) translate3d(-1px, 0, 0) }
100% { transform: rotate(-2deg) translate3d(-1px, -1px, 0) }
}
animation-duration: 400ms;
animation-iteration-count: infinite;
animation-fill-mode: none;
animation-name: wobble;
animation-timing-function: ease-in-out;
path {
fill: red;
}
}
}
}
Example
I could not figure out how to do it with SVGs - I did manage to come up with something similar to your requirement.
Part of the solution involved using a center point for the rotation:
transform-origin: center;
See demo below
#my-logo div {
display: inline-block;
color: red;
font-size: 60px;
font-family: arial;
font-weight: bolder;
text-transform: uppercase;
fill: transparent;
transition: all 300ms ease-in-out;
transform-origin: center;
animation-duration: 400ms;
animation-iteration-count: infinite;
animation-fill-mode: none;
animation-name: wobble;
animation-timing-function: ease-in-out;
}
#keyframes wobble {
0% {
transform: rotate(0) translate3d(0, 0, 0);
}
25% {
transform: rotate(2deg) translate3d(1px, 0, 0);
}
50% {
transform: rotate(-1deg) translate3d(0, -1px, 0);
}
75% {
transform: rotate(1deg) translate3d(-1px, 0, 0);
}
100% {
transform: rotate(-2deg) translate3d(-1px, -1px, 0);
}
}
<div id="my-logo">
<div>o</div>
<div>u</div>
<div>t</div>
<div>r</div>
<div>a</div>
<div>g</div>
<div>e</div>
<div>
<!-- also works with images -->
<img src="http://placekitten.com/100/100" />
</div>
</div>
Related
I'm just animating a simple text, then, after some time, I want it to disappear, however, a few issues appear:
When it first fades in, you can see that the opacity value isn't respected at all, the text appears almost out of nowhere.
When it fades out, you can see that the movement is weird and the opacity transition runs after the movement.
#container {
width: 960px;
height: 200px;
border: 1px solid black;
position: absolute;
}
#message {
position: relative;
z-index: 2;
color: black;
font-size: 18px;
opacity: 0;
top: 60px;
left: 100px;
transform: translate3d(0, -25px, 0);
animation: showMessage 1.5s ease 1.5s forwards, hideMessage 1.5s ease 4s forwards;
}
#keyframes showMessage {
0% {
opacity: 0;
transform: translate3d(0, -25px, 0);
}
100% {
opacity: 100;
transform: translate3d(0, 0, 0);
}
}
#keyframes hideMessage {
0% {
opacity: 100;
transform: translate3d(0, 0, 0);
}
100% {
opacity: 0;
transform: translate3d(-25px, 0, 0);
}
}
<div id="container">
<div id="message">
Hey, look at me!
</div>
</div>
What gives? If I remove the second animation, everything comes back to normal.
The property opacity goes from 0 to 1, so the change is happening almost instantly. About the weird movement when leaving, seems fine to me.
#container {
width: 960px;
height: 200px;
border: 1px solid black;
position: absolute;
}
#message {
position: relative;
z-index: 2;
color: black;
font-size: 18px;
opacity: 0;
top: 60px;
left: 100px;
transform: translate3d(0, -25px, 0);
animation: showMessage 1.5s ease 1.5s forwards, hideMessage 1.5s ease 4s forwards;
}
#keyframes showMessage {
0% {
opacity: 0;
transform: translate3d(0, -25px, 0);
}
100% {
opacity: 1;
transform: translate3d(0, 0, 0);
}
}
#keyframes hideMessage {
0% {
opacity: 1;
transform: translate3d(0, 0, 0);
}
100% {
opacity: 0;
transform: translate3d(-25px, 0, 0);
}
}
<div id="container">
<div id="message">
Hey, look at me!
</div>
</div>
Check this code, I hope this will help you.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
#container {
width: 960px;
height: 200px;
border: 1px solid black;
position: absolute;
}
#message {
position: relative;
z-index: 2;
color: black;
font-size: 18px;
opacity: 0;
top: 60px;
left: 100px;
transform: translate3d(0, -25px, 0);
animation-name: showMessage;
animation-duration: 3s;
animation-delay: 500ms;
animation-direction: alternate;
}
#keyframes showMessage {
0% {
opacity: 0;
transform: translate3d(0, -55px, 0);
}
50% {
opacity: 100;
transform: translate3d(0, 0, 0);
}
100%{
opacity: 0;
transform: translate3d(-65px, 0, 0);
}
}
#keyframes hideMessage {
0% {
opacity: 100;
transform: translate3d(0, 0, 0);
}
100% {
opacity: 0;
transform: translate3d(-65px, 0, 0);
}
}
</style>
</head>
<body>
<div id="container">
<div id="message">
Hey, look at me!
</div>
</div>
</body>
</html>
I have a span element and can not use another. Through this span element I have to achieve spinner/loader functionality and I want behavior looks like given below-
https://codepen.io/supah/pen/BjYLdW
Following is my code which is not working as expected:
<span class="spinner"></span>
.spinner{
display: block;
border-radius: 8em;
width: 8em;
height: 8em;
display: inline-block;
animation: dash 2.0s ease-in-out infinite;
}
#keyframes dash {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
50% {
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
Can any one help me where I am lacking?
Not sure what you were doing with spinner--wholePageWithVeil. But, it's not necessary. The bit you were missing was giving the border a width and style.
body {
background-color: #008;
}
.spinner {
animation: spin 1s infinite ease-in-out;
// animation: dash 2s infinite ease-in-out;
border-radius: 50%;
border-top: 2px solid #fff;
display: inline-block;
height: 2em;
margin: calc(50vh - 1em) calc(50vw - 1em);
width: 2em;
}
#keyframes spin {
100% {
-webkit-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#keyframes dash {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
50% {
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
<span class="spinner"></span>
This is to Easy.
You need to modified some css, give stroke: #fff; into spinner class.
Please check and let me know further clarificaion.
Hope this help.
html, body {
height: 100%;
background-image: linear-gradient(-105deg, #009acc, #363795);
}
.spinner {
animation: rotate 2s linear infinite;
z-index: 2;
position: absolute;
top: 50%;
left: 50%;
margin: -25px 0 0 -25px;
width: 50px;
height: 50px;
stroke: #fff;
}
.path {
stroke: hsl(210, 70, 75);
stroke-linecap: round;
animation: dash 1.5s ease-in-out infinite;
}
#keyframes rotate {
100% {
transform: rotate(360deg);
}
}
#keyframes dash {
0% {
stroke-dasharray: 1, 150;
stroke-dashoffset: 0;
}
50% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -35;
}
100% {
stroke-dasharray: 90, 150;
stroke-dashoffset: -124;
}
}
<svg class="spinner" viewBox="0 0 50 50">
<circle class="path" cx="25" cy="25" r="20" fill="none" stroke-width="5"></circle>
</svg>
Yes you can also create with pure css like that.
Hope this help.
.lds-ring {
display: inline-block;
position: relative;
width: 64px;
height: 64px;
}
.lds-ring span {
box-sizing: border-box;
display: block;
position: absolute;
width: 51px;
height: 51px;
margin: 6px;
border: 6px solid #fff;
border-radius: 50%;
animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
border-color: #000 transparent transparent transparent;
}
.lds-ring span:nth-child(1) {
animation-delay: -0.45s;
}
.lds-ring span:nth-child(2) {
animation-delay: -0.3s;
}
.lds-ring span:nth-child(3) {
animation-delay: -0.15s;
}
#keyframes lds-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<div class="lds-ring">
<span></span>
<span></span>
<span></span>
<span></span>
</div>
Yes, you need to change animation css like: animation: lds-ring 1.2s cubic-bezier(0.5, 0.5, 0.5, 0.5) infinite;
Hope this help.
span {
box-sizing: border-box;
display: block;
position: absolute;
width: 51px;
height: 51px;
margin: 6px;
border: 6px solid #fff;
border-radius: 50%;
animation: lds-ring 1.2s cubic-bezier(0.5, 0.5, 0.5, 0.5) infinite;
border-color: #000 #000 #000 transparent;
}
#keyframes lds-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<span></span>
The CSS animation commands are working perfectly but you can not see it. you need an image because you are not using <svg> and <circle> as they use in the example you have attached.
Note that the width and height of .spinner class should be the width and height of the spinner image.
Based on your code:
LIVE DEMO
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!--remove comment to use jquery-->
<!--<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>-->
<style>
.spinner {
vertical-align: middle;
width: 128px;
height: 128px;
display: inline-block;
margin-right: 5px;
border-radius: 2em;
-webkit-box-sizing: border-box;
border-top-color: #fff;
-webkit-animation: spin 1s infinite linear;
animation: spin 1s infinite linear;
}
.spinner--wholePageWithVeil{
display: block;
border-radius: 8em;
width: 8em;
height: 8em;
display: inline-block;
animation: dash 2.0s ease-in-out infinite;
}
#-webkit-keyframes spin {
100% {
-webkit-transform: rotate(360deg);
}
}
#keyframes spin {
100% {
-moz-transform: rotate(360deg);
-o-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#keyframes dash {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
50% {
-webkit-transform: rotate(180deg);
transform: rotate(180deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
</style>
</head>
<body>
<span class="spinner" [class.spinner--wholePageWithVeil]="wholePageWithVeil">
<img src="http://www.pbrennan.net/wp-content/uploads/2014/03/ic_progress.png" alt="">
</span>
</body>
</html>
I have this code: jsfiddle
The animation of the circle works fine in Firefox but fails to work smoothly in Chrome.
If I remove animation delay and duration from span element, like here, the circle is animated like it should.
What I'm doing wrong?
HTML:
<div class="box">
<div class="circle first">
<span>Lorem Ipsum</span>
</div>
</div>
CSS:
.circle {
position: absolute;
top: 50px;
left: 150px;
display: block;
border-radius: 50%;
-webkit-transition: box-shadow .25s;
transition: box-shadow .25s;
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
// animation
-webkit-clip-path: circle(0 at 50% 50%);
clip-path: circle(0 at 50% 50%);
-webkit-animation-name: scale-up;
animation-name: scale-up;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-transition-timing-function: cubic-bezier(0, 0, .2, 1);
transition-timing-function: cubic-bezier(0, 0, .2, 1);
-webkit-animation-duration: 1s;
animation-duration: 1s;
background-color: #323232;
}
.circle span {
position: absolute;
top: 20px;
right: 50%;
display: block;
background-color: green;
padding: .4em .6em .3em;
webkit-transform: translateX(100%);
transform: translateX(100%);
-webkit-animation-name: slide-left;
animation-name: slide-left;
-webkit-animation-duration: 1.5s;
animation-duration: 1.5s;
-webkit-animation-delay: 1.5s;
animation-delay: 1.5s;
}
.first {
width: 17em;
height: 17em;
-webkit-animation-delay: .5s;
animation-delay: .5s;
box-shadow: 0 0 0 1.6em rgba(32, 32, 32, .1);
}
// Scale up
#-webkit-keyframes scale-up {
0% {
-webkit-clip-path: circle(0 at 50% 50%);
clip-path: circle(0 at 50% 50%);
}
99% {
-webkit-clip-path: circle(60% at 50% 50%);
clip-path: circle(60% at 50% 50%);
}
100% {
-webkit-clip-path: none;
clip-path: none;
}
}
#keyframes scale-up {
0% {
-webkit-clip-path: circle(0 at 50% 50%);
clip-path: circle(0 at 50% 50%);
}
99% {
-webkit-clip-path: circle(60% at 50% 50%);
clip-path: circle(60% at 50% 50%);
}
100% {
-webkit-clip-path: none;
clip-path: none;
}
}
#-webkit-keyframes slide-left {
0% {
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
#keyframes slide-left {
0% {
-webkit-transform: translateX(100%);
transform: translateX(100%);
}
100% {
-webkit-transform: translateX(0);
transform: translateX(0);
}
}
Hope I can help you with this solution: Actually, clip-path animation fails because of span that deforms the circle shape. A solution may be to extract span from its parent (circle) and move it directly into .box container. So, span become sibling of circle. Now, the circle clip-path recovered its regular shape. Then, by defining style to .box element, we also define a new container for the span that is able move following previous locations. here is the code: https://jsfiddle.net/nesquimo/jn3dnuhm/13/
.box{
position: relative;
top: 50px;
left: 150px;
width: 17em;
height: 17em;
}
.circle {
position: absolute;
display: block;
border-radius: 50%;
-webkit-transition: box-shadow .25s;
transition: box-shadow .25s;
-webkit-transform: translate3d(0,0,0);
transform: translate3d(0,0,0);
// animation
-webkit-clip-path: circle(0 at 50% 50%);
clip-path: circle(0 at 50% 50%);
-webkit-animation-name: scale-up;
animation-name: scale-up;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-transition-timing-function: cubic-bezier(0, 0, .2, 1);
transition-timing-function: cubic-bezier(0, 0, .2, 1);
-webkit-animation-duration: 1s;
animation-duration: 1s;
background-color: #323232;
}
.circle__band {
position: absolute;
top: 20px;
right: 50%;
opacity: 0;
display: block;
background-color: green;
padding: .4em .6em .3em;
transform: translate3D(100%, 0, 0);
animation-name: slide-left;
animation-fill-mode: forwards;
animation-duration: 1s;
animation-delay: 1.5s;
}
.first {
width: 17em;
height: 17em;
-webkit-animation-delay: .5s;
animation-delay: .5s;
box-shadow: 0 0 0 1.6em rgba(32, 32, 32, .1);
}
// Scale up
#-webkit-keyframes scale-up {
0% {
-webkit-clip-path: circle(0 at 50% 50%);
clip-path: circle(0 at 50% 50%);
}
99% {
-webkit-clip-path: circle(60% at 50% 50%);
clip-path: circle(60% at 50% 50%);
}
100% {
-webkit-clip-path: none;
clip-path: none;
}
}
#keyframes scale-up {
0% {
-webkit-clip-path: circle(0 at 50% 50%);
clip-path: circle(0 at 50% 50%);
}
99% {
-webkit-clip-path: circle(60% at 50% 50%);
clip-path: circle(60% at 50% 50%);
}
100% {
-webkit-clip-path: none;
clip-path: none;
}
}
// Slide left
#-webkit-keyframes slide-left {
0% {
opacity: 1;
transform: translate3D(100%,0,0);
}
100% {
opacity: 1;
transform: translate3D(0,0,0);
}
}
#keyframes slide-left {
0% {
opacity: 1;
transform: translate3D(100%,0,0);
}
100% {
opacity: 1;
transform: translate3D(0,0,0);
}
}
<div class="box">
<div class="circle first">
</div>
<span class="circle__band">Lorem Ipsum</span>
</div>
I am trying to rotate a cube in a three direction. I need to stop the animation at the 3rd Box but its comes to original position. From the 3rd box there is an animation back to the 1st box which I don't want.The animation should stop at 3rd Box. Give some solution.
#spinner div {
position: absolute;
width: 120px;
height: 120px;
border: 1px solid #ccc;
background: rgba(255, 255, 255, 0.8);
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.2);
text-align: center;
line-height: 120px;
font-size: 100px;
}
#spinner .face1 {
-webkit-transform: translateZ(60px);
}
#spinner .face2 {
-webkit-transform: rotateY(90deg) translateZ(60px);
}
#spinner .face3 {
-webkit-transform: rotateY(90deg) rotateX(90deg) translateZ(60px);
}
#-webkit-keyframes spincube {
from, to {} 16% {
-webkit-transform: rotateY(-90deg);
}
33% {
-webkit-transform: rotateY(-90deg) rotateZ(90deg);
}
}
#spinner {
-webkit-animation-name: spincube;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-iteration-count: 1;
-webkit-animation-fill-mode: forwards;
-webkit-animation-duration: 8s;
-webkit-transform-style: preserve-3d;
-webkit-transform-origin: 60px 60px 0;
}
<div id="stage" style="width: 1200px; height: 300px;">
<div id="spinner">
<div class="face1">1</div>
<div class="face2">2</div>
<div class="face3">3</div>
</div>
</div>
Though you had set the animation-fill-mode to forwards (the -webkit prefix should not be a problem as you were trying on Chrome), the animation did not stop at the 3rd box because your to setting (last keyframe) was taking it back to its original state (which shows box 1). To fix this, you can make the last keyframe also hold the same position as at 33% (which is show box 3).
#spinner div {
position: absolute;
width: 120px;
height: 120px;
border: 1px solid #ccc;
background: rgba(255, 255, 255, 0.8);
box-shadow: inset 0 0 20px rgba(0, 0, 0, 0.2);
text-align: center;
line-height: 120px;
font-size: 100px;
}
#spinner .face1 {
-webkit-transform: translateZ(60px);
}
#spinner .face2 {
-webkit-transform: rotateY(90deg) translateZ(60px);
}
#spinner .face3 {
-webkit-transform: rotateY(90deg) rotateX(90deg) translateZ(60px);
}
#-webkit-keyframes spincube {
from {}
16% {
-webkit-transform: rotateY(-90deg);
}
33% {
-webkit-transform: rotateY(-90deg) rotateZ(90deg);
}
to {
-webkit-transform: rotateY(-90deg) rotateZ(90deg);
}
}
#spinner {
-webkit-animation-name: spincube;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-iteration-count: 1;
-webkit-animation-fill-mode: forwards;
-webkit-animation-duration: 8s;
-webkit-transform-style: preserve-3d;
-webkit-transform-origin: 60px 60px 0;
}
<div id="stage" style="width: 1200px; height: 300px;">
<div id="spinner">
<div class="face1">1</div>
<div class="face2">2</div>
<div class="face3">3</di>
</div>
</div>
Or, you could also change your keyframe settings like below. Note that, I have reduced the duration by a third because we are changing the keyframes by a factor of 3.
#-webkit-keyframes spincube {
from {
}
48% { /* factor of 3 since we are changing 33% to 100% or to */
-webkit-transform: rotateY(-90deg);
}
to { /* make the last keyframe show the box 3 */
-webkit-transform: rotateY(-90deg) rotateZ(90deg);
}
}
#spinner {
-webkit-animation-name: spincube;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-iteration-count: 1;
-webkit-animation-fill-mode: forwards;
-webkit-animation-duration: 2.7s; /* reduce total duration by a 3rd */
-webkit-transform-style: preserve-3d;
-webkit-transform-origin: 60px 60px 0;
}
I've tried many different ways to add text to this keyframe animation, but the problem is that it messes up one of the animations when I include the div containing the text. Ideally, I want the text to be center and top or center and top left, but when I get it there, it throws off the last span in the animation. How can I edit the class waitingtext so that it doesn't interfere with the animation?
Site where I got the css
HTML
<div class="main-loading" ng-show="mainloading">
<div class="waitingtext">My text</div>
<span class="main-loading"></span><!--
--><span></span><!--
--><span></span><!--
--><span></span><!--
--><span></span>
</div>
CSS
.waitingtext {
color:#FFF;
position: absolute;
z-index: -1;
line-height: 60px!important;
float: left;
margin-top: 5px;
}
div.main-loading
{
background: #1b7817;
opacity:.9;
position: absolute;
width: 400px;
height: 300px;
top: 50%;
left: 50%;
margin: -150px 0 0 -200px;
text-align: center;
border:1px solid #dcdcdc;-moz-border-radius:6px;-webkit-border-radius:6px;border-radius:6px; padding-left: 5px
}
div.main-loading
{
position: absolute;
height: 300px;
top: 50%;
left: 50%;
line-height: 300px;
text-align: center;
clear: both;
}
.main-loading span
{
display: inline-block;
width: 10px;
height: 10px;
margin: 145px 3px 0;
background: rgba(255,255,255,0.25);
border-radius: 50%;
transform: translateY(0);
-moz-transform: translateY(0);
-webkit-transform: translateY(0);
animation: wave 2s infinite ease-in-out;
-moz-animation: wave 2s infinite ease-in-out;
-webkit-animation: wave 2s infinite ease-in-out;
}
#keyframes wave
{
0%, 60%, 100%
{
background: rgba(255,255,255,0.25);
transform: translateY(0);
-moz-transform: translateY(0);
}
20%
{
background: rgba(255,255,255,0.75);
transform: translateY(13px);
-moz-transform: translateY(13px);
}
40%
{
background: rgba(255,255,255,0.75);
transform: translateY(-13px);
-moz-transform: translateY(-13px);
}
}
#-webkit-keyframes wave
{
0%, 60%, 100%
{
background: rgba(255,255,255,0.25);
transform: translateY(0);
-webkit-transform: translateY(0);
}
20%
{
background: rgba(255,255,255,0.75);
transform: translateY(13px);
-webkit-transform: translateY(13px);
}
40%
{
background: rgba(255,255,255,0.75);
transform: translateY(-13px);
-webkit-transform: translateY(-13px);
}
}
.main-loading span:nth-child(1)
{
animation-delay: 0s;
-moz-animation-delay: 0s;
-webkit-animation-delay: 0s;
}
.main-loading span:nth-child(2)
{
animation-delay: 0.1s;
-moz-animation-delay: 0.1s;
-webkit-animation-delay: 0.1s;
}
.main-loading span:nth-child(3)
{
animation-delay: 0.2s;
-moz-animation-delay: 0.2s;
-webkit-animation-delay: 0.2s;
}
.main-loading span:nth-child(4)
{
animation-delay: 0.3s;
-moz-animation-delay: 0.3s;
-webkit-animation-delay: 0.3s;
}
.main-loading span:nth-child(5)
{
animation-delay: 0.4s;
-moz-animation-delay: 0.4s;
-webkit-animation-delay: 0.4s;
}
This has nothing to do with positioning but everything to do with your CSS selectors
:nth-child() (what you were using) counts all of the children of the parent, including the div you added. What you need is nth-of-type(), which only counts the spans
Demo