How can I use JavaScript to determine the duration of an animation? - javascript

I have looked into trying to test internet connection to prevent people from being left on a loading screen for too long and I haven't found a good method for this. Is there a way I can figure out how long my loading animation has run for and if it exceeds x amount of seconds/ minutes to display an alert to check the connection? I am familiar with JavaScript and some libraries and open to other languages just want the job done. Thanks!
P.S.: Below is the code and animation I have as the loading screen and because if it doesn't connect to a jQuery CDN it won't load I want to mitigate time people spend on said screen.
$(window).on('load', function() {
$('.loader').delay(1000).fadeOut(500);
$('.page_cover').delay(1000).fadeOut(500);
$('.load-txt-cont').delay(1000).fadeOut(500);
});
body,
html {
margin: 0;
padding: 0;
border: none;
display: flex;
flex-direction: column;
text-decoration: none;
color: #ffffff;
background-color: #3b404d;
font-family: 'Raleway', Arial, Helvetica, sans-serif;
overflow-x: hidden;
scroll-behavior: smooth;
outline: none;
}
.page_cover {
position: fixed;
top: 0;
left: 0;
z-index: 10;
width: 100vw;
height: 100vh;
background-color: #3b404d;
display: flex;
justify-content: space-around;
align-items: center;
text-align: center;
}
.conet-cont {
display: flex;
flex-direction: column;
justify-content: space-around;
align-items: center;
font-size: 19.2px;
}
.loader {
width: 115.2px;
height: 115.2px;
border-radius: 100%;
border: 4.8px solid #fff;
z-index: 10;
animation: load 1.25s linear infinite alternate;
-webkit-animation: load 1.25s linear infinite alternate;
-ms-animation: load 1.25s linear infinite alternate;
-moz-animation: load 1.25s linear infinite alternate;
-o-animation: load 1.25s linear infinite alternate;
}
#keyframes load {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#-webkit-keyframes load {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#-ms-keyframes load {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#-moz-keyframes load {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
#-webkit-keyframes load {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Code Cafe | Home</title>
<link href="https://fonts.googleapis.com/css?family=Raleway|Playball|Lobster+Two" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="main.js"></script>
<style>
#font-face {
font-family: 'Ballet Harmony';
src: url('ballet_harmony-webfont.woff2') format('woff2'), url('ballet_harmony-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
</style>
</head>
<body>
<div class="page_cover">
<div class="conet-cont">
<h2 class="load-txt">Preparing everything for you...</h1>
<div class="loader"></div>
</div>
</div>
<h1>Loaded Content</h1>
</body>

The request seems to be a test for network connection after a certain time.
Simple network connectivity can be detected with the Navigator.onLine property.
let online = navigator.onLine;
To use a time delay before informing the user, you can use the setTimeout() function.
let timeout = setTimeout(myTimeoutHandler, 5000);
A very simple example that checks the connection after 5 seconds, showing an alert if there is no connection:
setTimeout(() => {
if (!navigator.onLine) {
alert('no network connection');
}
}, 5000);
But the question arises on how good is the browser support for navigator.onLine?
According to caniuse.com, the support is quite good.
Update
The original code is attempting to load jQuery from a CDN, so simply looking for the presence of jQuery will determine connectivity.
setTimeout(() => {
if (typeof window.jQuery !== 'function') {
alert('jQuery not loaded');
}
}, 5000);
Example to demonstrate.
function testForJquery() {
setTimeout(() => {
if (typeof window.jQuery !== 'function') {
alert('jQuery not loaded');
} else {
alert('jQuery is loaded');
}
}, 1000);
}
function loadJQuery () {
let script = document.createElement('script');
script.src = 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js';
document.body.appendChild(script);
}
<body>
<h4>Test for jQuery</h4>
<button onclick="loadJQuery();">Load jQuery</button><br/>
<button onclick="testForJquery();">Test for jQuery</button><br/>
</body>

Related

Keep triggering animations on click

I have a section in my html with height=100vh. I want to show an animation of a text once user clicks anywhere on the window. Basically I want to keep triggering multiple animations over click event. I've achieved this using the following code:
const p1 = document.querySelector('.one p')
const p2 = document.querySelector('.two p')
const section1 = document.querySelector('.one')
const section2 = document.querySelector('.two')
window.addEventListener('click', () => {
p1.classList.add('animation')
if (p1.classList.contains('animation')) {
setTimeout(() => {
window.addEventListener('click', () => {
section1.classList.add('animation')
section2.classList.add('animation')
if (section1.classList.contains('animation')) {
setTimeout(() => {
window.addEventListener('click', () => {
p2.classList.add('animation')
}, {once:true})
}, 500)
}
}, {once:true})
}, 1000)
}
}, {once:true})
* {
margin: 0;
padding: 0;
}
body {
overflow: hidden;
height: 100vh;
}
section {
width: 100%;
height: 100vh;
color: white;
font-family: sans-serif;
font-size: 50px;
display: flex;
align-items: center;
justify-content: center;
}
.one {
background-color: indianred;
transition: 500ms ease-in;
}
.one.animation {
transform: translateY(-100vh);
}
.one p {
transform: translateX(-100vw);
transition: 1s ease-in;
}
.one p.animation {
transform: translateX(0);
}
.two {
background-color: grey;
transition: 500ms ease-in;
}
.two.animation {
transform: translateY(-100vh);
}
.two p {
transform: translateX(-100vw);
transition: 1s ease-in;
}
.two p.animation {
transform: translateX(0);
}
<body>
<section class="one">
<p>Section One</p>
</section>
<section class="two">
<p>Section Two</p>
</section>
</body>
But once all animations are done and I refresh the page, the applied animations remains and the page doesn't reload to it's initial look. I want to know why that is happening.
Also I would appreciate if I'm suggested with a different approach to achieve the requirements. Because the way I'm achieving it, I'm nesting the click event listener which doesn't seem to be efficient and a good practice.

Text Animation Flickering Problem in CSS and React

I managed to achieve this animation through CSS animations and React. but go stuck in flickering problem. I don't know why this is happening maybe 'cause I used setInterval or there is some problem with my css animations keyframes. help me to solve this problem. the flicker only occurs after some time. and after refreshing the page the animation works perfectly fine without flicker problem.
this is how the animation looks after refreshing the page and this is what I want too. (ignore the screen recorder watermark).
animation I want
but after sometime the animation starts flickering like this.
Flickering problem
here are the code snippets I wrote
jsx snippet
<div className="relative w-[280px] md:w-[350px] lg:w-[500px]">
<span>{"[ "}</span>
<p className="text_animate ml-2">
{dev ? "for" : "by"} Developers
</p>
<span className="absolute right-0 ">{" ]"}</span>
</div>
css snippet
.text_animate {
color: orange;
margin: 0 auto;
display: inline-block;
position: relative;
letter-spacing: .15em;
text-align: start;
animation: text-up 6s linear infinite;
cursor: none;
}
#keyframes text-up {
0% {
top:45px;
opacity: 0;
}
20% {
top:0;
opacity: 1;
}
35% {
top: 0;
opacity: 1;
}
50% {
top: -45px;
opacity: 0;
}
52% {
top: 45px;
opacity: 0;
}
70% {
top: 0;
opacity: 1;
}
85% {
top: 0;
opacity: 1;
}
100% {
top: -45px;
opacity: 0;
}
}
useState changing text
const [dev, setDev] = useState(true);
setInterval(() => {
setDev(!dev);
}, 3000);
If there is any better way to achieve this I would really love to learn so let me know that too.
Maybe you should put setInterval to useEffect, and remember to clear timer. Like this:
useEffect(() => {
const timer = setInterval(() => {
setDev(!dev);
}, 3000);
return () => {
clearInterval(timer);
}
}, []);
And there is a solution only using css to implement this, I will write a demo later.
EDIT:
Explain the above code:
useEffect with [] as second param will make sure run setInterval once when mount the component.
The clearInterval in return function will make sure engine GC the variables in setInterval callback functions when unmount the component, or the setInterval will still work even though you needn't it.
CSS only solution:
ul {
margin: 0;
padding: 0;
list-style-type: none;
}
li {
margin: 0;
padding: 0;
}
.scroll-container {
overflow: hidden;
height: calc(var(--line-h) * 1px);
line-height: calc(var(--line-h) * 1px);
font-size: 18px;
}
.scroll-container ul {
animation-name: move;
animation-duration: calc(var(--speed) * var(--lines));
animation-timing-function: steps(var(--lines));
animation-iteration-count: infinite;
}
.scroll-container ul li {
animation-name: li-move;
animation-duration: var(--speed);
animation-iteration-count: infinite;
}
#keyframes move {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(0, calc(var(--lines) * var(--line-h) * -1px));
}
}
#keyframes li-move {
0% {
transform: translate(0, 0);
}
50%,
100% {
transform: translate(0, calc(var(--line-h) * -1px));
}
}
<div
class="scroll-container"
style="--lines: 2; --line-h: 26; --speed: 3s"
>
<ul>
<li>For Developers</li>
<li>By Developers</li>
<!-- repeat first in tail for infinity -->
<li>For Developers</li>
</ul>
</div>
I leaned this from Chokcoco on CodePen but forget which post.

How to sync two animations using css keyframes?

I am working on solution
I have created a basic html banner where I want to keep image and text animations in sync.
Basically image animation is like scale logo for about 3 seconds, meanwhile logo is animated I want text for same in typing effect
I have created basic solution using css and javascript but it is not in sync
var typewriter = function(txt) {
var container = document.getElementById('typewriter'),
speed = 28,
i = 0,
wordsObj = txt.split(" ")
container.textContent = "";
runAllWords();
function runAllWords() {
if (i < wordsObj.length) {
var a = (i == 0) ? i : i - 1;
setTimeout(function() {
showWord(wordsObj[i], 0)
}, wordsObj[a].length * speed);
}
}
function showWord(word, countWord) {
if (countWord < word.length) {
setTimeout(function() {
showLetter(word, countWord)
}, speed);
} else {
container.textContent = container.textContent + " ";
i += 1;
runAllWords();
}
if (i === wordsObj.length) {
console.log('complete')
}
}
function showLetter(word, countWord) {
container.textContent = container.textContent + word[countWord];
showWord(word, countWord + 1);
}
}
var i = 0;
function myLoop() {
// create a loop function
var dataType = document.getElementById('typewriter').dataset.typewriter,
w = dataType.split(',')
setTimeout(function() { // call a 3s setTimeout when the loop is called
typewriter(w[i]); // your code here
i++; // increment the counter
if (i < w.length) { // if the counter < 10, call the loop function
myLoop(); // .. again which will trigger another
} // .. setTimeout()
}, 3000)
}
myLoop();
.addsp_320x50 {
width: 100%;
height: 50px;
position: relative;
}
.addsp_320x50_img {
position: absolute;
top: 1px;
left: 10px;
width: 48px;
height: 48px;
border: 0px solid #ccc;
border-radius: 50%;
}
.addsp_title_text {
position: absolute;
top: 5px;
left: 70px;
font-family: Open Sans;
font-weight: bold;
}
.addsp_title_desc {
position: absolute;
top: 20px;
left: 70px;
font-family: Open Sans;
color: #999;
}
.addsp_320x50_action button {
height: 27px;
background: #058562;
border-radius: 4px;
color: #fff;
border-color: #058562;
font-size: 12px;
font-weight: bold;
font-family: Open Sans;
border-style: solid;
position: absolute;
right: 10px;
top: 10px;
display: flex;
}
.adz_text_1 {}
.adz_text_2 {
animation: text2;
}
.adz_text_1,
.adz_text_2 {}
#keyframes text2 {
0%,
50%,
100% {
width: 0px;
}
60%,
90% {
width: 200px;
}
}
#keyframes text1 {
0%,
50%,
100% {
width: 0px;
}
10%,
40% {
width: 200px;
}
}
#media only screen and (min-width: 320px) {
.addsp_320x50_img {
width: 42px;
height: 42px;
top: 4px;
left: 5px;
}
.addsp_title_text {
top: 14px;
left: 56px;
font-size: 0.85rem;
}
.addsp_title_desc {
top: 25px;
left: 55px;
font-size: 0.8rem;
}
}
#media only screen and (min-width: 480px) {
.addsp_title_text {
top: 3px;
left: 55px;
font-size: 1.1rem;
}
.addsp_title_desc {
top: 28px;
left: 55px;
font-size: 0.8rem;
}
}
#media only screen and (min-width: 600px) {
.addsp_title_text {
top: 3px;
left: 70px;
font-size: 1.1rem;
}
.addsp_title_desc {
top: 28px;
left: 70px;
font-size: 0.8rem;
}
}
#media only screen and (min-width: 800px) {
.addsp_title_text {
top: 3px;
left: 70px;
font-size: 1.1rem;
}
.addsp_title_desc {
top: 28px;
left: 70px;
font-size: 0.8rem;
}
}
.addsp_320x50_img:nth-child(1) {
animation-name: scale;
animation-duration: 3s;
animation-timing-function: linear;
animation-delay: 1s;
animation-iteration-count: infinite;
animation-fill-mode: forwards;
opacity: 0;
}
.addsp_320x50_img:nth-child(2) {
animation-name: scale;
animation-duration: 3s;
animation-timing-function: linear;
animation-delay: 4s;
animation-iteration-count: infinite;
animation-fill-mode: forwards;
opacity: 0;
}
.addsp_320x50_img:nth-child(3) {
animation-name: scale;
animation-duration: 3s;
animation-timing-function: linear;
animation-delay: 7s;
animation-iteration-count: infinite;
animation-fill-mode: forwards;
opacity: 0;
}
#keyframes scale {
0% {
transform: scale(1);
opacity: 1
}
20% {
transform: scale(1.2);
opacity: 1
}
40% {
transform: scale(1);
opacity: 1
}
60% {
transform: scale(1.2);
opacity: 1
}
80% {
transform: scale(1);
opacity: 1
}
90% {
transform: translateY(-100px);
opacity: 0;
}
100% {
opacity: 0;
}
}
.blinking-cursor {
color: #2E3D48;
-webkit-animation: 1s blink step-end infinite;
-moz-animation: 1s blink step-end infinite;
-ms-animation: 1s blink step-end infinite;
-o-animation: 1s blink step-end infinite;
animation: 1s blink step-end infinite;
}
#keyframes "blink" {
from,
to {
color: transparent;
}
50% {
color: black;
}
}
#-moz-keyframes blink {
from,
to {
color: transparent;
}
50% {
color: black;
}
}
#-webkit-keyframes "blink" {
from,
to {
color: transparent;
}
50% {
color: black;
}
}
#-ms-keyframes "blink" {
from,
to {
color: transparent;
}
50% {
color: black;
}
}
#-o-keyframes "blink" {
from,
to {
color: transparent;
}
50% {
color: black;
}
}
<div class="addsp_320x50">
<img src="https://de7yjjf51n4cm.cloudfront.net/banners/amazonprime_newicon.jpg" class="addsp_320x50_img">
<img src="https://de7yjjf51n4cm.cloudfront.net/banners/amazonprime_newicon.jpg" class="addsp_320x50_img">
<img src="https://de7yjjf51n4cm.cloudfront.net/banners/amazonprime_newicon.jpg" class="addsp_320x50_img">
<div class="addsp_title_text">
<span class="adz_text_1 typewriter" id="typewriter" data-typewriter="Web Strategy,
UX Testing,
Content Management System,
Web Design,
Research and Analytics,
Information Architecture,
Strategic Consulting,Maintenance and Support"></span><span class="blinking-cursor">|</span>
</div>
<div class="addsp_320x50_action">
<button>DOWNLOAD</button></div>
</div>
Mathematically speaking, sinking means adjusting frequency and phase. I'll demonstrate each separately. Note that what I'm gonna explain is the concept and you can implement it in your codes using Javascript, css, etc
Frequency
You can't sink two animations unless the longer duration is a factor
of shorter duration.
For example in your codes, blinking has a duration of 1s. So your image scaling duration and Also the whole duration must be a selection of either 1s, 2s, 3s, ... or 1/2s, 1/3s, ...
For better understanding let me make a simple example. Assume two images want to be animated.
<img src="1.png" id="img1">
<img src="1.png" style="margin-left: 50px;" id="img2">
Consider two different animations for each one
#keyframes k1
{
25%
{
transform: rotate(-4deg);
}
50%
{
transform: rotate(0deg);
}
75%
{
transform: rotate(3deg);
}
100%
{
transform: rotate(0deg);
}
}
#keyframes k2
{
50%
{
transform: scale(1.2);
}
100%
{
transform: scale(1);
}
}
So since k2 is simpler, I'll first assign it to img2 with duration of 0.7s
#img2
{
animation: k2 0.7s linear infinite;
}
And based on what was explained, I will assign animation k1 to img1 with a duration of 1.4s. (NOT 1.3s NOT 1.5s VERY IMPORTANT!)
#img1
{
animation: k1 1.4s linear infinite;
}
If you run this code you'll see they are sink! To feel the concept better, change the duration of k1 to 0.9s. Now it feels like they are doing their thing separately!
Note
I set k1 to 1.4s (0.7s × 2) because k1 seems to be a combination of one go forward and come back and using 2x feels they are dancing together with the same harmony!
Phase
In css, phase is showed by animation-delay. Modifying frequencies (duration) is enough to sink two animations but if two animation begin at the same time it will feel better! So to illustrate set a delay for img1 of 0.2s. They are still sink but it doesn't feel nice! Now change the delay to 0.7s. Now it's beautiful again! (Maybe even more beautiful)
Back to your code
Your images scale with duration of 1.2s (40% of 3s) and your text blinking duration is 1s and as you can see they are not factor of each other so you can't sink!
I think you might be looking for the animation iteration event and the animation start event.
Instead of just using the myLoop function to call itself, try using these listeners to call it instead.
The end of your js file would look like:
var i = 0;
function myLoop() {
var dataType = document.getElementById("typewriter").dataset.typewriter,
w = dataType.split(",");
if (i < w.length -1 ) {
typewriter(w[i]);
}
i++;
}
var imageElems = Array.from(document.querySelectorAll('.addsp_320x50_img'));
imageElems.forEach(elem=>{
elem.addEventListener('animationstart',myLoop);
});
Where ".addsp_320x50_img" is just whatever common selector you give to all the images.
If you control the animation with the same JavaScript loop as the typewriter script, it won't lose sync. I rewrote the typewriter script to do this in the snippet below.
startTypewriter() Exaplaination
First, all the messages from the are collected converted into an array.
typewriter.getAttribute('data-typewriter').split(',');
Then the CSS icon animation is started. Because JavaScript intervals wait for their duration before executing their code, so the first message is typed by calling type() before the interval is created.
icon.classList.add('icon-animation');
type(typewriter, messages[0].trim(), animationDuration - pauseDuration);
The interval is now started, running every 3 seconds by default. The first thing that happens is the animation is reset in case it got out of sync somehow.
icon.classList.remove('icon-animation');
window.setTimeout(function() {
icon.classList.add('icon-animation');
}, 25);
Next, the message is typed by calling type(). Before it ends, a check is run so see if it's on the last array element. If so, it will start over.
if (i == messages.length) i = 0;
type() Exaplaination
At the start, the timePerCharacter value is calculated. The message is split to an array and the typewriter output is cleared
var timePerCharacter = duration / message.length;
var message = message.split('');
typewriter.innerHTML = '';
A loop is created, running every timePerCharacter. The character is outputted to the typewriter output.
typewriter.innerHTML += message[i];
Once all the characters are outputted, the loop is cleared
if (i == message.length) clearInterval(typeLoop);
Snippent
var animationDuration = 3000;
var pauseDuration = 2000;
startTypewriter();
function startTypewriter() {
var typewriter = document.getElementById('typewriter');
var icon = document.getElementById('icon');
var messages = typewriter.getAttribute('data-typewriter').split(',');
icon.classList.add('icon-animation');
type(typewriter, messages[0].trim(), animationDuration - pauseDuration);
var i = 1;
window.setInterval(function() {
icon.classList.remove('icon-animation');
window.setTimeout(function() {
icon.classList.add('icon-animation');
}, 25);
type(typewriter, messages[i].trim(), animationDuration - pauseDuration);
i++;
if (i == messages.length) i = 0;
}, animationDuration);
}
function type(typewriter, message, duration) {
var timePerCharacter = duration / message.length;
var message = message.split('');
typewriter.innerHTML = '';
var i = 0;
var typeLoop = window.setInterval(function() {
typewriter.innerHTML += message[i];
i++;
if (i == message.length) clearInterval(typeLoop);
}, timePerCharacter);
}
#keyframes icon {
20% {
transform: scale(0.9);
}
40% {
transform: scale(1);
}
60% {
transform: scale(0.9);
}
80% {
transform: scale(1);
}
100% {
transform: translateY(-200%);
}
}
.icon {
border-radius: 100%;
}
.icon-animation {
animation: icon 3s;
}
#keyframes cursor {
50% {
color: transparent;
}
}
.blinking-cursor {
animation: cursor 1s steps(1) infinite;
}
<img id="icon" src="https://de7yjjf51n4cm.cloudfront.net/banners/amazonprime_newicon.jpg" class="icon">
<span id="typewriter" data-typewriter="
Web Strategy,
UX Testing,
Content Management System,
Web Design,
Research and Analytics,
Information Architecture,
Strategic Consulting,
Maintenance and Support
">
</span>
<span class="blinking-cursor">|</span>

control multiple keyframe animations of single element via JavaScript

I have a text and I want to apply two different keyframe animations named animeUp and animeDown to it. Also, I want to be able to control the animation using javascript.
The desired result is a javascript line of code to initiate animeUp animation and another one to initiate the animeDown...
I've tried to play and pause the animations by adding CSS classes that change the animation-play-state but using this approach I can only control one of the animations!
Note: we want the keyframe animations as they are...
//pause the animation at first
document.getElementById("Text").classList.add("paused");
//after 2 seconds initiate the animation
setTimeout(function(){
document.getElementById("Text").classList.add("played");
}, 2000)
html{
overflow:hidden;
}
#Text{
position: absolute;
overflow: hidden;
font-family: 'Open Sans', sans-serif;
font-weight: bold;
font-size: 7.5vw;
color: rgb(242, 242, 242);
left: 1vw;
top: -45vh;
animation: animeUp 0.5s ease-out ;
animation: animeDown 0.5s ease-in ;
animation-fill-mode: forwards;
}
#-webkit-keyframes animeUp {
from { top: 10vh }
to { top: -50vh }
}
#-webkit-keyframes animeDown {
from { top: -50vh }
to { top: 10vh }
}
.paused {
-webkit-animation-play-state: paused !important;
}
.played {
-webkit-animation-play-state: running !important;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div class = "container">
<p id="Text">Tutorial</p>
</div>
</body>
</html>
Create a class for each animation and toggle between the two.
I threw together a demo, nothing too fancy just to get the idea across.
document.querySelector('.up').onclick = (e) => {
document.getElementById("Text").classList.add("animeup");
document.getElementById("Text").classList.remove("animedown");
e.target.disabled = "true";
document.querySelector('.down').removeAttribute("disabled");
}
document.querySelector('.down').onclick = (e) => {
document.getElementById("Text").classList.remove("animeup");
document.getElementById("Text").classList.add("animedown");
document.querySelector('.up').removeAttribute("disabled");
e.target.disabled = "true";
}
html {
overflow: hidden;
}
#Text {
position: absolute;
overflow: hidden;
font-family: 'Open Sans', sans-serif;
font-weight: bold;
font-size: 7.5vw;
color: red;
left: 1vw;
top: -50vh;
animation-fill-mode: forwards;
}
#-webkit-keyframes animeUp {
from {
top: 10vh
}
to {
top: -50vh
}
}
#-webkit-keyframes animeDown {
from {
top: -50vh
}
to {
top: 10vh
}
}
.animeup {
animation: animeUp 0.5s ease-out;
}
.animedown {
animation: animeDown 0.5s ease-in;
}
<button class="up" disabled>Up</button>
<button class="down">Down</button>
<div class="container">
<p id="Text">Tutorial</p>
</div>

How to rotate an image back and forth with JavaScript

I am trying to create a website and on the website I want the faces to rotate to certain point and then rotate back in the opposite direction until a certain point, I would like it if they could keep doing this forever but I can only get it to do a full rotation forever does anyone know how to fix this?
This is my HTML code:
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>BSDC</title>
<link href="style.css" rel="stylesheet" type="text/css" media="all" />
<script src="jquery-1.10.2.js" type="text/javascript"></script>
<script>
var looper;
var degrees = 0;
function rotateAnimation(el,speed){
var elem = document.getElementById(el);
if(navigator.userAgent.match("Chrome")){
elem.style.WebkitTransform = "rotate("+degrees+"deg)";
} else if(navigator.userAgent.match("Firefox")){
elem.style.MozTransform = "rotate("+degrees+"deg)";
} else if(navigator.userAgent.match("MSIE")){
elem.style.msTransform = "rotate("+degrees+"deg)";
} else if(navigator.userAgent.match("Opera")){
elem.style.OTransform = "rotate("+degrees+"deg)";
} else {
elem.style.transform = "rotate("+degrees+"deg)";
}
looper = setTimeout('rotateAnimation(\''+el+'\','+speed+')',speed);
degrees++;
if(degrees > 359){
degrees = 1;
}
document.getElementById("status").innerHTML = "rotate("+degrees+"deg)";
}
</script>
</head>
<body>
<img id="Dave" src="Images/Dave.png"/>
<script>rotateAnimation("Dave",30);</script>
<img id="Andy" src="Images/Andy.png" />
<script>rotateAnimation("Andy",30);</script>
<img id="Dan" src="Images/Dan.png" />
<script>rotateAnimation("Dan",30);</script>
<img id="Nico" src="Images/Nico.png" />
<script>rotateAnimation("Nico",30);</script>
</body>
</html>
And this is my CSS code
body {
font-family: Arial, sans-serif;
background-image: url("Images/BSDC.png");
background-repeat: no-repeat;
}
#Dave {
position: absolute;
margin-left: 3%;
margin-top: 3%;
}
#Andy {
margin-left: 3%;
margin-top: 35%;
position: absolute;
}
#Dan {
margin-left: 85%;
margin-top: 3%;
position: absolute;
}
#Nico {
margin-left: 85%;
margin-top: 35%;
position: absolute;
}
You can do this all with CSS animation. Check out this jsFiddle
the browser prefixes are annoying... and if anybody knows if this can be simplified please comment. But this is the concept, you set an animation on your element:
#box {
-webkit-animation: NAME-YOUR-ANIMATION 5s infinite; /* Safari 4+ */
-moz-animation: NAME-YOUR-ANIMATION 5s infinite; /* Fx 5+ */
-o-animation: NAME-YOUR-ANIMATION 5s infinite; /* Opera 12+ */
animation: NAME-YOUR-ANIMATION 5s infinite; /* IE 10+, Fx 29+ */
}
and then you define your animation, you can do any property changes and make as many steps in it as possible, i just used basic values (0, 25, 50 100)
#keyframes NAME-YOUR-ANIMATION {
0% { transform: rotate(0deg); }
25% { transform: rotate(45deg); }
50% { transform: rotate(-45deg); }
100% { transform: rotate(0deg); }
}
You can read up on this stuff on MDN

Categories

Resources