How to add transition when changing img src on hover? - javascript

So I'm trying to add a different image when the original image is hovered over using javascript. The syntax I have is similar to this, which works great.
function imgHover() {
projectImage.src = '../img/img1.png';
}
function imgHover2() {
projectImage.src = '../img/img2.png';
}
projectImage.addEventListener('mouseover', imgHover);
projectImage.addEventListener('mouseleave', imgHover2);
Now I'm trying to find a way to make the image transition from one to the other (most likely using opacity.) Any suggestions on how to do this? I can't figure it out.

You can't create a transition effect changing just the src tag of an image.
One way of doing this is to create two image that is positioned absolute on top of each other with the top one having an opacity of 0.
If you need to change the hover image dynamically, you can still do that through javascript.
.image-wrapper {
position: relative;
}
.image-hover {
position: absolute;
top: 0;
left: 0;
opacity: 0;
transition: opacity 1s ease-out;
}
.image-hover:hover {
opacity: 1;
}
<div class="image-wrapper">
<img src="http://via.placeholder.com/350x150?text=normal" class="image" alt="normal" />
<img src="http://via.placeholder.com/350x150?text=hover" class="image-hover" alt="hover" />
</div>

Related

How to make an image change to another one with a transition effect using vanilla Javascript?

on a website I'm creating I have some accordions, and each of them has an image at the top. When you open the accordion, there's a description inside, and the image changes to another one. Then when you close the accordion, the image switches back to the first one.
The problem is that I'd like this image change to have a smooth transition, with a fade effect, and right now it's just an abrupt change. How can I do it?
Let's say that the accordion button has an id of "button"; and the tag that contains the first image (which will change to the second image) has an id of "firstimage".
This is the code in Javascript:
let counter = 1;
let button = document.querySelector("#button");
button.addEventListener("click", function () {
let image = document.querySelector("#firstimage");
image.setAttribute(
"src",
"(url of the first image)"
);
counter++;
if (counter > 2) {
counter = 1;
image.setAttribute(
"src",
"(url of the second image)"
);
}
});
Maybe this is something I should edit in the CSS? I already tried adding a transition to the first image in CSS ( transition: all 360ms ease-in-out ) but it didn't work.
You can just put two images on top of one another and set the opacity.
document.querySelector('.wrapper').addEventListener("click", function (e) {
e.currentTarget.classList.toggle("active");
});
.wrapper {
position: relative;
display: inline-block;
}
.wrapper > img + img {
position: absolute;
left:0;
opacity: 0;
transition: opacity 2s ease-in-out;
}
.wrapper.active > img + img {
opacity: 1;
transition: opacity 2s ease-in-out;
}
<div class="wrapper">
<img src="http://placekitten.com/200/300" />
<img src="http://placekitten.com/g/200/300" />
</div>

How to detect a CSS transition with JS

EDIT
I tried animationstart and animationend. And what I found is that animationstart triggers right away then when keyframe reaches 100% animationend triggers and says the animation is finished. What I wanted to know is it possible to monitor what is happening in between or inside the animation? Like monitor each keyframe? Example as on this example I am running the animation for 4 images so when each image slides in can I monitor that and console.log("incoming image or something").
Is it possible to monitor each keyframe like when an image is sliding in?
I am trying to make image carousel. I have set it up with css animation so transition is happening in a loop with the css. Then after that I added two button's nextBtn and prevBtn. And they are doing their trick of sliding through the images. But I have a problem cant use both functionality I get displacement issues if I try to use both functionality if I press next to many times it messes it up basically, while the css is doing the looping animation effect. So I tried to disable the buttons when a transition has started with the eventlistener "transitionstart" but the problem with this is the javascript cant "hear or listen" if the css is doing the transition animation. But If i physically press on the button then js fires up the eventlistener off transitionstart. so how can I make javascript "hear/listen" to when the css file does the animation
here is some of the js transitionstart eventlistener code
slideContainer.addEventListener('transitionstart', () => {
console.log('transition has started') // it cant hear and is not listening when movement animation transition is comming from the css file but it fires up if i physically press the next button
document.getElementById("prev").setAttribute('disabled', true);
document.getElementById("next").setAttribute('disabled', true);
})
so how do you detect a css animation transition with javascript?
the html element I wrote as:
<div id="slider">
<figure>
<img src="./images/image-product-4.jpg" id="lastClone" alt="product-4" />
<img src="./images/image-product-1.jpg" id="product-1" alt="product-1" />
<img src="./images/image-product-2.jpg" id="product-2" alt="product-2" />
<img src="./images/image-product-3.jpg" id="product-3" alt="product-3" />
<img src="./images/image-product-4.jpg" id="product-4" alt="product-4" />
<img src="./images/image-product-1.jpg" id="firstClone" alt="product-1" />
</figure>
<img id="next" class="next pointer" src="./images/icon-next.svg" alt="next-img">
<img id="prev" class="previous pointer" src="./images/icon-previous.svg" alt="previous-img">
</div>
as on the beginning of my js file I have the following logic to skip the first id="lastClone" image
const slideContainer = document.querySelector('figure');
const slideImages = document.querySelectorAll('figure img');
// counter
let counter = 1;
let size = slideImages[0].clientWidth;
slideContainer.style.transform = 'translateX(' + (-size * counter) + 'px)';
// then here I want to listen for transitionstart
slideContainer.addEventListener('transitionstart', () => {
console.log('transition has started') // it cant hear and is not listening when movement happens from the css file
document.getElementById("prev").setAttribute('disabled', true);
document.getElementById("next").setAttribute('disabled', true);
})
// but it cant detect if the transition is done by the css animation
and here is my css
#slider {
overflow: hidden;
}
#slider figure {
width: 600%;
/* width: 100%; */
display: flex;
margin: 0;
left: 0;
animation: 50s slider infinite;
/* top: 50px; */
}
#slider figure img {
float: left;
width: 20%;
}
#keyframes slider {
0% { left: 0; }
20% { left: 0; }
25% { left: -100%; }
45% { left: -100%; }
50% { left: -200%; }
70% { left: -200%; }
75% { left: -300%; }
95% { left: -300%; }
100% { left: -400% }
}
figure {
position: relative;
height: 20rem;
overflow: hidden;
}
figure img {
object-fit: fill;
height: 100%;
}
Live example of my code:
https://jsfiddle.net/CustomHaven/51mLatkr/34/
EDIT
I tried animationstart and animationend. And what I found is that animationstart triggers right away then when keyframe reaches 100% animationend triggers and says the animation is finished. What I wanted to know is it possible to monitor what is happening in between or inside the animation? Like monitor each keyframe? Example as on this example I am running the animation for 4 images so when each image slides in can I monitor that and console.log("incoming image or something").
Is it possible to monitor each keyframe like when an image is sliding in?
you can try :
element.ontransitionstart = () => {
console.log('Started transitioning');
};
with element is : getElementById ....

Changing image on hover and back using fade

I'm trying to change an image on hover and back again.
The idea is that when I hover over an image, it fades into a different image and when my mouse leaves, the image fades back to the original.
Here is what I have tried so far, using jQuery:
<img src="https://www.shareicon.net/data/128x128/2015/08/17/86675_cat_256x256.png" />
<script>
$("img").hover(function(event) {
event.preventDefault();
console.log("hover");
$("img").fadeOut(400, function() {
$("img").attr("src", "http://files.softicons.com/download/animal-icons/meow-icon-set-by-iconka/png/128x128/cat_purr.png")
}).fadeIn(400, function() {
$("img").attr("src", "https://www.shareicon.net/data/128x128/2015/08/17/86675_cat_256x256.png")
});
});
</script>
You can actually do this with plain CSS and it would be more efficient.
Just create a div, put both images inside, absolute position so one is on top of another, and when hover apply opacity: 0 with a transition to the front image.
You can achieve this with position absolute, z-index, and hover pseudo selector.
.container{
width: 300px;
height: 300px;
position: relative;
}
img{
position: absolute;
top: 0;
left: 0;
}
.img-top{
z-index: 999999;
transition: 0.3s linear all;
}
.img-top:hover{
opacity: 0;
}
<div class="container">
<img class="img-bottom" src="https://www.cesarsway.com/sites/newcesarsway/files/d6/images/askthevet/checklist.jpg" alt="">
<img class="img-top" src="https://i.ebayimg.com/images/g/k2gAAOSwT5tWKhVS/s-l300.jpg" alt="">
</div>

Image on image overlay on hover with Javascript

I have a php sql query that will generate a lot of images, and I need a code that will overlay a semi transparent image on top of the original image on hover.
I've seen a lot of code to do this with CSS, but that will add a ton of html code that I don't think is needed. The query can return up to like 4000 results with 40x40 images and I need just one overlay image to overlay all of them (only the one hovering) on hover.
So technically, this is what I need
Javascript
find class or id iconoverlay
onhover overlay this transparent image
HTML
<img src="" class or id="iconoverlay" />
I'm currently using JQuery in my site but I'm not familiar with javascript.
If you have a span, a or similar block tag wrapping img. You can do this:
<a class="imgHover" href="#"><img src="" /></a>
<style>
.imgHover { display: inline-block; position: relative;}
.imgHover:after {content:''; width: 100%; height: 100%; background: #000 url('MyPlaceholderURI.jpg') no-repeat center center; display: block; position: absolute; top: 0; left: 0; opacity: 0; transition: opacity .5s linear; }
.imgHover:hover:after {opacity: 1}
</style>
You can see this in action here:
https://codepen.io/fabioarantes89/pen/rwMqNE
here's some code to float a div on hovering over an element:
function createTooltips(elem) {
if (!elem.getAttribute) return;
if (elem.getAttribute('tooltip')) {
$(elem).hover(
function (event) {
$('#tt').html(this.getAttribute('tooltip'));
$('#tt').css('left',(event.pageX + 10) + 'px');
$('#tt').css('top',event.pageY + 'px');
$('#tt').show();
},
function (event) {
$('#tt').hide();
});
}
for (var i = 0; i < elem.childNodes.length; i++) {
createTooltips(elem.childNodes[i], num);
}
}
createTooltips(document.body[0]);
All you need to do then if put your img tags into the "tooltip=" attribute and add to your page

How can I make this Jquery animate() with css3 animations?

This is my jfiddle
And this is my actual code
$card.animate({
left: "1000px"
}, 500, function(){
$card.hide(500);
});
(I dont know why 'left' didnt work on jfiddle) Basically ive got a container with 5 $cards there. When user swipes the card (already implemented) the animate() is triggered and the card slides to the rightand then disappears. How can I implement such thing in CSS animations instead of using Jquery? Ive read that CSS animations run faster (and I proved it on my mobile device, the hide() runs really slow)... Any help or advice will be appreciated
First of all, create a class that you can trigger via jQuery that will have the animation.
Then, using you have two options: transition or animation. Transitions are simpler and more direct, but you can do more with animations.
Here is how I would suggest to do it: a transition for the movement, and an animation to recreate the hide() function.
#keyframes hide {
99% { display: auto; }
100%{ display: none; opacity: 0; }
}
.myelement {
transition: all .5s;
position: absolute;
left: 0;
}
.myelement.toLeft {
left: 2000px;
animation: hide .5s 1 forwards;
}
To trigger it, simply do this:
$(".myelement").addClass("toLeft");
Here is a working JSFiddle.
And like #MohitBhardwaj said, it is necessary for you to set position to absolute, relative, or static in order for positioning (i.e., the left property) to work.
It's also important to note that a transition needs an initial value. I added left: 0 to do this. Otherwise, (with a CSS transition) it would simply jump to 2000px because there is no starting point.
Also, because 2000px as a left value is very large, I suggest you change the parent element's scroll to overflow: hidden, so that the extraneous scroll bar doesn't appear.
Your left didn't work, because you need to set position to a value other than static (which is default) for it to work.
As for using CSS, you can add a class instead of animating in jQuery. This class can change the transition which you can set in css as per your requirements.
var my_div = $('.myelement');
my_div.on('click', function() {
var $this = $(this);
$this.addClass("gone");
setTimeout(function(){
$this.hide();
}, 600 );
})
#mywrapper
{
overflow: hidden;
}
.myelement {
height: 200px;
width: 200px;
background-color: red;
opacity: 1;
position: relative;
transition: all 0.5s ease;
opacity: 1;
left: 0px;
}
.myelement.gone
{
left: 500px;
opacity: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="mywrapper">
<div class="myelement">
Click me please
</div>
</div>

Categories