Reputation: 1792
I've been trying to create a fadeIn & fadeOut animation using VanillaJS in my project but I literally don't understand what's the problem. I'm using SCSS. I made it simple for you.
I tried visibility
but it didn't work too. like it appears e.g. for 200ms
but then immediately disappears. In another way of explanation, it appears whenever I click on it (stable) and then goes away after 200ms
(unstable).
const fade = () => {
const box = document.querySelector('#box');
box.classList.toggle('fade');
};
document.querySelector('#fadebtn').addEventListener('click', fade);
#box {
width: 70px;
height: 50px;
background: #FD7A6B;
display: none;
opacity: 0;
-webkit-transition: 200ms ease-in-out;
-moz-transition: 200ms ease-in-out;
-o-transition: 200ms ease-in-out;
transition: 200ms ease-in-out;
}
#box.fade {
display: block !important;
opacity: 1 !important;
}
// I also tried this, wondered it may work, but didn't.
// .fade {
// display: block !important;
// opacity: 1 !important;
// }
<button type="button" id="fadebtn">Fade</button>
<div id="box"></div>
Upvotes: 1
Views: 4201
Reputation: 1206
I wrote this due to the title of the question: "Fade in ... pure javascript ... simple way."
tl;dr https://jsfiddle.net/nqfud4j0/
The following solution is a basic example of how you can use only Javascript to fade in/out to a desired value. You could also use this with other values/properties, but it also serves as an example for basic tweening.
It's intentionally using setInterval rather than requestAnimationFrame to demonstrate the example's use of time + controlled framerate rather than a delta or 'fast as possible.' A good solution would abstract this logic into a tweening library that combines both RAF + intervals to manage latency between frames.
function fadeTo(element, toValue = 0, duration = 200) {
// Store our element's current opacity (or default to 1 if null)
const fromValue = parseFloat(element.style.opacity) || 1;
// Mark the start time (in ms). We use this to calculate a ratio
// over time that applied to our supplied duration argument
const startTime = Date.now();
// Determines time (ms) between each frame. Sometimes you may not
// want a full 60 fps for performance reasons or aesthetic
const framerate = 1000 / 60; // 60fps
// Store reference to interval (number) so we can clear it later
let interval = setInterval(() => {
const currentTime = Date.now();
// This creates a normalized number between now vs when we
// started and how far into our desired duration it goes
const timeDiff = (currentTime - startTime) / duration;
// Interpolate our values using the ratio from above
const value = fromValue - (fromValue - toValue) * timeDiff;
// If our ratio is >= 1, then we're done.. so stop processing
if (timeDiff >= 1) {
clearInterval(interval);
interval = 0;
}
// Apply visual. Style attributes are strings.
element.style.opacity = value.toString();
}, framerate)
}
// Element reference
const element = document.querySelector('div');
// Fade in and out on click
element.addEventListener('click', e => {
// Animates our element from current opacity (1.0) to 0.25 for 1000ms
fadeTo(element, 0.25, 1000);
// Waits 1s, then animates our element's opacity to 1.0 for 500ms
setTimeout(() => {
fadeTo(element, 1.0, 500);
}, 1000);
});
Upvotes: 3