How can I control CSS transitions and animations with JS? - javascript

I have an image that goes from opacity 0 to 1 when a bit of text is hovered. I would like the transition to be smooth, something similar to CSS transition. Can't really figure out how to make this happen, so any help would be appreciated.
The JavaScript looks like this:
document.getElementById("text-hover").addEventListener("mouseover", imageTransition);
document.getElementById("text-hover").addEventListener("mouseout", imageTransitionOut);
function imageTransition() {
document.getElementById("pic").style.opacity = "1";
}
function imageTransitionOut() {
document.getElementById("pic").style.opacity = "0";
}

Just define the transition in css, it will trigger when you change the opacity value in javascript:
#pic {
transition: opacity .3s;
opacity: 0;
}
You don't need to change your javascript
Update
If you need to animate more than one property, it is better to define the animation in css and then trigger it from javascript by toggling a class on the element
the css:
#pic {
transition: all .3s;
opacity: 0;
transform: scale(.1);
}
#pic.animate {
opacity: 1;
transform: scale(1);
}
javascript:
var textHover = document.getElementById("text-hover");
var pic = document.getElementById("pic");
textHover.addEventListener("mouseover", function() {
pic.classList.add('animate');
});
textHover.addEventListener("mouseout", function() {
pic.classList.remove('animate');
});

Related

How to Append image to div, and fade image in over 1 second?

I am trying to append an image to my div "gamecol", but I want to fade-in, not just appear immediately. Do I need to write a JavaScript function, or is there a method that I can use with css? Thanks for the help.
Here is my code:
var img = document.createElement("img");
img.src = "./images/tbltop.jpg";
img.id = "gameboard"
var gamecol = document.getElementById("gamecol");
gamecol.appendChild(img)
<div class="col-8" id="gamecol" style="padding:0"></div>
You can achieve that with css, depending on the functionality you want, of course.
If you want it to fade in when the image enters to the screen view, you'll need javascipt.
If not, you only need to tell that, when the item is appended, you use CSS 3 animations to make it appear.
It could look like this:
.game-img
{
animation: fadein 1s;
}
#keyframes fadein {
from { opacity: 0; }
to { opacity: 1; }
}
You can try with CSS3 properties of #keyframes(animation). I'm appending same image with help of setTimeout function for checking fadein effect. So it's working and easy to use.
function TwoImages(){
var img = document.createElement("img");
img.src = "https://i.stack.imgur.com/fcbpv.jpg";
img.id = "gameboard";
var gamecol = document.getElementById("gamecol");
gamecol.appendChild(img)
}
TwoImages();
setTimeout(function(){
TwoImages();
},2500);
.fade-in img{
animation: fadein 1s linear;
}
#keyframes fadein {
0% { opacity: 0 }
100% { opacity: 1 }
}
<div id="gamecol" class="fade-in"></div>

Why animation play state is always running?

I couldn't get the animation play state to be paused with css3 animation even after using animation-iteration-count to 1 and animation-fill-mode to forwards:
var isRunning = window.getComputedStyle(
document.querySelector('div')
).getPropertyValue('animation-play-state');
setInterval(function(){
console.log(isRunning);
},1000)
#keyframes foo {
0% {
width: 0;
}
100% {
width: 50%;
}
}
div {
animation: foo 2s linear 0s 1 normal forwards;
background-color: #f00;
height: 3px;
}
<div></div>
I should get animation-play-state to be paused when it finishes the animation.
Actually, the following answer that I provided doesn't work for me. In fact, I was working with a pseudo element and pseudo element doesn't accept addEventListener. So, my final solution would be to use this only way.
var isRunning = window.getComputedStyle(
document.querySelector('div'), ':after'
).getPropertyValue('animation-play-state');
Sadly, CSS doesn't seem to set play state to paused when animation is finished. To conclude this question has no findings or solution?
The value of animation-play-state doesn't change once an animation finishes all its iterations.
You'll need to listen for the animationend event and change the value manually:
document.querySelector('div').addEventListener('animationend', function() {
this.style.animationPlayState = 'paused';
console.log(window.getComputedStyle(this).getPropertyValue('animation-play-state'));
});
#keyframes foo {
0% {
width: 0;
}
100% {
width: 50%;
}
}
#foo {
animation: foo 2s linear 0s 1 normal forwards;
background-color: #f00;
height: 3px;
}
<div id=foo></div>
... though I don't really see any reason to do so when your animation-fill-mode is already set to forwards.
I don't know why css3 keeps animation play state to running but go with the animationend event:
var x = document.getElementById("myDIV");
x.addEventListener("animationend", function(){
console.log('paused'); // animation is end
});
Here's the reference for animationend: https://developer.mozilla.org/en-US/docs/Web/Events/animationend

Vanilla Javascript - Animation with different timing

I would like to make an animation using onscroll in Vanilla Javascript. I have 2 classes. The first one is .photography_box which is active and the second one is .photography_box_active which is not active. When i scroll down to 1500px my second class .photography_box_active kicks in and my animation is working great. My .photography_box consist of 12 boxes. When the animation happens all of them come in at the same time which is not what i want. I would like each one of them to come in one after the other. In jQuery i could use $.each but i would like to have the same effect using Vanilla Javascript. Can someone help me solve the problem?
Thanks
CSS code for my classes :
.photography_box {
overflow: hidden;
position:relative;
cursor: pointer;
margin-bottom:20px;
opacity: 0;
cursor: pointer;
-webkit-transform:translateX(-50px);
transform:translateX(-50px);
-webkit-transition: all .3s ease-in-out;
transition: all .3s ease-in-out;
}
.photography_box_active {
opacity: 1;
-webkit-transform: translateX(0px);
transform: translateX(0px);
}
JS code is :
var photoBox = document.getElementsByClassName("photography_box");
window.onscroll = function() {
loopBox()
};
function loopBox(){
if ( window.pageYOffset > 1500 ){
for ( f = 0; f <= photoBox.length -1; f++ ) {
photoBox[f].classList.add("photography_box_active");
};
};
};
You can use setTimeout in your loop to delay the animation for each item based on its index. So if you want a delay of 150ms:
for ( f = 0; f < photoBox.length; f++ ) {
setTimeout(function(){
photoBox[f].classList.add("photography_box_active");
}, 150 * f);
}
Note that as you know in advance the number of items, and as you are using css transitions, this could be done purely in css, keeping your existing js code. Supposing your .photography_box items are in a .box container
.box .photography_box:nth-child(1) { transition-delay: 0 }
.box .photography_box:nth-child(2) { transition-delay: 0.05s }
// and so on...
quite cumbersome to write, especially with vendor-prefixes, but nothing annoying if you are using a css preprocessor like sass
Example: array.forEach(callback[, thisArg])
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

How to remove a div with fade out effect in JavaScript?

I want to remove a div element on click event but i want to remove it with a fade out effect. I have got some JQuery solution but i need pure JavaScript or css solution.
document.querySelector('.list').addEventListener("click", function(e){
if (e.target.localName === "span") {
var removeTarget = e.target.parentNode.parentNode;
removeTarget.parentNode.removeChild(removeTarget);
};
});
This code is removing the div element with no effect. How can i add a fade out effect?
I've made this function a while ago for a personal project:
function removeFadeOut( el, speed ) {
var seconds = speed/1000;
el.style.transition = "opacity "+seconds+"s ease";
el.style.opacity = 0;
setTimeout(function() {
el.parentNode.removeChild(el);
}, speed);
}
removeFadeOut(document.getElementById('test'), 2000);
There are two ways you can achieve this: CSS3 animation or jQuery animation.
CSS3 Animation
In your CSS document, add:
.list {
opacity: 1;
-webkit-transition: opacity 1000ms linear;
transition: opacity 1000ms linear;
}
This will make any change of opacity to your item fade by 1000ms.
Change line 4 of your JavaScript to:
removeTarget.style.opacity = '0';
setTimeout(() => removeTarget.remove(), 1000);
This will make your item change opacity to 0, thus making the transition from step 1 have an effect. Then it will remove the item with your code after 1000ms.
Note: Make sure the time of the CSS3 transition and the setTimeout are the same.
jQuery Animation
Get jQuery
Go to the jQuery Website and download it, or
Add ` in your HTML document before any jQuery code.
Change line 4 of your Javascript to:
removeTarget.fadeOut(1000)
This will Fade Out your item by 1000ms, you can change this time to whatever you want.
In 2020 you can forgo use of use setTimeout for the animationend event, removing the need to maintain the duration in two places:
.fade-out {
animation: fade 2s;
-webkit-animation: fade 2s;
-moz-animation: fade 2s;
}
/* Animate opacity */
#keyframes fade {
from { opacity: 1 }
to { opacity: 0 }
}
#-moz-keyframes fade {
from { opacity: 1 }
to { opacity: 0 }
}
#-webkit-keyframes fade {
from { opacity: 1 }
to { opacity: 0 }
}
const elementToFade = document.getElementById('my-element');
elementToFade.onanimationend = (e) => {
if (e.target.classList.contains('fade-out')) {
elementToFade.parentNode.removeChild(elementToFade);
}
};
// To fade away:
elementToFade.classList.add('fade-out');
It's a good question, but to animate some element in html, this element has to exist while it is animating. So, you have some ways to do this, a good way is hide this element with CSS and after the animation you remove this element. While you hiding you can animate, you can see this example:
<style>
.hide{
opacity: 0;
}
.fade-out {
transition:1s linear all;
}
</style>
<span class="list fade-out">
This is a List, click me to hide
</span>
<script>
document.querySelector('.list').addEventListener("click", function(e) {
if (e.target.localName === "span") {
//Add CSS hide and animate with fade out
var currentCSS = this.className;
this.className = currentCSS + ' hide';
var removeTarget = e.target.parentNode.parentNode;
setTimeout(function(){
removeTarget.parentNode.removeChild(removeTarget);
},1000);
};
});
</script>
Add the following CSS class to the element using elem.className="my-animation"; on click:
.my-animation {
animation: fade 3s steps(90) forwards;
-webkit-animation: fade 3s steps(90) forwards;
-moz-animation: fade 3s steps(90) forwards;
}
#keyframes fade {
from {
opacity: 1;
}
to {
opacity: 0.0;
}
}
You may control the speed of the animation by modifying the steps(number) as well.
Just goto jQuery source code, take out the fade code which is in pure javascript, and use it, no need to reinvent the wheel,
or a hint is reduce the height of div to 0 slowly using setTimeInterval()
or a css solution would be to use transform and transition properties

How to make a div fade on hover?

Hi I currently have span that displays over an image on hover, however I want to use a bit of javascript or css transitions to make this div fade in to about 0.8 opacity on hover then back to 0 when the mouse is not hovering.
Here is an example of how I have it setup so far, now all thats needed is the fade and 0.8 opacity:
How its setup - Jsfiddle
Im sure there is a simple bit of code that someone has to do this
Help is much appreciated thanks!
So... here's the CSS3 / HTML5-way to do this. This won't work in IE though: it will fall back on the regular, immediate way (so it does work, it just isn't as smooth as it is in the real browsers).
div.yourDiv {
-webkit-transition: .4s ease-in-out opacity;
-moz-transition: .4s ease-in-out opacity;
-o-transition: .4s ease-in-out opacity;
transition: .4s ease-in-out opacity;
}
div.yourDiv:hover {
opacity: 0.8;
}
Since CSS3-transitions are using hardware-accerelation, this really is very smooth! Besides that, you don't even need any Javascript or jQuery for this =)!
You can use CSS's :hover pseudo-class, unless you need to support IE6:
.image-hover:hover {
opacity: .8;
}
* html .image-hover:hover { /* For IE7 and higher */
filter: alpha(opacity=80);
}
That won't fade to 80%, though, it'll just go there immediately. To do that, you can use jQuery's hover and animate functions (edit: or fadeTo, which is just a convenience wrapper for animate on opacity as shown below):
$(".image-hover").hover(
function() {
$(this).stop().animate({opacity: "0.8"});
},
function() {
$(this).stop().animate({opacity: "1"});
}
);
It's not clear from your question what the text in the span is supposed to be doing, but those are the tools to get you started.
Here's an updated version of your fiddle showing the animation; I've used 0.6 rather than 0.8 just so it's more obvious.
.classa
{
opacity:0.8;
}
you can addClass and removeClass like
$("div.image-hover").hover(
function(){
//fadein
$(this).addClass("classa");
},
function(){
//fadeout
$(this).removeClass("classa");
}
);
here is the fiddle http://jsfiddle.net/2RN6E/8/
EDITED after the comment below
you can use fadeTo
$("div.image-hover").hover(
function(){
//fadein
$(this).fadeTo( "2000", "0.8");
},
function(){
//fadeout
$(this).fadeTo( "2000","1");
}
here is the fiddle http://jsfiddle.net/2RN6E/14/
);
You could do:
function fadein() {
$('.desc').animate({
opacity: 0.8,
}, 1000, function() {
// Animation complete.
})
}
function fadeout() {
$('.desc').animate({
opacity: 0,
}, 1000, function() {
// Animation complete.
})
}
$('.image-hover').hover(fadein, fadeout);
fiddle here: http://jsfiddle.net/nicolapeluchetti/2RN6E/9/
This code retains the block display for the description element: http://jsfiddle.net/2RN6E/11/
It just uses the animate function of jQuery:
$(".image-hover").hover(function() {
$(".desc").animate({opacity: '0.75'},'slow');
}, function() {
$(".desc").animate({opacity: '0'},'slow');
});

Categories