How to add a page preloader when user click on a button - javascript

I need to add page preloader when the user clicks on the login button in my project.so I create a sample page by including a submit button. and created a spinner as a preloader by using CSS as well as a javascript function to execute the spinner & fade it out and load another page call welcome.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="overlay"> <div class="spinner"></div>
</div>
<input type="submit" name="click me" id="submit">
**here is the javascript function**
<script>
(function(){
var spinner =document.getElementById("spinner");
var loading = 0;
var id = setInterval(frame,20);
function frame(){
if(loading==100){
clearInterval(id);
window.open("welcome.html","_self");
} else {
loading = loading + 1;
if(loading==90){
spinner.style.animation ="fadeout 1s ease";
}
}
}
})();
</script>
</body>
</html>
**here is the style sheet for preloader**
.overlay{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #ff6347;
z-index: -999;
}
.spinner {
position: fixed;
top: 33%;
left: 48%;
width: 60px;
height: 60px;
background-color: black;
-webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
animation: sk-rotateplane 1.2s infinite ease-in-out;
}
**here is the keyframe code for fadeout**
#keyframes fadeout {
from {opacity: 1;}
to{opacity: 0;}
}
}
#-webkit-keyframes sk-rotateplane {
0% { -webkit-transform: perspective(120px) }
50% { -webkit-transform: perspective(120px) rotateY(180deg) }
100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }
}
#keyframes sk-rotateplane {
0% {
transform: perspective(120px) rotateX(0deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
} 50% {
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
} 100% {
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
}
}
what I needed was, the user clicks on the button and then shows the preloader. But the thing is when I run the page button appears at the same time spinner preloader is running without clicking on the button and after the loading welcome.html page opens.

You should hide the spinner initially and only show it when the loading starts. So you could change the frame function to something like this:
function loading(){
if(loading==0) {
spinner.classList.add('active');
} else if(loading==100){
clearInterval(id);
window.open("welcome.html","_self");
spinner.classList.remove('active');
} else {
loading = loading + 1;
if(loading==90){
spinner.style.animation ="fadeout 1s ease";
}
}
}
Also you could add some sort of click listener to the submit button rather than setting an interval to check every 20 milliseconds on page load already, that seems unnecessary.
And then change this in your css:
.spinner {
display: none;
position: fixed;
top: 33%;
left: 48%;
width: 60px;
height: 60px;
background-color: black;
-webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
animation: sk-rotateplane 1.2s infinite ease-in-out;
}
.spinner.active {
display: block
}

First add
.overlay{
display:none;
}
in css and then on click function of submit button add
document.getElementById("overlayId").style.display = "block";
If you are using javascript
and
$(".overlay").css("display", "block");
if you are using jquery
N.B.: overlayId is the Id of overlay DIV

Related

CSS animation to occur on a timer to create a heartbeat animation

The snippet below shows a spinning circle. Every 1 second I want this circle to double in size and then shrink back to it's original size(to look like a heartbeat). The way I am attempting to do this is by creating a timer in javascript so that every one second, the class which causes the grow effect is removed from the circle, and then immediately added back on. I was hoping that having the class added back on after being removed would trigger the animation but I guess not. Right now the "heartbeat" only happens once.
Also I would like to have the circle spinning at constant speed if that's possible. Right now the circle really slows down at the end, and starts a little bit slow.
// set timeout
let tid = setTimeout(mycode, 1000);
function mycode() {
// do some stuff...
let ic = document.getElementById('inner-circle')
ic.classList.remove('heartbeat')
ic.classList.add('heartbeat')
tid = setTimeout(mycode, 1000); // repeat myself
}
function abortTimer() { // to be called when you want to stop the timer
clearTimeout(tid);
}
#spinning-circle {
animation-name: spinning-circle;
animation-duration: 10s;
animation-iteration-count: infinite;
width: 40px;
height: 40px;
}
.heartbeat {
width: 100%;
height: 100%;
animation-name: heartbeat;
animation-duration: 0.15s;
animation-iteration-count: 2;
animation-direction: alternate;
animation-fill-mode: both;
}
#inner-circle img {
width: 100%;
height: auto;
}
#-webkit-keyframes heartbeat {
100% {
transform: scale(2,2);
-webkit-transform: scale(2,2);
}
}
#-webkit-keyframes spinning-circle {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
<div id="spinning-circle">
<div id='inner-circle'>
<img src="http://i.stack.imgur.com/WbNlQ.jpg">
</div>
</div>
use setInterval() and clearInterval() instead of setTimeout(), and remove the setTimeout() inside the function mycode()
// set timeout
let tid = setInterval(mycode, 1000);
function mycode() {
// do some stuff...
let ic = document.getElementById('inner-circle')
ic.classList.remove('heartbeat')
ic.classList.add('heartbeat')
}
function abortTimer() { // to be called when you want to stop the timer
clearInterval(tid);
}
and for the animation speed add animation-timing-function: linear; to .heartbeat {} and #spinning-circle {}
You don't need javascript at all:
#spinning-circle {
margin-top: 40px;
margin-left: 40px;
animation: spinning-circle linear 10s infinite;
width: 40px;
height: 40px;
overflow: visible;
}
#inner-circle {
animation: heartbeat 1s infinite;
}
#inner-circle img {
width: 100%;
height: auto;
}
#keyframes heartbeat {
0% {
transform: scale(1);
}
25% {
transform: scale(2);
}
50% {
transform: scale(1);
}
100% {
transform: scale(1);
}
}
#keyframes spinning-circle {
0% {
transform: rotate(0turn);
}
100% {
transform: rotate(-1turn);
}
}
<div id="spinning-circle">
<div id='inner-circle'>
<img src="http://i.stack.imgur.com/WbNlQ.jpg">
</div>
</div>

How to trigger a CSS animation from JS?

I have a balloon that when hovered, will expand n disappear (a popping-like animation). I made this in CSS but when the cursor moves, the balloon returned. I want the balloon to disappear forever until I refresh the page, so I guess it needs to be onclick, but that selector is not available in CSS.
Here's what I have in CSS
#keyframes pop
{
from{
opacity:1;
transform: translateZ(0) scale(1,1);
}
to{
opacity:0;
transform: translateZ(0) scale(1.5,1.5);
}
}
.balloon:hover
{
animation: pop 0.5s cubic-bezier(0.16, 0.87, 0.48, 0.99) forwards;
}
I saw another question that said the closest thing is :active but it requires the mouse to be held down. If I want it to be onclick, I need to use Javascript. But I don't know what I need to write to trigger the animation.
And is it also possible to make it so that when I pop 1 balloon, all the others will pop too automatically with a 1s delay inbetween? (There are 5 balloons).
You can add and remove the class of the animation with JS using classList.
Add:
object.classList.add('balloon');
Remove:
object.classList.remove('balloon');
Working example:
const add = () => {
document.getElementById('balloon').classList.add('animation')
}
const remove = () => {
document.getElementById('balloon').classList.remove('animation')
}
#keyframes pop {
from {
opacity: 1;
transform: translateZ(0) scale(1, 1);
}
to {
opacity: 0;
transform: translateZ(0) scale(1.5, 1.5);
}
}
.animation {
animation: pop 0.5s cubic-bezier(0.16, 0.87, 0.48, 0.99) forwards;
}
.balloon {
height: 125px;
width: 110px;
background-color: #FF6B6B;
border-radius: 50%;
}
.controls{
position: absolute;
bottom: 10px;
right: 10px;
}
<div id="balloon" class="balloon" onmouseover="add()"></div>
<div class="controls">
<button onClick="add()">Hide</button>
<button onClick="remove()">Show</button>
</div>
Here is a solution which makes balloons hiding one by one with interval .5s between them
var balloons = document.getElementsByClassName('balloon');
[...balloons].forEach( (e, i)=>{
e.onmouseover = function() {
this.classList.add('hidden');
setTimeout(hideAll, 500, balloons);
}
});
function hideAll(arg){
[...arg].forEach( (e, i)=>{
if ( ! e.classList.contains('hidden') ) {
e.style.animationDelay = i+'s';
e.classList.add('hidden');
}
});
}
#keyframes pop
{
from{
opacity:1;
transform: translateZ(0) scale(1,1);
}
to{
opacity:0;
transform: translateZ(0) scale(1.5,1.5);
}
}
.balloon.hidden
{
animation: pop .5s cubic-bezier(0.16, 0.87, 0.48, 0.99) forwards;
}
<div class="balloon">Balloon</div>
<div class="balloon">Balloon</div>
<div class="balloon">Balloon</div>
<div class="balloon">Balloon</div>
<div class="balloon">Balloon</div>

Animate each transform property separately on click event using CSS

I want that whenever I click on the div, it first translate, then rotate and, finally scale. Further, I want to reverse it back in the same way when I click again
I have the following code:
$(() => {
$('div').on('click', () => {
$('div').toggleClass('clicked');
});
});
div.normal {
height: 20px;
width: 100px;
background: black;
transition: 2s all;
}
div.clicked {
transform: translate(100px, 100px) rotate(45deg) scale(2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='normal'></div>
As you can see, all the transformations are occurring at the same time. But, I want them to occur separately. How do I achieve this?
Thanks in advance!
Decompose your animation using keyframes. Here is a minimally edited version of your code:
var $el = $('#to-animate')
var firstClick = true
$el.click(() => {
$el.toggleClass('clicked')
if (!firstClick) {
$el.toggleClass('unclicked')
}
firstClick = false
})
div.normal {
height: 20px;
width: 100px;
background: black;
}
div.clicked {
animation: transforms 2s forwards;
}
div.unclicked {
animation: transforms-2 2s reverse;
}
#keyframes transforms {
33% {
transform: translate(100px, 100px);
}
66% {
transform: translate(100px, 100px) rotate(45deg);
}
100% {
transform: translate(100px, 100px) rotate(45deg) scale(2);
}
}
#keyframes transforms-2 {
33% {
transform: translate(100px, 100px);
}
66% {
transform: translate(100px, 100px) rotate(45deg);
}
100% {
transform: translate(100px, 100px) rotate(45deg) scale(2);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="to-animate" class='normal'></div>
Edit updated to include ability to reverse the animation (making the code edit less minimal)
An idea is to rely on other properties to achieve the same effect and be able to apply different transition
$(() => {
$('div').on('click', () => {
$('div').toggleClass('clicked');
});
});
div.normal {
height: calc(20px * var(--s,1));
width: calc(100px * var(--s,1));
background: black;
position:relative;
top:0;
left:0;
transition: 2s top 4s,2s left 4s,2s width 2s,2s height 2s,2s transform;
}
div.clicked {
top:100px;
left:100px;
--s:2;
transform:rotate(45deg);
transition: 2s top,2s left,2s width 2s,2s height 2s,2s transform 4s;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='normal'></div>

Animating divs to act as pages in CSS3

I'm trying to get content to move across the screen but I was having trouble moving text with Bootstrap's carousel.
I have an animation working, but the divs sit on top of each other so they animate in and out of their own positions, not in and out of the same position.
Here's the CSS
/* Home and about pages */
#about-page {
transform: translateX(200%);
}
.slideOutLeft {
animation: slideOutLeft 1s forwards;
}
.slideInLeft {
transform: translateX(-200%);
animation: slideInLeft 1s forwards;
}
.slideOutRight{
transform: translateX(200%);
animation: slideOutRight 1s forwards;
}
.slideInRight {
animation: slideInRight 1s forwards;
}
/* Slide in from the left */
#keyframes slideOutLeft {
0% { transform: translateX(0%); }
100% { transform: translateX(-200%); }
}
#keyframes slideInLeft {
0% { transform: translateX(-200%); }
100% { transform: translateX(0%); }
}
#keyframes slideOutRight {
0% { transform: translateX(0%); }
100% { transform: translateX(200%); }
}
#keyframes slideInRight {
0% { transform: translateX(200%); }
100% { transform: translateX(0%); }
}
which is triggered by the following JavaScript
$(function() {
// Go to home
$("#home-link").click(function(){
// Link appearance
$(this).addClass('active');
$('#about-link').removeClass('active');
// Slide in homepage
$('#home-page').removeClass('slideOutLeft');
$('#home-page').addClass('slideInLeft');
// Slide out about page
$('#about-page').removeClass('slideInRight');
$('#about-page').addClass('slideOutRight');
$('#about-page').addClass('hidden');
});
// Go to about slide
$("#about-link").click(function(){
// Link appearance
$(this).addClass('active');
$('#home-link').removeClass('active');
// Slide out homepage
$('#home-page').removeClass('slideInLeft');
$('#home-page').addClass('slideOutLeft');
$('#home-page').addClass('hidden');
// Slide in about page
$('#about-page').removeClass('slideOutRight');
$('#about-page').addClass('slideInRight');
});
});
You can see the problem at testing version of the site here.
Thanks for all of your help and advice.
First add a class item in your page containers
<div class="inner cover">
<div id="home-page" class="item">
<!-- content -->
</div>
<div id="about-page" class="item">
<!-- content -->
</div>
</div>
Add this block in your css
.inner.cover {
position: relative;
overflow: hidden;
height: 200px;
}
.item {
position: absolute;
top: 0;
left: 0;
width: 100%;
}

Show loading spinner before heavy processing in jQuery Mobile 1.1?

I'm going mad trying to get a spinner to appear. I've bound my heavy processing function to a button thus:
$(document).delegate("#clearread", "tap", onClearRead);
So on tap it calls this:
var onClearRead = function() {
setTimeout($.mobile.showPageLoadingMsg, 5);
// Civilised cleaning of saved status
var jStorIndex = $.jStorage.index();
for (var i = 0; i < jStorIndex.length; i++) {
if( jStorIndex[i] != "version" ) {
$.jStorage.deleteKey(jStorIndex[i]);
}
}
// Load articles afresh
loadArticles();
$.mobile.changePage("#choosearticle");
} //onClearRead
I find that the spinner does not appear during the clearing/loading of articles (about 10 secs) but only for a brief period while the #choosearticle page loads (0.5 secs).
What am I doing wrong?
I have the spinner working elsewhere in the app.
Thanks
Try this:
$(document).delegate("#clearread", "tap", onClearRead);
var onClearRead = function() {
$.mobile.showPageLoadingMsg();
setTimeout(function(){
//Your heavy processing
$.mobile.changePage("#choosearticle");
}, 5);
} //onClearRead
jQuery.show( [duration ] [, complete ] )
Putting the heavy processing in the "complete" function slot, ensures the object (with show called on it) is visible before the show happens.
Related SO Answers
https://stackoverflow.com/a/25207120/999943
jQuery whole HTML page load with spinner
Example using a CSS based spinner
CSS
#-moz-keyframes spin {
0% {
-moz-transform: rotate(0deg); }
100% {
-moz-transform: rotate(359deg); } }
#-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg); }
100% {
-webkit-transform: rotate(359deg); } }
#-o-keyframes spin {
0% {
-o-transform: rotate(0deg); }
100% {
-o-transform: rotate(359deg); } }
#-ms-keyframes spin {
0% {
-ms-transform: rotate(0deg); }
100% {
-ms-transform: rotate(359deg); } }
#keyframes spin {
0% {
transform: rotate(0deg); }
100% {
transform: rotate(359deg); } }
.icon-spin {
display: inline-block;
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
-webkit-animation: spin 2s infinite linear;
animation: spin 2s infinite linear; }
Html using font awesome
<div id="spinner" data-bind="visible: isSpinning" style="padding: 10px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: #cccccc; z-index: 1; filter: alpha(opacity=30);">
<i class="fa fa-spinner fa-spin fa-5x"></i>
</div>
Javascript
$('#spinner').show(100, function() {
// Once the spinner is visible then run the heavy function.
heavyProcessingFunction();
});

Categories