Trying to make different hover animations for multiple images in css - javascript

So i have a few images in HTML like this
<div class="thumb">
<img src="image1.jpg" alt="name1">
<img src="image2.jpg" alt="name2">
<img src="image3.jpg" alt="name3">
</div>
I'm trying to make them have a specific hover effect - when you hover on image1, image1 gets bigger and image2 and image3 get smaller and with reduced opacity. This is an example with only three images but in reality i have varying number of images on different pages.
I tried this in CSS but it doesn't seem to work properly. The problem is the first effect is triggered whenever the mouse is above .thumb and not above an image, but i haven't found a way to adress all images other than the one which is being hovered.
.thumb:hover img {
opacity: .25;
transform: scale(.8);
}
.thumb img:hover {
opacity: 1;
transform: scale(1.2);
}
I prefer to have it in CSS but if it requires javascript it's ok. Any help will be appreciated.

Maybe you are after sibling selector:
.thumb{
display: inline-block;
}
.thumb:hover img{
opacity: .25;
transform: scale(.8);
transition: opacity 1s, transform 1s;
}
.thumb a:hover img{
opacity: 1;
transform: scale(1.2);
}
<div class="thumb">
<img src="http://placehold.it/100x100/6666ff" alt="name1">
<img src="http://placehold.it/100x100/ff6666" alt="name2">
<img src="http://placehold.it/100x100/66ff66" alt="name3">
</div>
UPDATE
If you are after a JS solution it would be something like this:
$('.thumb a').hover(function(){
$(this).siblings().addClass('shrink').removeClass('grow');
$(this).addClass('grow').removeClass('shrink');
}, function(){
$(this).siblings().removeClass('shrink');
$(this).removeClass('grow');
});
.thumb a{
margin: 20px;
}
.thumb a.shrink img{
opacity: .25;
transform: scale(.8);
transition: opacity 1s, transform 1s;
}
.thumb a.grow img{
opacity: 1;
transform: scale(1.2);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class="thumb">
<img src="http://placehold.it/100x100/6666ff" alt="name1">
<img src="http://placehold.it/100x100/ff6666" alt="name2">
<img src="http://placehold.it/100x100/66ff66" alt="name3">
</div>

This can now be done directly with css using ::has pseudo class: https://developer.mozilla.org/en-US/docs/Web/CSS/:has
(Currently only available in safari, with other browsers' support rolling out)

have you tried to add particular classes for different type of hover that you want and add them in the img tags that you like?
.thumb img.opacity-1:hover {
opacity: 1;
transform: scale(1.2);
}
.thumb img.opacity-05:hover {
opacity: 0.5;
transform: scale(1.2);
}

This will work for you.
.thumb img {
opacity: 0.25;
transform: scale(0.8);
}
.thumb img:hover {
opacity: 1;
transform: scale(1.2);
}

Related

Slick Slider with ken-burns-out image jumps bug

After the slide animation (scale(1.3) to scale(1)) finishes and moving back to the slide I get this annoying jump.
I want that each active slide will be already in scale(1.3) without the jump.
$('.home-slider').slick({
slidesToScroll: 1,
slidesToShow: 1,
//arrows: true,
autoplay: true,
autoplaySpeed: 7000,
dots: false
})
body,
html {
height: 100%;
background: #333;
font-family: 'Roboto', sans-serif;
}
.slideshow {
position: relative;
z-index: 1;
height: 100%;
max-width: 700px;
margin: 50px auto;
}
.slideshow .item {
height: 100%;
position: relative;
z-index: 1;
}
.slideshow .item img {
width: 100%;
}
.slideshow .item.slick-active img {
-webkit-animation: ken-burns-out 8s 1 ease-in-out forwards;
animation: ken-burns-out 8s 1 ease-in-out forwards;
}
/*//The animation: from 1.3 scale to 1*/
#-webkit-keyframes ken-burns-out {
0% {
-webkit-transform: scale(1.3);
transform: scale(1.3)
}
to {
-webkit-transform: scale(1);
transform: scale(1)
}
}
#keyframes ken-burns-out {
0% {
-webkit-transform: scale(1.3);
transform: scale(1.3)
}
to {
-webkit-transform: scale(1);
transform: scale(1)
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.js"></script>
<div class="slideshow">
<div class="home-slider">
<div class="item">
<img src="https://images.unsplash.com/photo-1532386236358-a33d8a9434e3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=978&q=80" />
</div>
<div class="item">
<img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
</div>
</div>
</div>
The problem happens because all of the images gets the same z-index.
My code doesn't work when you navigate from first slide to last slide (slide right), but it's something to start with.
first of all, delete the z-index from this selector: .slideshow .item.
Then, add transform to every image in order every image to start with this scale (maybe add class name to each image and then change the selector):
img {
transform: scale(1.3);
}
Add a function to get slick by index (there are cloned slicks elements so I use the selector that gets un-cloned slicks):
function getSlickByIndex(index) {
return $('.item:not(.slick-cloned)[data-slick-index="' + index + '"]');
}
Then, add init event (the logic makes the first slide to get the bigger zIndex=1 of all of his siblings that have zIndex=0), and beforeChange (the logic makes the next slick to get the bigger index and the others to get the smaller index):
$('.home-slider').on('init', function(event, slick){
getSlickByIndex(0).css('zIndex', '1');
}).on('beforeChange', function(event, slick, currentSlide, nextSlide){
getSlickByIndex(currentSlide).css('zIndex', '0');
getSlickByIndex(nextSlide).css('zIndex', '1');
});
Demo
img {
transform: scale(1.3);
}
body,
html {
height: 100%;
background: #333;
font-family: 'Roboto', sans-serif;
}
.slideshow {
position: relative;
z-index: 1;
height: 100%;
max-width: 700px;
margin: 50px auto;
}
.slideshow .item {
height: 100%;
position: relative;
z-index: 1;
}
.slideshow .item img {
width: 100%;
}
.slideshow .item.slick-active img {
-webkit-animation: ken-burns-out 8s 1 ease-in-out forwards;
animation: ken-burns-out 8s 1 ease-in-out forwards;
}
/*//The animation: from 1.3 scale to 1*/
#-webkit-keyframes ken-burns-out {
0% {
-webkit-transform: scale(1.3);
transform: scale(1.3)
}
to {
-webkit-transform: scale(1);
transform: scale(1)
}
}
#keyframes ken-burns-out {
0% {
-webkit-transform: scale(1.3);
transform: scale(1.3)
}
to {
-webkit-transform: scale(1);
transform: scale(1)
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.js"></script>
<div class="slideshow">
<div class="home-slider">
<div class="item">
<img src="https://images.unsplash.com/photo-1532386236358-a33d8a9434e3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=978&q=80" />
</div>
<div class="item">
<img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
</div>
<div class="item">
<img src="https://images.unsplash.com/photo-1532386236358-a33d8a9434e3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=978&q=80" />
</div>
<div class="item">
<img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
</div>
</div>
</div>
<script>
function getSlickByIndex(index) {
return $('.item:not(.slick-cloned)[data-slick-index="' + index + '"]');
}
$('.home-slider').on('init', function(event, slick){
getSlickByIndex(0).css('zIndex', '5555');
}).on('beforeChange', function(event, slick, currentSlide, nextSlide){
getSlickByIndex(currentSlide).css('zIndex', '0');
getSlickByIndex(nextSlide).css('zIndex', '5555');
});
$('.home-slider').slick({
slidesToScroll: 1,
slidesToShow: 1,
//arrows: true,
autoplay: true,
autoplaySpeed: 7000,
dots: false
});
</script>
This is a working fiddle: https://codepen.io/alonsh/pen/JQmZjj
Your images are starting with a scale of 1, then when they become active the animation starts them off at 1.3 which is what causes the jump. What you need to do is start all the images off at a scale(1.3) by adding this to the .item img css definition.
Doing only that causes the images to overflow onto one another. To combat that make sure the contents of each .item don't overflow by adding overflow: hidden which results in:
EDIT
Which results in code which still doesn't quite work correctly. We still need everything from the previous answer but we end up with the opposite issue where the images jump to the fully zoomed size when they're switched off.
This became a bit of a rabbit hole, but there is an animation-play-state property in css which we can use to pause the animation at the state it is in when an item becomes inactive, so I made the animation play on every .item element, which means that when it's scrolled away and the active class is lost, it will pause the animation where it is.
This almost gets us to the desired result, but then when an image is brought back into view, it resumes from where it has left off. It turns out there isn't a pretty way to get a css animation to restart, so what I'm doing is I've bound to the slide change event for slick and when a slide has changed (which I believe guarantees only the active slide is visible) I reset the .item animation. In order to do this in a way which doesn't interrupt the active slide I've added a class .animated which I can remove, then add back later in a setTimeout. The delay is needed in order for the animation to restart.
You'd hope that was the end, but you'd be wrong. THEN Slick considers a started swipe, which then lands back on the same image to be a slide change ("change") so I added a current slide variable to keep track of which slide we are on and only reset the .animated class if the slide did actually change. Important Note: in a real project I would wrap this currentSlide in some sort of class/object to track the state of an individual slideshow, because as it stands you couldn't have more than one slideshow on a single page without them interfering. But I wasn't going to write all of that for a simple example.
After all of this, we end up with slightly different CSS and a bit more JS to get a working result:
$('.home-slider').slick({
slidesToScroll: 1,
slidesToShow: 1,
//arrows: true,
autoplay: true,
autoplaySpeed: 7000,
dots: false
});
var currentSlide = 0;
$('.home-slider').on('afterChange', function(event, slick, newSlide){
var items = $('.home-slider .item');
if(currentSlide != newSlide){
currentSlide = newSlide;
items.removeClass('animated');
setTimeout(function(){
items.addClass('animated');
});
}
});
body,
html {
height: 100%;
background: #333;
font-family: 'Roboto', sans-serif;
}
.slideshow {
position: relative;
z-index: 1;
height: 100%;
max-width: 700px;
margin: 50px auto;
}
.slideshow .item {
height: 100%;
position: relative;
overflow: hidden;
}
.slideshow .item img {
width: 100%;
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
.slideshow .item.animated img {
-webkit-animation: ken-burns-out 8s 1 ease-in-out forwards;
animation: ken-burns-out 8s 1 ease-in-out forwards;
animation-play-state: paused;
}
.slideshow .item.slick-active img {
animation-play-state: running;
}
/*//The animation: from 1.3 scale to 1*/
#-webkit-keyframes ken-burns-out {
0% {
-webkit-transform: scale(1.3);
transform: scale(1.3);
}
to {
-webkit-transform: scale(1);
transform: scale(1)
}
}
#keyframes ken-burns-out {
0% {
-webkit-transform: scale(1.3);
transform: scale(1.3)
}
to {
-webkit-transform: scale(1);
transform: scale(1)
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery-easing/1.3/jquery.easing.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.js"></script>
<div class="slideshow">
<div class="home-slider">
<div class="item animated">
<img src="https://images.unsplash.com/photo-1532386236358-a33d8a9434e3?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=978&q=80" />
</div>
<div class="item animated">
<img src="https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1050&q=80" />
</div>
</div>
</div>

how to make transition of stacked Divs. in JavaScript

i am trying to make "memory game" using html5, CSS3 and JS. I have completed the view and model part of this game and now trying to make the Controller. What i want is call a function i.e. flip in JS and want that function to perform transition instead of using hover effect of CSS3. Basically i am trying to follow this approach. I checked that flipping in css3 using hover as can be seen in sass code below, but for the game, the user decides where to click. For simplicity, i have concised the code in html5 since it repeats for all other divs.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>I Don't Know</title>
<link rel="stylesheet" href="trapStyle.css">
</head>
<body>
<div class = "container" >
<div class="sub1" >
<div class="front" id="card1" onclick="flip(card1)">card1</div>
<div class="back" id="card1_1">what the hell?</div>
</div> <--sub1 Ends-->
<div class="sub1">
<div class="front" id="card2" onclick="flip(this)">card2</div>
<div class="back" id="card2_2">what the hell?
</div> <--sub1 Ends-->
</div> <-- container Ends -->
<script src ="script.js"></script>
</body>
</html>
and the SASS code for css
.container {
position: absolute;
left: 115px;
width: 1150px;
height: 700px;
background-color: silver;
/* SUB-CONTAINER to stack two cards */
.sub1 {
width: 200px; height: 200px;
float:left; margin: 5px;
.front {
position:absolute; width: 200px; height: 200px;
background-color: #498010;
transform: perspective( 600px) rotateY(0deg);
backface-visibility: hidden;
transition: transform 0.5s linear 0s;
}
.back {
position: absolute; width: 200px; height: 200px;
float:left; background-color: #689;
transform: perspective( 600px) rotateY(180deg);
backface-visibility: hidden;
transition: transform 0.5s linear 0s;
}
}
.sub1:hover > .front {
/* transform: perspective(600px) rotateY(-180deg); */
}
.sub1:hover > .back {
/* transform: perspective(600px) rotateY(0deg); */
}
}
and JavaScript
function flip(front) {
document.getElementById("front").style.transition = opacity 0.5s linear 0s;
document.getElementById("front").style.opacity = 0;
}
Note: the link, above, is trying to pass id to JS function where the transition takes place. Exactly same is being done here, just to get input from user instead of just hovering, but nothing happens! I copy/pasted the link code in my editor and smooth transitions are performed but when it comes of my code, nothing! Could you tell me where is my flaw?
Change your CSS from the hover state to a class, for iunstance change .sub1:hover to .hovered:
.container .hovered > .front {
transform: perspective(600px) rotateY(-180deg); }
.container .hovered > .back {
transform: perspective(600px) rotateY(0deg); }
And now, on click, add this class to the element clicked:
$(".sub1").click(function() {
$(this).addClass ('hovered');
})
fiddle
this function in javascript would be
function change(element) {
element.className = element.className + " hovered";
}
provided that you send the element in the function call
onclick="change(this)"
fiddle - function set only in the first div

how to get flip with css3 and change the element?

my context
HTML
<div class="cart">
<div class="black"></div>
</div>
JS
var whiteEl="<div class="white"></div>";
//I would like to replace black with white, flip animation.
$(".cart").empty().append(whiteEl);
whiteEl.addClass("flipanim");
css
#-webkit-keyframes flip{
from{
-webkit-transform: rotateY(0deg);
}
to {
-webkit-transform: rotateY(180deg);
}
}
/*
similar cross browser code*/
.flipanim{
-webkit-animation: flip 1s 1;
-moz-animation:flip 1s 1;
-o-animation:flip 1s 1;
animation:flip 1s 1;
-webkit-transition: all .5s;
-moz-transition: all .5s;
-o-transition: all .5s;
transition: all .5s;
}
I am using key frame animation for show transform animation.
and in javascript adding class to attached element.
my animation not working.
How can I add the new element with flip animation to ".cart"?
try this
$(".cart").html('').append(whiteEl);
//since you have already appended the created div here.. you can use class selctor.
$('.white').addClass("flipanim");
You don't need to remove any content for that and also don't need Javascript for it:
html-markup:
<div class="container">
<div class="cart">
<div class="black">Black side</div>
<div class="white">White side</div>
</div>
</div>
css:
.cart div {
position: absolute;
width: 100%;
height: 100%;
-webkit-backface-visibility: hidden;
}
.cart .black {
background:#111;
color:white;
}
.cart .white {
-webkit-transform: rotateY(180deg);
color: black;
background: #eee;
}
Now you can apply your effects simply with:
.container:hover .cart {
-webkit-transform: rotateY(180deg);
}
See the Demo

Controlling CSS Transform with an external button?

Need help with a javascript on a button to trigger these transformations like a slider 1,2,3 and alternate back and forth. Like on the apple website for iPhone features slider. Anyone?
The HTML:
<div id="anima-slide1">
<div class="anima-text-slide1">Genuinity comes at a price.<br>
<font color="#f06">Will you pay it?</font></div>
<div class="anima-image-slide1"><img src="img/lowrider1.png" width="250" height="250"> </div>
</div>
<div id="anima-slide2">
<div class="anima-text-slide2">Genuinity comes at a price.<br>
<font color="#f06">Will you pay it?</font></div>
<div class="anima-image-slide2"><img src="img/lowrider1.png" width="250" height="250"> </div>
</div>
<div id="anima-slide3">
<div class="anima-text-slide3">Genuinity comes at a price.<br>
<font color="#f06">Will you pay it?</font></div>
<div class="anima-image-slide3"><img src="img/lowrider1.png" width="250" height="250"> </div>
</div>
The CSS: (Same for 2 and 3)
.anima-text-slide1 {
margin-top:10px;
position:absolute;
font-family: 'BebasRegular';
color:#FFF;
font-size:40px;
}
.anima-text-slide1 {
-webkit-backface-visibility: visible;
-webkit-transition: 900ms ease;
opacity: 0;
-webkit-transform: translate(-497px, 0px) rotate(0deg);
}
.anima-image-slide1 {
position:absolute;
left: 610px;
top: 0px;
}
.anima-image-slide1 {
-webkit-backface-visibility: visible;
-webkit-transition: 900ms ease;
opacity: 0;
-webkit-transform: translate(497px, 0px) rotate(0deg);
}
By adding a class name you can create several animation steps. Using jQuery makes it a lot easier to change the class names on the target element. You can apply this technique to your particular situation.
<div class="container">
Hello
</div>
Frame 1
Frame 2
JS:
function setFrame(frameName) {
$('.container').addClass(frameName);
}
CSS:
.container {
font-size:24px;
}
.frame1 {
font-size:48px;
-webkit-backface-visibility: visible;
-webkit-transition: 900ms ease;
opacity: 20;
-webkit-transform: translate(200px, 0px) rotate(0deg);
}
.frame2 {
font-size:64px;
color:#ff0000;
-webkit-backface-visibility: visible;
-webkit-transition: 900ms ease;
opacity: 20;
-webkit-transform: translate(0px, 150px) rotate(30deg);
}
EDIT:
So if you want to do multiple elements you can do something like this:
.containerA .frame1 {
...
}
.containerB .frame1 {
...some different style...
}
Then:
function setFrame(frameName) {
$('.containerA').addClass(frameName);
$('.containerB').addClass(frameName);
}

helping in transition effect by CSS3 or JS or jquery

I want to change the background-image of this picture while moving to another one on my images folder
like this example
that's my code
CSS
.image {
position: relative;
overflow: hidden;
-webkit-transition: all 0.5s ease-out;
-moz-transition: all 0.5s ease-out;
transition: all 0.5s ease-out;
opacity:1;
filter:alpha(opacity=100);
}
.image:hover {
opacity:0;
filter:alpha(opacity=0);
-moz-transform: scale(1.00) rotate(0deg) translate(0px, 100px) skew(0deg, 0deg);
-webkit-transform: scale(1.00) rotate(0deg) translate(0px, 100px) skew(0deg, 0deg);
transform: scale(1.00) rotate(0deg) translate(0px, 100px) skew(0deg, 0deg); transform-origin: 0% 0%
background-color:#36F;
}
HTML
<div id="image_holder_1" class="image_holder">
<img id="image_1" class="image" src="images/esu.gif" />
</div>
jQuery.cycle is your answer.
<script type="text/javascript">
$(document).ready(function() {
$('.image_holder').cycle({
fx: 'fade' // choose your transition type, ex: fade, scrollUp, shuffle, etc...
});
});
</script>
You should remove the "image" id and image elements should be contained inside your "image_holder" that contain links to the images you want to cycle (transition) through. Your html will then look something like this:
<div id="image_holder_1" class="image_holder">
<img src="images/esu.gif"/>
<!-- Your other image source(s) goes here -->
</div>
If your image transition worked the way that you liked with your css, use the css for the transition and omit the transition type in the jQuery. Here is a link to the different transitions that may be useful to you by using jQuery.cycle. jQuery.cycle transitions
The effect in your example would not be achievable in CSS, transition animations cannot be cancelled, so each animation would have to complete for both the mouse over and mouse out events in the CSS.

Categories

Resources