Delaying Animation on Click Slide Change - javascript

I have a slick slider that use a fade transition. Each active slide has an animation that scales the background image of the slide. When the slide changes the animation is removed from the slide.
When manually clicking to a new slide the scale jumps back to the default size before the transition finished creating a jump on the image. My question is how do I delay the removal of the animation so I don't get that jump back to the default scale?
Code is below, and you can see an example here: http://tesla.uk-cpi.com/
JS
// Slider on Home Page
$('.homeSlider').slick({
draggable: true,
autoplay: true,
autoplaySpeed: 7000,
arrows: false,
dots: true,
fade: true,
speed: 500,
infinite: true,
cssEase: 'linear',
touchThreshold: 100,
customPaging : function(homeSlider, i) {
var title = $(homeSlider.$slides[i]).data('title');
var number = $(homeSlider.$slides[i]).data('index-number');
return '<a class="pager__item" onClick=reset()><div class="slide-number">'+number+'</div><div class="slide-title">'+title+'</div></a>';
},
});
$('.slick-active .item').addClass('kenburnseffect');
$('.homeSlider').on('afterChange', function(event, slick, currentSlide){
$('.item').removeClass('kenburnseffect');
$('.slick-active .item').addClass('kenburnseffect');
});
CSS
.item {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
#-webkit-keyframes kenburns {
from {
-webkit-transform: scale(1.1);
}
to {
-webkit-transform: scale(1);
}
}
#keyframes kenburns {
from {
transform: scale(1.1);
}
to {
transform: scale(1);
}
}

Use setTimeout,
$('.homeSlider').on('afterChange', function(event, slick, currentSlide){
setTimeout(function(){
$('.item').removeClass('kenburnseffect');
$('.slick-active .item').addClass('kenburnseffect');
},1000);
});
Here, time delay is given 1000 milli-seconds

I had the same issue and never found a good JS solution. One CSS solution I've found that isn't perfect but at least hides the ugly 'jump' when you skip the slide mid-animation is to add this:
.slick-slide[aria-hidden="true"] img {
visibility: hidden;
}
It basically hides the active slide during the fade, so you don't get as much of a blend between the two slides the casual observer probably won't notice or care.
EDIT - Found another, better CSS solution. There's a CSS animation property called 'animation-play-state'. Instead of hiding the image during the transition, you can pause it so that it doesn't jump when the current class disappears. However, you do need to make the animation infinite as it'll resume, rather than reset on each slide, so if the user comes back around to them it'll eventually stop. You will also want to make the animation start and end in the same state to loop seamlessly. Code example below:
img {
transform-origin: bottom left;
transform: scale(1.1);
animation-name: bannerPan;
animation-duration: 18s;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-fill-mode: forwards;
animation-play-state: paused;
}
.slick-current img {
animation-play-state: running;
}
#keyframes bannerPan {
0% {
transform-origin: bottom left;
transform: scale(1.0);
}
50% {
transform-origin: bottom left;
transform: scale(1.1);
}
100% {
transform-origin: bottom left;
transform: scale(1.0);
}
}

Related

Triggering a new CSS webkit animation while another animation is running

I am relatively new to CSS/JS and I have a problem when triggering a new CSS animation.
I have a <div> that infinitely moves through to some specific points of the screen using a CSS keyframe animation.
I have an image that, when clicked, it triggers a js. function that toggles a new CSS class / animation. My problem is that I want to start this new animation in the position that the current(or last animation) was before toggling the new class.
I don't know how to store the current position from the keyframe and make a new animation starting from it.
To simplify, I have something like this in CSS:
.block {
width: 100px;
height: 100px;
background-color: black;
position: relative;
animation: animate 10s infinite ease-in-out;
animation-play-state: running;
}
#keyframes animate {
0% {
transform: translate(-300px, 20px) rotateY(180deg) scale(1)
}
50% {
transform: translate(1200px, 200px) rotateY(180deg) scale(1.2)
}
100% {
transform: translate(200px, 100px) scale(1.2)
}
}
CSS of the new animation triggered:
.block.new-animation {
animation-play-state: paused;
animation: new-animate 10s infinite ease-in-out;
}
#keyframes new-animate{
from {
// current position
}
to {
transform: translate(500px, 20px) scale(1.5);
}
}
Javascript:
const block = document.querySelector('.block')
const image = document.querySelector('.image')
const togglenewAnimation = () => {
block.classList.toggle('new-animation');
}
image.onclick = () => togglenewAnimation();
What I am trying to do is pause the first animation, and then start the new animation based on the current position the div is located.
Any help is very much apreciated. Thank you!

How do i stop webkit animation through js? + fixing image to the right

I'm trying to build a puzzle game website. I'm using webkit animation to rotate (and translate) two images.
My plan is to have rotating gears attached to the left and right edge of my page, offset in a way that only half of each image is shown at a time.
The animation works fine but
(1) i am unable to pause it, and
(2) depending on window size the images are moved out of view (with an automatic scrollbar popping up) or into full view.
The setup is pretty simple:
I have 3 divs: one bar at the top with 100% width and two divs with 50% width below as containers for my images.
I might need to add more below or in between the two divs down the road but for now a solution for this would be good enough^^
For the animation i have a pseudo button on each side which adds a pause class to my images.
HTML
<div id="div-left">
<p>Hey this is the left div</p>
<img src="images/zahnrad.png" alt="zahnrad" id="image1">
<p id="pausebtn1" onclick="pause1()">pause</p>
</div>
<div id="div-right">
<p>hey this is the right div</p>
<img src="images/zahnrad.png" alt="zahnrad" id="image2">
<p id="pausebtn2" onclick="pause2()">pause</p>
</div>
CSS
#image1{
-webkit-animation: rotation-left 30s infinite linear;
}
#image1.paused1::-webkit-progress-value{
-webkit-animaion-play-state:paused;
animaion-play-state:paused;
}
#image2{
align: right;
-webkit-animation: rotation-right 30s infinite linear;
}
#image2.paused2::-webkit-progress-value{
-webkit-animaion-play-state:paused;
animaion-play-state:paused;
}
/* Animations */
#-webkit-keyframes rotation-left{
from {
-webkit-transform: translate(-50%,0px) rotate(0deg);
}
to{
-webkit-transform: translate(-50%,0px) rotate(359deg);
}
}
#-webkit-keyframes rotation-right{
from {
-webkit-transform:translate(+50%,0px) rotate(0deg);
}
to{
-webkit-transform:translate(+50%,0px) rotate(-359deg);
}
}
Javascript
function pause1() {
console.log("pause img 1");
document.getElementById('image1').classList.toggle("paused1");
}
function pause2() {
console.log("pause img 2");
document.getElementById('image2').classList.toggle("paused2");
}
So to sum it all up:
I have two images in the wrong places. They are animated. My two buttons are working but trying to pause the animation by adding a paused class doesn't function.
Any help would be appreciated and i'll see if i can add images later
You shouldn't be targeting ::-webkit-progress-value, that's for <progress> elements. Just toggle the class onto the element:
button.addEventListener('click', function () {
square.classList.toggle('paused');
});
#square {
animation: rotate 1s infinite;
background: lightblue;
border: 1px solid black;
height: 100px;
left: 50px;
position: absolute;
top: 50px;
width: 100px;
}
#square.paused {
animation-play-state: paused;
}
#keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
<button id="button">Pause/Resume</button>
<div id="square">Rotate</div>

CSS3 animate slide left to right and right to left toggling

So basically I have a process with multiple steps that users will go through. Whenever they click a forward button, I want to slide the current step to the left and slide the next step on from right to left. When hitting backwards, I want the current step to slide off to the right and the previous step to slide in from the left. I have it working so it correctly does the slide on the first click both ways, the problem arrives when I basically try to toggle it (so clicking on forward, then back). When I do this, the thing will slide off correctly, but the previous step does not slide back on, leaving a blank content area. This is the state of the classes once you hit forward first, then hit back:
Here's my animation CSS:
#keyframes slide-in-from-left {
0% { tranform: translate(-100%); }
100% { transform: translateX(0%); }
}
#keyframes slide-out-left {
0% { transform: translateX(0%); }
100% { transform: translateX(-100%); }
}
#keyframes slide-in-from-right {
0% { transform: translateX(100%); }
100% { transform: translateX(0%); }
}
#keyframes slide-out-right {
0% { transform: translateX(0%); }
100% { transform: translateX(100%); }
}
// Animation Classes
// ------------------------------
.slide-in-from-left {
animation: slide-in-from-left 0.5s forwards;
}
.slide-out-left {
animation: slide-out-left 0.5s forwards;
}
.slide-in-from-right {
animation: slide-in-from-right 0.5s forwards;
}
.slide-out-right {
animation: slide-out-right 0.5s forwards;
}
And then I just have:
[class^="step-"] {
position: absolute;
}
.step-4 {
transform: translateX(-100%);
}
And my jQuery/coffeescript:
goForwardAStep = () ->
step = $(this).data('step')
$('.signup .step-' + step).addClass('slide-out-left')
$('.signup .step-' + (step + 1)).addClass('slide-in-from-right')
goBackAStep = () ->
step = $(this).data('step')
$('.signup .step-' + step).addClass('slide-out-right')
$('.signup .step-' + (step - 1)).addClass('slide-in-from-left')
Should I be removing a class somewhere when the steps change? Should I have more classes involved to make sure things are laying off screen where they should?
A simpler approach. 3 clases for the state:
.current {
transform: {translateX(0%);}
}
.moved-left {
transform: {translateX(-100%);}
}
.moved-right {
transform: {translateX(100%);}
}
and a permanent one
.slide {
transition: transform 0.5s;
}

Rotating image 2 times

There is several questions about how to rotate an image, but I want an animation-like rotating. By an
event (tap) I would like to rotate an image with -5 degree then with 5 degree, but if I write both rotating in
the same function (or eventhandler), the first rotate doesn't appear only the second is visible.
$("#imgdiv").on('taphold', function(e){
//$("#imageID").addClass("swing animated");
$("#imageID").css({"transition-property":"transform","transition-duration":"2s","transform":"rotate(-5deg)"});
$("#imageID").css({"transition-property":"transform","transition-duration":"2s","transform":"rotate(5deg)"});
//$("#imageID").removeClass("swing animated");
});
I have also tried a swing animation with classes (addClass, then removeClass), but with the same result:
#keyframes swing {
25% { transform: rotate(-5deg); }
50% { transform: rotate(0deg); }
75% { transform: rotate(5deg); }
100% { transform: rotate(0deg); }
}
.swing {
transform-origin: top center;
animation-name: swing;
}
.animated {
animation-duration: 1s;
animation-fill-mode: both;
animation-timing-function: linear;
}
You may put the second animation in a setTimeout in order to delay its animation until the first one finishes.
You can also put your transition in the css rather than in JS. Just place the transform value in JS.
Try something like this SAMPLE.
JS:
$(".clickme").click(function(){
//animate to -5deg
$(this).css('transform','rotate(-5deg)');
//animate to 5deg
setTimeout(function(){$(".clickme").css('transform','rotate(5deg)')},1000);
//animate back to root position
setTimeout(function(){$(".clickme").css('transform','rotate(0deg)')},2000);
});
you can do with addclass and removeclass, but there is one mistake in your code.
you are doing addclass and removeclass at the same time. so, animation is not happening or only one time happens
so try setTimeout:
$("#imgdiv").on('click', function(e){
$("#imageID").addClass("swing animated");
setTimeout(function(){
$("#imageID").removeClass("swing animated");
},1000)
});
i have done that in jsfiddle - http://jsfiddle.net/tqn394k9/

jQuery : How to animate a span and show?

I have a function that checks mail on every 10 secods, if there is a new email, it make a bubble notification and show the total number of mail.
jQuery("#bubble_mate").text(responseText.totalmail);
jQuery("#bubble_mate").addClass('animating').show();
It animates the bubble, first time I load the page, but this function is set on an interwal, so it should animate the bubble each time there is new mail, but it Doesn't
My animation and other functions are perfect.. it is just it Doesn't animate when it is being called in set interval. it ads the number of total mail.. but no animation.
Please help me.
Regards
Added
This is animating class and css
.animating{
-webkit-animation: animate 1s cubic-bezier(0,1,1,0);
-moz-animation: animate 1s cubic-bezier(0,1,1,0);
-ms-animation: animate 1s cubic-bezier(0,1,1,0);
-o-animation: animate 1s cubic-bezier(0,1,1,0);
animation: animate 1s cubic-bezier(0,1,1,0);
}
#-webkit-keyframes animate{
from {
-webkit-transform: scale(1);
}
to {
-webkit-transform: scale(1.7);
}
}
#-moz-keyframes animate{
from {
-moz-transform: scale(1);
}
to {
-moz-transform: scale(1.7);
}
}
#-ms-keyframes animate{
from {
-ms-transform: scale(1);
}
to {
-ms-transform: scale(1.7);
}
}
#-o-keyframes animate{
from {
-o-transform: scale(1);
}
to {
-o-transform: scale(1.7);
}
}
#keyframes animate{
from {
transform: scale(1);
}
to {
transform: scale(1.7);
}
}
You'll need to remove the class once the animation is completed, and re-add it once you'll need to use it again.
setInterval(function() {
$("#bubble_mate").addClass('animating');
setTimeout(function() {
$("#bubble_mate").removeClass('animating');
}, 1000); // This is the time specified in your CSS
}, 3000); // Example interval time
​JSFiddle.
If you are using keyframe animations, you may want to remove the class, then wait 1 ms and re-add the class. Adding the class multiple times will not animate it multiple times.
$('#test').addClass('animated');
setInterval(function(){
$('#test').removeClass('animated');
setTimeout(function(){
$('#test').addClass('animated')
}, 1);
}, 3000);
Will give the test element the class 'animated', which will start the animation, and every 3 seconds, it will remove the class, pause for 1 ms, then re-add it, which will restart the animation.
Source: http://jsfiddle.net/jcolicchio/eV7ET/
To show the slide down effect you have first to hide the div!
$("#simulate").on("click", function() {
console.log("mail in");
$("#bubble_mate").text("10 new mail");
$("#bubble_mate").addClass('animating').hide();
$("#bubble_mate").slideDown(500);
});
try on this fiddle
http://jsfiddle.net/jQmJr/32/
​
Try:
jQuery("#bubble_mate").hide().show('normal');
I resolved it myself..
in beforeSend function i added this:
beforeSend:function (){
jQuery("#bubble_mate").removeClass('animating');
},
and then on success:
success:function(responseText)
{
if(responseText.mails=='yes')
{
jQuery("#bubble_mate").text(responseText.totalmail);
jQuery("#bubble_mate").addClass('animating').show();
}
}
I used the webkitEndAnimation event to remove the animated class and the end of the animation.
Here is the live example
Code:
$(document).ready(function(){
setInterval(function(){
$('#test').show().addClass('animated');
}, 3000);
$('#test').on('webkitAnimationEnd', function () {
$(this).removeClass('animated').hide();
});
});​
If this works for you should think of a way to get the correct event name depending on the users browser

Categories

Resources