Adding pause to keyframe animation - html

I have this script letting 2 characters move around 360degrees each. Now i have to add a pause of 4 seconds each time both have turned 180degrees. I have tried it with percentages but that doesnt work well. Either the letters will spin too fast or way too slow or the pause is not long enough.
Anyone has a solution for my problem?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Animation</title>
<link rel="stylesheet" type="text/css" href="main.css">
</head>
<body>
<style>
.letter{
height: 80px;
z-index: 99;
position: absolute;
margin-top: 100px
}
.letter1{
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.letter2{
margin-left: 700px;
}
.letter3{
margin-left: 780px;
}
.letter4{
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: linear;
}
.letter5{
margin-left: 940px;
}
.letter6{
margin-left: 1020px;
}
.C {
position: absolute;
margin-left: 730px;
animation: rotC 3s infinite linear;
z-index: 1;
display: inline-block;
}
.P {
position: absolute;
margin-left: 730px;
animation: rotP 3s infinite linear;
z-index: 1;
display: inline-block;
/*animation-delay: move 3s infinite;*/
}
#keyframes rotC {
from {
transform: rotate(0deg)
translate(-130px)
rotate(0deg);
}
to {
transform: rotate(360deg)
translate(-130px)
rotate(-360deg);
}
}
#keyframes rotP {
from {
transform: rotate(0deg)
translate(130px)
rotate(0deg);
}
to {
transform: rotate(360deg)
translate(130px)
rotate(-360deg);
}
}
</style>
<div class="vid"><!-- prycto-->
<img src="geknletters/P.png" alt="p" class="P letter">
<img src="geknletters/R.png" alt="r" class="letter2 letter">
<img src="geknletters/y.png" alt="y" class="letter3 letter">
<img src="geknletters/C.png" alt="c" class="C letter">
<img src="geknletters/T.png" alt="t" class="letter5 letter">
<img src="geknletters/o.png" alt="o" class="letter6 letter">
<video src="051476630-astronaut-doing-ballet-dance-m_H264HD1080.mov" style="position: absolute;
margin: 0;
width: 100%;
height: 100vh;
top:0;
left: 0;" >
</video>
</div>
</body>
</html>
Kind regards,
Jorn Barkhof

You can't stop the animation when the animation started .
There is animation-delay but that delays the start of the animation, but after it's started it runs continuously.
The solution will be Keyframes with No Changes.
For more info please read this link.
https://css-tricks.com/css-keyframe-animation-delay-iterations/
And the Answer to your question.
First thing that you will do is to make the animation to be 14s
since you will need a 4s stop and 3s animate .
3s animate (180deg) + 4s stop (180deg) + 3s animate (360deg) + 4s stop (360deg) = 14s
animation: rotP 14s infinite linear;
animation: rotC 14s infinite linear;
After that you will need to calculate the percentage of the animation.
We will need to use to percentage since we will do the keyframes with no changes.
(3/14)*100 = 21.4% (For 3s) -- (4/14)*100 = 28.6% (For 4s)
(21.4% = 3s) animation and (28.6% = 4s) stop time. For the 14s period of time.
then initialize the percentage
0% + 21.4% = 21.4% [total time 3s] -- since (21.4% = 3s) animation
21.4% + 28.6% = 50% [total time 7s] -- since (28.6% = 4s) stop time
50% + 21.4% = 71.4% [total time 10s]
71.4% + 28.6% = 100% [total time 14s]
.letter{
height: 80px;
z-index: 99;
position: absolute;
margin-top: 100px
}
.letter1{
animation-duration: 2s;
animation-timing-function: linear;
animation-iteration-count: infinite;
animation-direction: alternate;
}
.letter2{
margin-left: 700px;
}
.letter3{
margin-left: 780px;
}
.letter4{
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: linear;
}
.letter5{
margin-left: 940px;
}
.letter6{
margin-left: 1020px;
}
.C {
position: absolute;
margin-left: 730px;
animation: rotC 14s infinite linear;
z-index: 1;
display: inline-block;
}
.P {
position: absolute;
margin-left: 730px;
animation: rotP 14s infinite linear;
z-index: 1;
display: inline-block;
/*animation-delay: move 3s infinite;*/
}
#keyframes rotC {
0% {
transform: rotate(0deg)
translate(-130px)
rotate(0deg);
}
21.4% {
transform: rotate(180deg)
translate(-130px)
rotate(-180deg);
}
50% {
transform: rotate(180deg)
translate(-130px)
rotate(-180deg);
}
71.4% {
transform: rotate(360deg)
translate(-130px)
rotate(-360deg);
}
100% {
transform: rotate(360deg)
translate(-130px)
rotate(-360deg);
}
}
#keyframes rotP {
0% {
transform: rotate(0deg)
translate(130px)
rotate(0deg);
}
21.4% {
transform: rotate(180deg)
translate(130px)
rotate(-180deg);
}
50% {
transform: rotate(180deg)
translate(130px)
rotate(-180deg);
}
71.4% {
transform: rotate(360deg)
translate(130px)
rotate(-360deg);
}
100% {
transform: rotate(360deg)
translate(130px)
rotate(-360deg);
}
}
<div class="vid"><!-- prycto-->
<img src="geknletters/P.png" alt="p" class="P letter">
<img src="geknletters/R.png" alt="r" class="letter2 letter">
<img src="geknletters/y.png" alt="y" class="letter3 letter">
<img src="geknletters/C.png" alt="c" class="C letter">
<img src="geknletters/T.png" alt="t" class="letter5 letter">
<img src="geknletters/o.png" alt="o" class="letter6 letter">
<video src="051476630-astronaut-doing-ballet-dance-m_H264HD1080.mov" style="position: absolute;
margin: 0;
width: 100%;
height: 100vh;
top:0;
left: 0;" >
</video>
</div>
Hope this helps

Related

css animation not rotating the box

** why box not rotating but its translating the box . translateX is working but rotate is not working in animation **
<style>
.box{
height: 20px;
width: 20px;
background-color: red;
animation: animate 1s linear infinite alternate;
}
#keyframes animate{
0%{
transform: translateX(100px);
}
100%{
transform: rotate(360deg);
}
}
</style>
<div class="box">
</div>
You need to add both the transform properties in the keyframe, take a look at the snippet below
.box{
height: 20px;
width: 20px;
background-color: red;
animation: animate 1s linear infinite alternate;
}
#keyframes animate{
0%{
transform: translateX(100px) rotate(0deg);
}
100%{
transform: translateX(0) rotate(360deg);
}
}
<div class="box">
</div>
This is because it cannot rotate 360deg at the end of the animation.
Almost anything below 360deg will work. Please provide an illustration or video of the result you are trying to accomplish if this solution is not exactly what you want.
<style>
.box {
height: 20px;
width: 20px;
background-color: red;
animation: animate 1s linear infinite alternate;
}
#keyframes animate {
0% {
transform: translateX(100px);
}
100% {
transform: rotate(180deg);
}
}
</style>
<div class="box"></div>
However if you only want it to spin 360deg and not translateX, you can do it using:
<style>
.box {
height: 20px;
width: 20px;
background-color: red;
animation: animate 1s linear infinite alternate;
}
#keyframes animate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>
<div class="box"></div>

Rotate an element in a rotating div

I'm working on a project right now where I have to draw octagons around <img> tags. These octagons serve as menu items. If a menu is opened the center node should rotate, but only the octagon and not the <img>.
The octagons are drawn around a image with this code:
.octagonWrap{
width: 70px;
height: 70px;
float: left;
position: absolute;
overflow: hidden;
}
.octagon{
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
transform: rotate(45deg);
background-color: transparent;
border: 2px solid #ff7a00;
}
.octagon:before{
position: absolute;
top: -2px;
right: -2px;
bottom: -2px;
left: -2px;
transform: rotate(-45deg);
content: '';
border: inherit;
}
So the basic structure looks like this:
<div class="octagonWrap">
<div class="octagon">
<img style="transform:rotate(-45deg)">
</div>
</div>
The if a octagon is clicked the most outer div gets the class .rotating:
.rotating {
-webkit-animation: rotating 8s linear infinite;
-moz-animation: rotating 8s linear infinite;
-ms-animation: rotating 8s linear infinite;
-o-animation: rotating 8s linear infinite;
}
This class uses the following webkit functions:
#-webkit-keyframes rotating{
from {
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(36deg);
-o-transform: rotate(360deg);
}
}
#keyframes rotating {
from {
-ms-transform: rotate(0deg);
-moz-transform: rotate(0deg);
-webkit-transform: rotate(0deg);
-o-transform: rotate(0deg);
}
to {
-ms-transform: rotate(360deg);
-moz-transform: rotate(360deg);
-webkit-transform: rotate(360deg);
-o-transform: rotate(360deg);
}
}
To prevent the inner image from rotating, i wrote a class with the name .counterrotation which does basically the same as the .rotation class but counterclockwise. So the border of the octagon turns, but the image is stationary.
Problem
Because the image is turned counterclockwise the whole time the menu is open, the style attribute transform:rotate(-45deg) does not work anymore.
As you can see here the octagon turns and the image is stationary but the image is turned by 45 degree where it shouldn't be turned.
Is there a way to turn the image so that it's aligned horizontally while not turning with the other octagon?
If not, is it possible to prevent the image from spinning in the first place?
Edit 1:
Somehow working code:
https://jsfiddle.net/mrcrane/rz285mw9/13/
Since the image is already rotated -45deg just change the counterrotation animation
#keyframes counterrotating {
from {
transform: rotate(-45deg);
}
to {
transform: rotate(-405deg);
}
}
$(document).on("click", '.octa', function(e) {
$(e.target.parentElement).parent().addClass("open rotating");
$(e.target).addClass("counterrotating");
});
.octagonWrap {
width: 70px;
height: 70px;
float: left;
position: absolute;
overflow: hidden;
}
.octagon {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
overflow: hidden;
transform: rotate(45deg);
background-color: transparent;
border: 2px solid #ff7a00;
}
.octagon::before {
position: absolute;
top: -2px;
right: -2px;
bottom: -2px;
left: -2px;
transform: rotate(45deg);
content: '';
border: inherit;
}
#keyframes rotating {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
.rotating {
-webkit-animation: rotating 8s linear infinite;
-moz-animation: rotating 8s linear infinite;
-ms-animation: rotating 8s linear infinite;
-o-animation: rotating 8s linear infinite;
}
#keyframes counterrotating {
from {
transform: rotate(-45deg);
}
to {
transform: rotate(-405deg);
}
}
.counterrotating {
-webkit-animation: counterrotating 8s linear infinite;
-moz-animation: counterrotating 8s linear infinite;
-ms-animation: counterrotating 8s linear infinite;
-o-animation: counterrotating 8s linear infinite;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="graphContainer" style="position:absolute; width:100%;height:100%;cursor:default;">
<div id="add" style="position:absolute; top:10% ;left:50%" class='octagonWrap menuItem open'>
<div class='octagon' style="width:100%;height:100%;">
<img class="octa" src="https://image.flaticon.com/icons/svg/149/149098.svg" style="position:absolute; top:0;left:0;bottom:0;right:0; margin:auto; transform: rotate(-45deg); width:50px; height:50px" />
</div>
</div>
</div>

Animation issues with internet explorer

I'm trying to make waves with continuously floating animation. I have put the code below that I have tried and it's working fine in all browsers except internet explorer.
Is there anything to do with this code to make it work in explorer? Please help.
If you need anything else please let me know. Thanks.
.inf-waveWrapperInner {
position: absolute;
top: auto;
right: 0;
bottom: 25px;
left: 0;
overflow: visible;
margin: auto;
}
.inf-bgTop {
height: 188px;
bottom: 130px;
overflow: visible;
}
.inf-bgMiddle {
height: 255px;
bottom: 5px;
overflow: visible;
}
.inf-bgBottom {
height: 170px;
}
.inf-wave {
width: 500%;
height: 100%;
background-repeat: repeat no-repeat !important;
background-position: 0 top;
transform-origin: center top;
}
.inf-wave.inf-waveTop {
animation: move_wave 25s linear infinite;
-webkit-animation: move_wave 25s linear infinite;
animation-delay: 2s;
-webkit-animation-delay: 2s;
animation-timing-function: linear;
-webkit-animation-timing-function: linear;
}
.inf-wave.inf-waveMiddle {
animation: move_wave 25s linear infinite;
-webkit-animation: move_wave 25s linear infinite;
animation-delay: 2s;
-webkit-animation-delay: 2s;
animation-timing-function: linear;
-webkit-animation-timing-function: linear;
}
.inf-wave.inf-waveBottom {
animation: move_wave 25s linear infinite;
-webkit-animation: move_wave 25s linear infinite;
animation-delay: 2s;
-webkit-animation-delay: 2s;
animation-timing-function: linear;
-webkit-animation-timing-function: linear;
&::after {
content: '';
display: block;
background: #0B5268;
width: 100%;
height: 700px;
position: absolute;
top: 100px;
left: 0;
right: 0;
}
}
#-webkit-keyframes move_wave {
0% {
transform: translateX(0) translateZ(0);
-webkit-transform: translateX(0) translateZ(0);
}
50% {
transform: translateX(-25%) translateZ(0);
-webkit-transform: translateX(-25%) translateZ(0)
}
100% {
transform: translateX(0) translateZ(0);
-webkit-transform: translateX(0) translateZ(0)
}
}
#keyframes move_wave {
0% {
transform: translateX(0) translateZ(0);
-webkit-transform: translateX(0) translateZ(0);
}
50% {
transform: translateX(-25%) translateZ(0);
-webkit-transform: translateX(-25%) translateZ(0)
}
100% {
transform: translateX(0) translateZ(0);
-webkit-transform: translateX(0) translateZ(0)
}
}
<div class="inf-waveWrapperInner inf-bgTop">
<div class="inf-wave inf-waveTop" style="background:url(images/inf-wave-one.svg);"></div>
</div>
<div class="inf-waveWrapperInner inf-bgMiddle">
<div class="inf-wave inf-waveMiddle" style="background:url(images/inf-wave-two.svg);"></div>
</div>
<div class="inf-waveWrapperInner inf-bgBottom">
<div class="inf-wave inf-waveBottom" style="background:url(images/inf-wave-three.svg);"></div>
</div>

rotate gif image to right when hover on it using css3 and html5

How can I rotate gif image when mouse hover on it using css3
#tiger:hover{
-webkit-transform:rotateX(180deg)
}
Use transform: rotate(90deg)
img:hover {
transform: rotate(90deg)
}
<img src="http://placehold.it/150/f00" alt="image">
try this :
.image {
position: absolute;
top: 50%;
left: 50%;
width: 120px;
height: 120px;
margin:-60px 0 0 -60px;
}
.image:hover{
-webkit-animation:spin 4s linear infinite;
-moz-animation:spin 4s linear infinite;
animation:spin 4s linear infinite;
}
#-moz-keyframes spin { 100% { -moz-transform: rotate(360deg); } }
#-webkit-keyframes spin { 100% { -webkit-transform: rotate(360deg); } }
#keyframes spin { 100% { -webkit-transform: rotate(360deg); transform:rotate(360deg); } }
<img class="image" src="http://placehold.it/350x150" alt="" width="120" height="120">

CSS3 Animation pendulum effect

I want pendulum effect with pure CSS but it's not smooth.
Here is what I want, but with pure CSS. http://www.webdevdoor.com/demos/html5-pendulum-demo/
But I prefer more looked like natural speed variation according to it's position.
Fiddle
.bellImg {
height: 20px;
width: 20px;
position: absolute;
right: 10px;
top: 18px;
-webkit-animation-name: rotate;
animation-delay: 3s;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: linear;
-webkit-transform-origin: 50% 0%;
-webkit-animation-timing-function: ease-in-out;
}
#-webkit-keyframes rotate {
0% {
-webkit-transform: rotate(0deg);
}
10% {
-webkit-transform: rotate(10deg);
}
20% {
-webkit-transform: rotate(20deg);
}
30% {
-webkit-transform: rotate(10deg);
}
40% {
-webkit-transform: rotate(5deg);
}
50% {
-webkit-transform: rotate(0deg);
}
60% {
-webkit-transform: rotate(-5deg);
}
70% {
-webkit-transform: rotate(-10deg);
}
80% {
-webkit-transform: rotate(-20deg);
}
90% {
-webkit-transform: rotate(-10deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
<img class="bellImg" src="img/bell.png">
There are a few problems in your code:
The animation-timing-function is specified as ease-in-out. This indicates that the animation starts and end slowly but has more speed in between. For a graceful and equal move, this should be set to linear.
This is what MDN says about ease-in-out timing function:
This keyword represents the timing function cubic-bezier(0.42, 0.0, 0.58, 1.0). With this timing function, the animation starts slowly, accelerates then slows down when approaching its final state. At the beginning, it behaves similarly to the ease-in function; at the end, it is similar to the ease-out function.
There is no value called linear for animation-direction.
The splits are not equal. That is, for some 10% gap it is rotating by 10 degree whereas for others it is rotating only by 5 degree. Make the splits equal.
The below snippet with all corrections done produces a smooth animation.
.bellImg {
height: 20px;
width: 20px;
position: absolute;
right: 10px;
top: 18px;
-webkit-animation-name: rotate;
animation-delay: 3s;
-webkit-animation-duration: 2s;
-webkit-animation-iteration-count: infinite;
-webkit-animation-direction: normal;
-webkit-transform-origin: 50% 0%;
-webkit-animation-timing-function: linear; /* or make your custom easing */
}
#-webkit-keyframes rotate {
0% {
-webkit-transform: rotate(0deg);
}
25% {
-webkit-transform: rotate(20deg);
}
75% {
-webkit-transform: rotate(-20deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
<img class="bellImg" src="https://cdn1.iconfinder.com/data/icons/freeline/32/bell_sound_notification_remind_reminder_ring_ringing_schedule-48.png">
Setting the animation's speed to depend on the position (that is, slow down as it reaches the extremes and quicken up in the middle) is impossible to achieve with pure CSS (even if we add extra elements).
For setting the animation's speed depending on its position, one option would be to do the following:
Add the image into a container element. Animate it such that it rotates from 20deg to -40deg.
Make the animation on the parent start earlier than the child by 1/3rd of the animation duration of both. That is, reduce the delay on parent by 0.66s. This is done to get the parent to offset initial rotation on the child. The difference is 1/3rd of animation duration because it is the time taken by parent to come to 0deg.
Change the keyframes for the image's animation such that the rotation is from -20deg to 40deg.
Set the animation-direction as alternate for both so that they go in forward direction for first iteration, in reverse for the next and so on.
Set the animation-timing-function as ease-in-out so that it slows down as it approaches the extremes. The effect is more apparent when the animation duration is increased.
.container {
position: absolute;
height: 20px;
width: 20px;
/* right: 10px; commented for demo */
top: 18px;
transform: rotate(20deg);
animation-name: rotate-container;
animation-delay: 2.33s;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
transform-origin: 50% 0%;
animation-timing-function: ease-in-out;
}
.bellImg {
height: 100%;
width: 100%;
transform: rotate(-20deg);
animation-name: rotate;
animation-delay: 3s;
animation-duration: 2s;
animation-iteration-count: infinite;
animation-direction: alternate;
transform-origin: 50% 0%;
animation-timing-function: ease-in-out;
}
#keyframes rotate {
0% {
transform: rotate(-20deg);
}
100% {
transform: rotate(40deg);
}
}
#keyframes rotate-container {
0% {
transform: rotate(20deg);
}
100% {
transform: rotate(-40deg);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<div class='container'>
<img class="bellImg" src="https://cdn1.iconfinder.com/data/icons/freeline/32/bell_sound_notification_remind_reminder_ring_ringing_schedule-48.png">
</div>
Prefix-free library is used in the snippet only to avoid browser prefixes.
The equation involved in the movement of a pendulum is a sinusoidal movement.
You can get this movement with the following animation
.base {
height: 600px;
width: 10px;
position: absolute;
animation: base 10s infinite linear;
background-color: lightgray;
transform: translateX(588px);
}
#keyframes base {
from {transform: translateX(77px);}
to {transform: translateX(760px);}
}
.element {
height: 10px;
width: 10px;
background-color: green;
border-radius: 100%;
animation: element 10s infinite;
transform: translateY(553px);
}
#keyframes element {
from {transform: translateY(294px); animation-timing-function: ease-out;}
25% {transform: translateY(36px); animation-timing-function: ease-in;}
50% {transform: translateY(294px); animation-timing-function: ease-out;}
75% {transform: translateY(553px); animation-timing-function: ease-in;}
to {transform: translateY(294px);}
}
.ref {
width: 800px;
height: 600px;
background-image: url(http://i.stack.imgur.com/Fx4bR.png);
background-size: cover;
}
<div class="base">
<div class="element">
</div>
</div>
<div class="ref"></div>
I had to use some hand-worked values to adjust for the background-image, but the key idea is in the timing functions.
If the preset function is not what you want, you can set a cubic bezier and adjust it as you want.
.base {
height: 600px;
width: 10px;
position: absolute;
animation: base 10s infinite linear;
background-color: lightgray;
transform: translateX(588px);
}
#keyframes base {
from {transform: translateX(77px);}
to {transform: translateX(760px);}
}
.element {
height: 10px;
width: 10px;
background-color: green;
border-radius: 100%;
animation: element 10s infinite;
transform: translateY(553px);
}
#keyframes element {
from {transform: translateY(294px);
animation-timing-function: cubic-bezier(0.1, 0.3, 0.3, 1);}
25% {transform: translateY(36px);
animation-timing-function: cubic-bezier(0.7, 0.0, 0.9, 0.7);}
50% {transform: translateY(294px);
animation-timing-function: cubic-bezier(0.1, 0.3, 0.3, 1);}
75% {transform: translateY(553px);
animation-timing-function: cubic-bezier(0.7, 0.0, 0.9, 0.7);}
to {transform: translateY(294px);}
}
.ref {
width: 800px;
height: 600px;
background-image: url(http://i.stack.imgur.com/Fx4bR.png);
background-size: cover;
}
<div class="base">
<div class="element">
</div>
</div>
<div class="ref"></div>
This is the image used for reference
And this would be the 2 timing functions applied to a pendulum
.test {
height: 400px;
width: 10px;
background-color: lightgreen;
display: inline-block;
margin: 10px 100px;
transform-origin: center top;
}
.anim1 {
animation: oscil1 6s infinite;
}
.anim2 {
animation: oscil2 6s infinite;
}
#keyframes oscil1 {
from {transform: rotate(0deg); animation-timing-function: cubic-bezier(0.1, 0.3, 0.3, 1);}
25% {transform: rotate(20deg); animation-timing-function: cubic-bezier(0.7, 0.0, 0.9, 0.7);}
50% {transform: rotate(0deg); animation-timing-function: cubic-bezier(0.1, 0.3, 0.3, 1);}
75% {transform: rotate(-20deg); animation-timing-function: cubic-bezier(0.7, 0.0, 0.9, 0.7);}
to {transform: rotate(0deg);}
}
#keyframes oscil2 {
from {transform: rotate(0deg); animation-timing-function: ease-out;}
25% {transform: rotate(20deg); animation-timing-function: ease-in;}
50% {transform: rotate(0deg); animation-timing-function: ease-out;}
75% {transform: rotate(-20deg); animation-timing-function: ease-in;}
to {transform: rotate(0deg);}
}
<div class="test anim1"></div>
<div class="test anim2"></div>
I haven't used CSS here, but since (it seems like) you just want to avoid libraries, I've implemented it in native JS. It uses the Math.sin() method to tween the values smoothly. As you can see, the effect is very smooth and requires very little code.
var img = document.querySelector( '.bellImg' ),
start = 0;
function sine(){
img.style.transform = "rotate(" + 20 * Math.sin( start ) + "deg)";
start += 0.05;
setTimeout(sine, 1000/30)
}
setTimeout( sine, 3000 );
.bellImg {
height: 20px;
width: 20px;
position: absolute;
left: 10px;
top: 18px;
}
<img class="bellImg" src="https://cdn1.iconfinder.com/data/icons/freeline/32/bell_sound_notification_remind_reminder_ring_ringing_schedule-48.png">
Hope this helps!