loading animation not happening in container - javascript

I have a working example of a page loading animation when the user hits submit on the form here. Im trying to change the animation to something different but the newer animation is not happening inside the container and is loading even before the user hits submit on that form. The non working example can be found here
Can someone help me understand why this animation is not happening inside the container and why its being run when the page loads?
var myForm = document.getElementById('needs-validation');
myForm.addEventListener('submit', showLoader);
function showLoader(e) {
this.querySelector('.loader-container').style.display = 'block';
// the line below is just for the demo, it stops the form from submitting
// so that you can see it works. Don't use it
e.preventDefault();
}
#needs-validation {
/* .loader-container will be positionned relative to this */
position: relative;
}
.loader-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.loader {
display: block;
position: relative;
left: 50%;
top: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #9370DB;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
}
.loader:before {
content: "";
position: absolute;
top: 5px;
left: 5px;
right: 5px;
bottom: 5px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #BA55D3;
-webkit-animation: spin 3s linear infinite;
animation: spin 3s linear infinite;
}
.loader:after {
content: "";
position: absolute;
top: 15px;
left: 15px;
right: 15px;
bottom: 15px;
border-radius: 50%;
border: 3px solid transparent;
border-top-color: #FF00FF;
-webkit-animation: spin 1.5s linear infinite;
animation: spin 1.5s linear infinite;
}
#-webkit-keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#keyframes spin {
0% {
-webkit-transform: rotate(0deg);
-ms-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
-ms-transform: rotate(360deg);
transform: rotate(360deg);
}
}
<form id="needs-validation">
<p>First name: <input type="text"></p>
<p>Last name: <input type="text"></p>
<p>Age: <input type="text"></p>
<button type="submit">Next</button>
<!-- insert your loader container here, inside the <form> element -->
<div class="loader-container">
<div class="loader"></div>
</div>
</form>

There was something messy in your .loader-container
Actually only thing I have done, I haave taken this class from working solution and added into the new one and it works.
In your new solution, you are missing the display:none at first place.
Here is an updated solution for you.
https://jsfiddle.net/v9dhqvrc/

Related

How to run/pause an animation with holding down any key and letting it go?

I can't really figure out how to make this "rotating ball" start and stop its animation by holding down any key. Animation should only run while a key is pressed.
I have really tried to do research but only find code for jQuery which i don't know how to code. I think I miss some stuff for my Javascript but as you probably figured out by now, i am really new to this so i don't know whats missing.
(I know I've put the keypress on "Q" but i would like the Animation to start running while I push any key down and then pause if i let the key go. I also want the animation to run several times and not stop after 1 run.)
const start = document.querySelector("#ball");
const rot = document.querySelector("#roter");
window.addEventListener("keydown", spill)
function spill(event) {
if (event.key == "q") {
ball.style.animation = "rulle 4s linear running";
roter.style.animation = "roter 4s linear running";
} else {
ball.style.animation = "rulle 4s linear paused";
roter.style.animation = "roter 4s linear paused";
}
};
.linje{
width: 1000px;
height: 500px;
}
#ball{
position: relative;
top: 40px;
left: 0;
width: 100px;
height: 100px;
background-color: rgb(114, 240, 214);
border-radius: 50%;
animation-play-state: paused;
text-align: center;
line-height: 100px;
}
/*.ball:hover{
animation-play-state: paused;
}
-#roter:hover{
animation-play-state: paused;
} */
#keyframes rulle {
0%{
top: 40px;
left: 0;
transform: rotate(0deg);
}
12.5%{
top: 40px;
left: 50px;
transform: rotate(45deg);
}
25%{
top: 40px;
left: 100px;
transform: rotate(90deg);
}
37.5%{
top: 40px;
left: 150px;
transform: rotate(135deg);
}
50%{
top: 40px;
left: 200px;
transform: rotate(180deg);
}
62.5%{
top: 40px;
left: 250;
transform: rotate(225deg);
}
75%{
top: 40px;
left: 300px;
transform: rotate(270deg);
}
87.5%{
top: 40px;
left: 350px;
transform: rotate(315deg);
}
100%{
top: 40px;
left: 250px;
transform: rotate(360deg);
}
}
#roter{
animation-name: roter;
animation-play-state: paused;
}
#keyframes roter {
0%{
}
25%{
transform: rotate(90deg);
}
50%{
transform: rotate(180deg);
}
75%{
transform: rotate(270deg);
}
100%{
transform: rotate(360deg);
}
}
<div class="linje">
<div id="ball">
<p id="roter">161519</p>
</div>
</div>
Is this what you want? Run the snippet and check. Your css animation is not smooth. I don't have time to fix your animation but the following code do what you asked.
Note the js code here. In css, the animation is already applied and set the play state to paused so it's not playing at the beginning. Then, on keydown event, play state is changed to running and on keyup, it's changed back to paused.
Also, the other point you asked is running css animation forever. It can be addressed by animation-iteration-count: infinite or by using the shorthand animation: rulle 4s infinite linear; as I used here. Note the word infinite.
const start = document.querySelector("#ball");
const rot = document.querySelector("#roter");
window.addEventListener("keydown", () => {
ball.style.animationPlayState = "running";
roter.style.animationPlayState = "running";
})
window.addEventListener("keyup", () => {
ball.style.animationPlayState = "paused";
roter.style.animationPlayState = "paused";
})
.linje{
width: 1000px;
height: 500px;
}
#ball{
position: relative;
top: 40px;
left: 0;
width: 100px;
height: 100px;
background-color: rgb(114, 240, 214);
border-radius: 50%;
animation: rulle 4s infinite linear;
animation-play-state: paused;
text-align: center;
line-height: 100px;
}
#keyframes rulle {
0%{
top: 40px;
left: 0;
transform: rotate(0deg);
}
12.5%{
top: 40px;
left: 50px;
transform: rotate(45deg);
}
25%{
top: 40px;
left: 100px;
transform: rotate(90deg);
}
37.5%{
top: 40px;
left: 150px;
transform: rotate(135deg);
}
50%{
top: 40px;
left: 200px;
transform: rotate(180deg);
}
62.5%{
top: 40px;
left: 250;
transform: rotate(225deg);
}
75%{
top: 40px;
left: 300px;
transform: rotate(270deg);
}
87.5%{
top: 40px;
left: 350px;
transform: rotate(315deg);
}
100%{
top: 40px;
left: 250px;
transform: rotate(360deg);
}
}
#roter{
animation: roter 4s linear infinite;
animation-play-state: paused;
}
#keyframes roter {
0%{
}
25%{
transform: rotate(90deg);
}
50%{
transform: rotate(180deg);
}
75%{
transform: rotate(270deg);
}
100%{
transform: rotate(360deg);
}
}
<div class="linje">
<div id="ball">
<p id="roter">161519</p>
</div>
</div>
You need to listen to the "keyup" event to let go of the animation. event.key == "q" else doesn't mean that the Event.type was a "keyup".
Here's a simpler CSS and the needed (better) JS approach.
All you need is to toggle using JS the element's style animationPlayState value.
Also, while doing so make sure that the code is not being triggered on a long-press — by using evt.repeat:
const elBall = document.querySelector("#ball");
const toggleRoll = (evt) => {
if (evt.key !== "q" || evt.repeat) return;
elBall.style.animationPlayState = evt.type === "keydown" ? "running" : "paused";
};
addEventListener("keydown", toggleRoll);
addEventListener("keyup", toggleRoll);
#ball {
--size: 100px;
position: relative;
top: 40px;
width: var(--size);
height: var(--size);
line-height: var(--size);
border-radius: var(--size);
text-align: center;
background-color: rgb(114, 240, 214);
animation: roll 3s linear infinite alternate;
animation-play-state: paused;
}
#keyframes roll {
0% { transform: translateX(0px) rotate(0deg); }
100% { transform: translateX(300px) rotate(360deg); }
}
Click here to focus, then press key "q" to animate!
<div id="ball">161519</div>

How Can I Trigger a CSS keyframe animation in pseudo-element with Pure JavaScript?

I have a pseudo-element in my CSS and a keyframe animation I can run it using this:
.bottle:after
{
z-index: -500;
content: "";
position: absolute;
bottom: -95%;
left: -60%;
height: 130%;
width: 240%;
background: blue;
border-radius: 45%;
animation: spin 6s ease-in-out;
animation-fill-mode: forwards;
}
#keyframes spin
{
0% {transform: translateY(0) rotate(0deg);}
100% {transform: translateY(-50%) rotate(500deg);}
}
But I want this animation to be when the button is clicked.
An CSS pseudo element :active is what you need, no JavaScript is needed.
.button:active::after {
content: '';
position: absolute;
bottom: -95%;
left: -60%;
height: 130%;
width: 240%;
background: blue;
border-radius: 45%;
animation: spin 6s ease-in-out;
animation-fill-mode: forwards;
z-index: -500;
}
#-webkit-keyframes spin {
0% {
transform: translate(0, 0) rotate(0deg);
}
100% {
transform: translate(0, -50%) rotate(500deg);
}
}
#keyframes spin {
0% {
transform: translate(0, 0) rotate(0deg);
}
100% {
transform: translate(0, -50%) rotate(500deg);
}
}
add "active" to the button you want , also it's "::after" not ":after" .
.button:active::after {
z-index: -500;
content: "";
position: absolute;
bottom: -95%;
left: -60%;
height: 130%;
width: 240%;
background: blue;
border-radius: 45%;
animation: spin 6s ease-in-out;
animation-fill-mode: forwards;
}
#keyframes spin {
0% {
transform: translateY(0) rotate(0deg);
}
100% {
transform: translateY(-50%) rotate(500deg);
}
}
See an example below.
button = document.querySelector(".button");
// Add event listener to button
button.addEventListener("click", () => {
// Find first element with class = cl
bottle = document.querySelector(".cl");
// Add CSS class to first element with class = cl
bottle.classList.add("bottle");
});
.bottle:after {
z-index: -500;
content: "";
position: absolute;
bottom: -95%;
left: -60%;
height: 130%;
width: 240%;
background: blue;
border-radius: 45%;
animation: spin 6s ease-in-out;
animation-fill-mode: forwards;
}
#keyframes spin {
0% {
transform: translateY(0) rotate(0deg);
}
100% {
transform: translateY(-50%) rotate(500deg);
}
}
<div class="cl">Bottle</div>
<button class="button">Click</button>
If you really want this with "Pure JavaScript", then have a look at the Web Animation API:
document.querySelector("button").onclick = (evt) => {
// we can't target a pseudo element through DOM
// so we target its "owner"
const el = document.querySelector(".bottle");
el.animate(
[ // keyframes
{ transform: "translateY(0) rotate(0)" },
{ transform: "translateY(-50%) rotate(500deg)" }
],
{ // settings
pseudoElement: "::after", // target the pseudo element
duration: 6000,
easing: "ease-in-out",
fill: "forwards"
}
);
};
.bottle:after
{
z-index: -500;
content: "";
position: absolute;
bottom: -95%;
left: -60%;
height: 130%;
width: 240%;
background: blue;
border-radius: 45%;
}
<button>animate</button>
<div class="bottle"></div>

Transform Rotate not working on my CSS when I added keyframes [duplicate]

I have a situation similar to this fiddle, where I have a CSS3 animation that scales an element absolute-positioned in the centre of another element. However, when the animation takes place it is off-centre, as seen by the red squares relative to blue in the example. How do I centre it? I have tried a couple of configurations around the transform-origin property, but this isn't producing the correct results.
#keyframes ripple_large {
0% {transform:scale(1); }
75% {transform:scale(3); opacity:0.4;}
100% {transform:scale(4); opacity:0;}
}
.container {
position: relative;
display: inline-block;
margin: 10vmax;
}
.cat {
height: 20vmax;
}
.center-point {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 10px;
width: 10px;
background: blue;
}
.to-animate {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid red;
height: 5vmax;
width: 5vmax;
transform-origin:center;
}
.one {
animation: ripple_large 2s linear 0s infinite;
}
.two {
animation: ripple_large 2s linear 1s infinite;
}
<div class='container'>
<img src='http://www.catster.com/wp-content/uploads/2017/08/Pixiebob-cat.jpg' class='cat'>
<div class='center-point'>
</div>
<div class='to-animate one'></div>
<div class='to-animate two'></div>
</div>
The issue is that you are overriding the translate transformation.
When you specify a new transformation (the one inside the animation) it override the first one. In your case you are removing the translation that is fixing the center alignment.
You need to add them to the same transform property and pay attention to the order because it's important (Why does order of transforms matter? rotate/scale doesn't give the same result as scale/rotate)
#keyframes ripple_large {
0% {
transform: translate(-50%, -50%) scale(1);
}
75% {
transform: translate(-50%, -50%) scale(3);
opacity: 0.4;
}
100% {
transform: translate(-50%, -50%) scale(4);
opacity: 0;
}
}
.container {
position: relative;
display: inline-block;
margin: 10vmax;
}
.cat {
height: 20vmax;
}
.center-point {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 10px;
width: 10px;
background: blue;
transform-origin: center;
}
.to-animate {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 1px solid red;
height: 5vmax;
width: 5vmax;
}
.one {
-webkit-animation: ripple_large 2s linear 0s infinite;
animation: ripple_large 2s linear 0s infinite;
}
.two {
-webkit-animation: ripple_large 2s linear 1s infinite;
animation: ripple_large 2s linear 1s infinite;
}
<div class='container'>
<img src='http://www.catster.com/wp-content/uploads/2017/08/Pixiebob-cat.jpg' class='cat'>
<div class='center-point'>
</div>
<div class='to-animate one'></div>
<div class='to-animate two'></div>
</div>
UPDATE
As commented, it's better to center your element using another method than translation to avoid changing the animation since this can be used with other elements.
Example:
#keyframes ripple_large {
0% {
transform: scale(1) ;
}
75% {
transform:scale(3) ;
opacity: 0.4;
}
100% {
transform: scale(4) ;
opacity: 0;
}
}
.container {
position: relative;
display: inline-block;
margin: 10vmax;
}
.cat {
height: 20vmax;
}
.center-point {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 10px;
width: 10px;
background: blue;
transform-origin:center;
}
.to-animate {
position: absolute;
top: 0;
left: 0;
bottom:0;
right:0;
margin:auto;
border: 1px solid red;
height: 5vmax;
width: 5vmax;
}
.one {
animation: ripple_large 2s linear 0s infinite;
}
.two {
animation: ripple_large 2s linear 1s infinite;
}
<div class='container'>
<img src='http://www.catster.com/wp-content/uploads/2017/08/Pixiebob-cat.jpg' class='cat'>
<div class='center-point'>
</div>
<div class='to-animate one'></div>
<div class='to-animate two'></div>
</div>

Page loader not working in firefox

I have a page loader , it will load until my entire page loading complete ,this works fine with chrome but doesnt support in firefox .any other solutions welcome
<style>
#loading {width: 100%;height: 100%;top: 0px;left: 0px;position: fixed;display: block; z-index: 99}
#loading-image {position: absolute;top: 40%;left: 45%;z-index: 100}
</style>
<body>
<div id="loading">
<img id="loading-image" src="images/loader.gif" alt="Loading..." />
</div>
<script>
window.onload = function(){ document.getElementById("loading").style.display = "none" }
</script>
</body>
this is a complete ansower for u :)
#loader {
position: absolute;
left: 50%;
top: 50%;
z-index: 30;
margin: -75px 0 0 -75px;
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #3498db;
width: 120px;
height: 120px;
-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;
display:block;
}
#-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}
#keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
that was the style now the body
<div id="loader"></div>
hope it helps :)

Rails: Infinite Scroll, load spinner instead of text

All works properly, but I want to show a spinner loading instead of text. This is my code in Page.js.coffee:
jQuery ->
if $('.pagination').length
$(window).scroll ->
url = $('.pagination .next_page').attr('href')
if url && $(window).scrollTop() > $(document).height() - $(window).height() - 50
$('.pagination').text("Fetching more...")
$.getScript(url)
$(window).scroll().
This line show the text:
$('.pagination').text("Fetching more...")
Thank you guys.
Perhaps css #keyframes suits just fine for your case, you can check possible implementation here https://projects.lukehaas.me/css-loaders/
for example you can take
.loader,
.loader:before,
.loader:after {
border-radius: 50%;
}
.loader {
color: #ffffff;
font-size: 11px;
text-indent: -99999em;
margin: 55px auto;
position: relative;
width: 10em;
height: 10em;
box-shadow: inset 0 0 0 1em;
-webkit-transform: translateZ(0);
-ms-transform: translateZ(0);
transform: translateZ(0);
}
.loader:before,
.loader:after {
position: absolute;
content: '';
}
.loader:before {
width: 5.2em;
height: 10.2em;
background: #0dc5c1;
border-radius: 10.2em 0 0 10.2em;
top: -0.1em;
left: -0.1em;
-webkit-transform-origin: 5.2em 5.1em;
transform-origin: 5.2em 5.1em;
-webkit-animation: load2 2s infinite ease 1.5s;
animation: load2 2s infinite ease 1.5s;
}
.loader:after {
width: 5.2em;
height: 10.2em;
background: #0dc5c1;
border-radius: 0 10.2em 10.2em 0;
top: -0.1em;
left: 5.1em;
-webkit-transform-origin: 0px 5.1em;
transform-origin: 0px 5.1em;
-webkit-animation: load2 2s infinite ease;
animation: load2 2s infinite ease;
}
#-webkit-keyframes load2 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
#keyframes load2 {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(360deg);
transform: rotate(360deg);
}
}
and then in your coffescript just add and remove the class "loader" loading div, or add/remove div with such a class.
<div class="loader">Loading...</div>

Categories

Resources