Slick Slider with ken-burns-out image jumps bug - javascript

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>

Related

Image won't stay visible for hover effect

Hello and thank you in advance for reading my question.
GOAL: Set image so that once it's scrolled into view it transitions smoothly into a set position - but still reacts to :hover. Using #keyframes and a little JavaScript, I set the image to opacity: 0 and it's final opacity to opacity: .85. Then I added a hover effect in CSS to make it's opacity: 1
The issue is once it's finished with it's transition - it disappears - reverting to it's original opacity which is zero. I managed to make it freeze at .85 with animation-fill-mode: forwards, rather than animation-fill-mode: none, but then it won't respond to :hover
And here's a test snippet of the problem in action:
let observer_img = new IntersectionObserver(updates => {
updates.forEach(update => {
if (update.isIntersecting) {
update.target.classList.add('shift_frame_center_img');
} else {
update.target.classList.remove('shift_frame_center_img');
}
});
}, { threshold: 0 });
[...document.querySelectorAll('.features-img-wrapper img')].forEach(element => observer_img.observe(element));
body {
width: 100%;
height: 100vh;
background-color: lightgrey;
}
/* CHILD */
.features-img-wrapper img {
width: 10rem;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 8rem;
opacity: 0;
transition: all .5s;
}
/* APPEND-CHILD */
.shift_frame_center_img {
animation: center_img 1s 0.5s none;
}
/* CHILD ON HOVER */
.features-img-wrapper img:hover {
opacity: 1;
transform: scale(1.035);
}
/* KEYFRAMES */
#keyframes center_img {
0% {
transform: translateY(20rem);
}
100% {
transform: translateY(0);
opacity: .85;
}
}
<body>
<div class="features-img-wrapper">
<img src="https://synapse.it/wp-content/uploads/2020/12/test.png">
</div>
</body>
If I could get a hand with this that would be wonderful, I'm a bit of a beginner and have already spent a few hours on this, all feedback welcome. Thank you very much.
Solution 1
To understand why the hover effect was not working with the animation-fill-mode: forwards, read this answer.
You can fix that by adding !important property to the hover styles:
.features-img-wrapper img:hover {
opacity: 1 !important;
transform: scale(1.035) !important;
}
The problem, in this case, is that the transition will not work for hover.
Solution 2
You could remove the animation entirely and add the final state styles to the shift_frame_center_img class.
But you would still need to use the !important property because of the CSS Specificity.
let observer_img = new IntersectionObserver(updates => {
updates.forEach(update => {
if (update.isIntersecting) {
update.target.classList.add('shift_frame_center_img');
} else {
update.target.classList.remove('shift_frame_center_img');
}
});
}, { threshold: 0 });
[...document.querySelectorAll('.features-img-wrapper img')].forEach(element => observer_img.observe(element));
body {
width: 100%;
height: 100vh;
background-color: lightgrey;
}
/* CHILD */
.features-img-wrapper img {
width: 10rem;
transform: translateY(20rem);
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 8rem;
opacity: 0;
transition: all .5s;
}
/* APPEND-CHILD */
.shift_frame_center_img {
transform: none !important;
opacity: .85 !important;
}
/* CHILD ON HOVER */
.features-img-wrapper img:hover {
opacity: 1 !important;
transform: scale(1.035) !important;
}
<body>
<div class="features-img-wrapper">
<img src="https://synapse.it/wp-content/uploads/2020/12/test.png">
</div>
</body>
This snippet removes the need for fill-mode forwards by setting the img to have opacity 1 as its initial state so it will revert to that at the end of the animation.
The animation itself is altered to take 1.5s rather than 1s with the first third simply setting the img opacity to 0 so it can't be seen. This gives the delay effect.
let observer_img = new IntersectionObserver(updates => {
updates.forEach(update => {
if (update.isIntersecting) {
update.target.classList.add('shift_frame_center_img');
} else {
update.target.classList.remove('shift_frame_center_img');
}
});
}, { threshold: 0 });
[...document.querySelectorAll('.features-img-wrapper img')].forEach(element => observer_img.observe(element));
body {
width: 100%;
height: 100vh;
background-color: lightgrey;
}
/* CHILD */
.features-img-wrapper img {
width: 10rem;
display: block;
margin-left: auto;
margin-right: auto;
margin-top: 8rem;
opacity: 0;
transition: all .5s;
opacity: 1;
}
/* APPEND-CHILD */
.features-img-wrapper img {
animation: center_img 1.5s 0s none;
}
/* CHILD ON HOVER */
.shift_frame_center_img:hover {
opacity: 1;
transform: translateY(0) scale(1.035);
}
/* KEYFRAMES */
#keyframes center_img {
0% {
transform: translateY(20rem) scale(1);
opacity: 0;
}
33.33% {
transform: translateY(20rem) scale(1);
opacity: 0;
}
100% {
transform: translateY(0) scale(1);
opacity: .85;
}
}
<body>
<div class="features-img-wrapper">
<img src="https://synapse.it/wp-content/uploads/2020/12/test.png">
</div>
</body>
Note: as each transform setting will reset anything that isn't included both tranlateY and scale are included in each setting.
Outside the SO snippet system it was possible to leave the animation settings untouched by chaining another animation to the front which ran for 0.5s and just set the img to opacity: 0. This did not work in the snippet system (it got into a loop of flashing on and off) hence the introduction of one but extended animation.

Executing keyframes animation in JS or jQuery

I know that it is possible to set the animation of an element by id either in a stylesheet or in JS from the DOM. The issue is that I want the animation to execute every time a click action on a specific element is performed by the user. Adding the animation to an element's style in JS seems to add it permanently so that the keyframes animation cannot be performed again, (only performed once when the window finishes loading). I also thought about using jQuery's .animate() function however all documentation points to it animating over CSS specific styles and not setting/calling the animation style attribute as if I were to set it using CSS. I want to know the best way of executing my animation over an element when another element is clicked on by the user and consistently executing the animation for each click.
#keyframes fadeInDown {
from {
opacity: 0;
transform: translate(0, -20%);
}
to {
opacity: 1;
transform: translate(0, 0);
}
}
The current way I'm setting animation for an element:
$("#element").css("animation", "fadeInDown 0.5s ease-in 0s 1");
This is a toggling animation using transition and jquery, without using .animate()
$(document).ready(function() {
$('button').click(function() {
var box = $('.box')
box.removeClass("show")
setTimeout(function(){
box.addClass("trans").addClass("show")
setTimeout(function(){
box.removeClass("trans")
},100)
},200)
});
});
.box {
background: red;
height: 50px;
width: 50px;
position: absolute;
margin-top: 50px;
margin-left: 50px;
opacity: 0;
transform: translate(0, -20%);
}
.box.trans {
transition: all 0.7s;
}
.box.show {
opacity: 1;
transform: translate(0, 0);
}
<button>Test</button>
<div class="box show"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
It's my first answer on stack overflow.
I had the same question about animation.
What I did last was just like Vivek Patel's answer, but instead of toggling the css keyframe, I created a separated class only for css animation("animation-fadeInDown"), and toggle it.
Because the animation-name "fadeInDown" is correponding to the #keyframes name, so if you separate it you could apply the animation to other elements, by just toggling the animation class.
And, you can still do the css deco to the original box seperately, which might be more clear to read.
I hope this is close to what you looking for.
$('button').click(() => {
$('.box').toggleClass('animation-fadeInDown');
});
.box {
width: 50px;
height: 50px;
background: black;
}
.animation-fadeInDown {
animation: fadeInDown 0.5s ease-in 0s 1
}
#keyframes fadeInDown {
from {
opacity: 0;
transform: translate(0, -20%);
}
to {
opacity: 1;
transform: translate(0, 0);
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="box"></div>
<button>
Test
</button>
Basically CSS animation only runs once when the page loads. So it is not possible to re-trigger it again. Here is the workaround for your use case: Remove the element from the page entirely and re-insert it.
Try this:
$('button').click(() => {
var oldDiv = $('#animated-div');
newDiv = oldDiv.clone(true);
oldDiv.before(newDiv);
$("." + oldDiv.attr("class") + ":last").remove();
});
#keyframes fadeInDown {
from {
opacity: 0;
transform: translate(0, -20%);
}
to {
opacity: 1;
transform: translate(0, 0);
}
}
.animated-div {
animation: fadeInDown 0.5s ease-in 0s 1
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="animated-div" class="animated-div" style="width: 50px; height: 50px; background: black"></div>
<button>
Test
</button>
This is an simple example that use jquery to animate in Queue as it works in #keyframes. The transition duration and animation duration gives more control on the animation character.
$(document).ready(function() {
$('button').click(function() {
$('.box')
.css('transition', 'all 0.2s')
.animate({ opacity: 0 }, {
duration: 200,
step: function(now) {
$(this).css({ opacity: now });
$(this).css({ transform: 'translate(0, -20%)' });
}
})
.animate({ opacity: 1 }, {
duration: 600,
step: function(now) {
$(this).css({ opacity: now });
$(this).css({ transform: 'translate(0, 0)' });
}
})
});
});
.box {
background: red;
height: 50px;
width: 50px;
position: absolute;
margin-top: 50px;
margin-left: 50px;
}
<button>Test</button>
<div class="box"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

Playing CSS animation not playing after adding javascript class when other class removed

I am trying to have a animation play when an element is selected, and the reverse animation play when the element is deselected. My CSS looks like this:
#keyframes scale-effect {
from {
transform: scale(1);
}
to {
transform: scale(0.75);
}
}
.card.active {
animation: 1s ease-in-out reverse scale-effect;
}
.card.inactive {
animation: 1s ease-in-out forwards scale-effect;
transform: scale(0.75);
}
This plays the correct animations on page load. However, if I try to change the selected class in javascript:
newActiveObject.classList.remove('inactive');
oldActiveObject.classList.remove('active');
oldActiveObject.classList.add('inactive');
newActiveObject.classList.add('active');
Now, the classes get added properly, and I can see the size changes. However, no animation plays.
Things I have tried:
Using setTimeout(..., 0), between removing and adding classes does not have any effect. Same for 1.
Using setTimeout(..., 10), works, but very clear ugly fash of post-animation style before animation starts
Putting the animation in .card, instead of .inactive. This seems to just disable all animation even on page load.
Using getComputedStyle to force DOM redraw in between removing and adding classes. Has no effect.
Does anyone know how to properly replace a animation after removing a class?
Why don't you use transition instead? With animation, it's hard to control the flow. You need either to use a 2nd animation (one for active, one for inactive) or to trigger a reflow in JavaScript (see similar question). Here an example with transition:
const $cards = Array.from(document.getElementsByClassName("card"))
function handleClick(evt) {
$cards.forEach($card => $card.classList.remove("active"))
evt.target.classList.add("active")
}
$cards.forEach($card => $card.addEventListener("click", handleClick))
.card {
display: inline-block;
margin: 10px;
width: 100px;
height: 100px;
border: 1px solid gray;
cursor: pointer;
transition: transform 1s ease-in-out;
transform: scale(0.75);
}
.card.active {
transform: scale(1);
}
<div class="card">CARD 1</div>
<div class="card">CARD 2</div>
<div class="card">CARD 3</div>
<div class="card">CARD 4</div>
If your really need animation, here a working example with 2 animations:
const $cards = Array.from(document.getElementsByClassName("card"))
function handleClick(evt) {
$cards.forEach($card => {
$card.classList.remove("active")
$card.classList.add("inactive")
})
evt.target.classList.remove("inactive")
evt.target.classList.add("active")
}
$cards.forEach($card => $card.addEventListener("click", handleClick))
#keyframes scale-effect-out {
from { transform: scale(1); }
to { transform: scale(0.75); }
}
#keyframes scale-effect-in {
from { transform: scale(0.75); }
to { transform: scale(1); }
}
.card {
display: inline-block;
margin: 10px;
width: 100px;
height: 100px;
border: 1px solid gray;
cursor: pointer;
}
.card.inactive {
animation: 1s forwards ease-in-out scale-effect-out;
}
.card.active {
animation: 1s forwards ease-in-out scale-effect-in;
}
<div class="card inactive">CARD 1</div>
<div class="card inactive">CARD 2</div>
<div class="card inactive">CARD 3</div>
<div class="card inactive">CARD 4</div>
I have faced this before, you need to reset the animation for the target element, before adding another animation by javascript.
var el = document.getElementById('target_element_id');
el.style.animation = 'none'; // clear animation
el.offsetHeight; /* trigger reflow */
and then you can add another animation/class.
If needed try css '!important' while changing animation.
Assuming the active card should start on .75, then get bigger.
.card.active {
transform: scale(0.75); /* moved this to here */
animation: 1s ease-in-out reverse scale-effect;
}
.card.inactive {
animation: 1s ease-in-out forwards scale-effect;
}

JS/CSS How to zoom picture by clicking with adjustable speed and execute function after this

I try to create an animation effect with JS/CSS, but the result is not the wished one.
The idea was to click on the image and start a function which zooms into the image until it's really huge and only one last color is seen.
If this is true, my function should open the next page.
But I don't get a smooth zoom. Do you have any idea how I could do it?
Here is my code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TraumRaum</title>
<link href="css/index.css" rel="stylesheet" type="text/css">
<style type="text/css">
div.image {
width: 250px;
height: 250px;
position: fixed;
top: 50%;
left:50%;
transform: translate(-50%, -50%);
}
div.image img {
width: 100%;
height: auto;
/* SCALE */
-webkit-transform: scale(1);
-moz-transform: scale(10);
-ms-transform: scale(10);
-o-transform: scale(10);
transform: scale(10);
/* VERZĂ–GERUNG */
-webkit-transition: all 0.1s linear;
-moz-transition: all 0.1s linear;
-ms-transition: all 0.1s linear;
-o-transition: all 0.1s linear;
transition: all 0.1s linear;
}
div.image img:hover {
-webkit-transform: scale(3);
-moz-transform: scale(3);
-ms-transform: scale(3);
-o-transform: scale(3);
transform: scale(3);
cursor: pointer;
}
</style>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script src="jquery.zoomooz.min.js"></script>
<script type="text/javascript">
function zoomin(){
var yourImg = document.getElementById('yourImgId');
var i;
for(i =0 ; i< 100000; i++){
yourImg.height = yourImg.height+1;
yourImg.width = yourImg.width+1;
}
window.open("https://www.nextwebsite.com","_self")
}
</script>
</head>
<body onmousedown="zoomin()">
<div class = "image" >
<class="zoomTarget" data-targetsize="1" data-duration="60000">
<img id="logo1" src="logo.png" alt="Logo">
</div>
</div>
</body>
</html>
If zooming in on an image is what you'd like to accomplish, perhaps just use css transitions.
Apply a starting height and width to your original, like so:
#logo1 {
height: 100%;
width: 100%;
}
and then apply either a hover or focus state which increases the height and width of the object in question. For example:
#logo1:hover {
height: 500%;
width: 500%;
This will give increase the image's size to 5x it's original size when hovered. If you'd like this to take place over a period of time, set a transition duration by adding "transition duration: 500ms" to #logo1. This would take 500 milliseconds to apply the change. I hope this answers your question.

Sliding and fading a div element

I am trying to animate a div element (slide and fade) with a button click. At first, the element is not visible to a user. When the button is clicked, it will slide to right and fade in. Once the button is clicked again, it will slide to left and fade out. I come up with two solutions, with css and with JQuery.
In the first one, I used JQuery. You can find the example in this JSFiddle 1.
HTML
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
CSS
#my-modal {
opacity: 1;
position: fixed;
top: 50px;
left: 0;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
}
JQuery
$("#my-button").click(function () {
var $modal = $("#my-modal");
$modal.stop(true, true).animate({
left: "toggle",
opacity: "toggle"
}, 1000);
});
Here, everything seems working but it does directly opposite of what I want. It first fades out, and with the second click, it fades in. It is because that the opacity of the element is 1, but if I turn it to 0, nothing happens.
Secondly, I tried to do that with css animation by using key-frames (changing opacity from 0 to 1) but it has also problem. It starts the animation exactly the way I want. However, when I click the button again, it disappears immediately. Here is the JSFiddle 2.
HTML
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
CSS
#my-modal {
opacity: 0;
position: fixed;
top: 50px;
left: 0;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
-moz-transition: all 1s ease;
-webkit-transition: all 1s ease;
-o-transition: all 1s ease;
transition: all 1s ease;
}
.move-my-modal {
-moz-transform: translate(250px, 0px);
-webkit-transform: translate(250px, 0px);
-ms-transform: translate(250px, 0px);
-o-transform: translate(250px, 0px);
}
.animate-opacity {
-webkit-animation: toggle-opacity 1s ease;
-moz-animation: toggle-opacity 1s ease;
-o-animation: toggle-opacity 1s ease;
animation: toggle-opacity 1s ease;
-webkit-animation-fill-mode: forwards;
}
#-webkit-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-moz-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#-o-keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
#keyframes toggle-opacity {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
JQuery
$("#my-button").click(function () {
var $modal = $("#my-modal");
$modal.toggleClass("move-my-modal");
$modal.toggleClass("animate-opacity");
});
To this end, I have these questions;
1) What are the problems with these two approaches? Is there something that I missed or forgot to use? How can I correct them to meet the requirements that I mentioned at the beginning.
2) Which one is the better way to make this action? Is there any cons or pros of these approaches?
3) Is there any other way to make this action? I am new on this area and I might not notice a simpler way.
You can toggle an .active class to the element and use CSS transitions.
This way, if the browser is old enough to not support animations, it will still work but it won't slow down computers that do not handle animations well.
$("#my-button").click(function () {
$("#my-modal").toggleClass('active');
});
#my-modal.active {
opacity: 1;
left: 0;
}
$("#my-button").click(function () {
$("#my-modal").toggleClass('active');
});
#my-modal {
opacity: 0;
position: fixed;
top: 50px;
left: -250px;
width: 250px;
height: 100%;
background-color: red;
transition: all 1s linear;
}
#my-modal.active {
opacity: 1;
left: 0;
}
<button id="my-button">Click me!</button>
<div id="my-modal"></div>
<!-- jQuery -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Categories

Resources