addEventListener for specific animationName - css-animations

I have written the code below. I'm trying to invoke functions one after the other based on 'animationend' eventlisteners. The problem arises in the js code after startScreenContainer.classList.add('thisFadeOut');
I expected the function: removeStartScreen(); to be called by the animationend event of: thisFadeOutAnim. I'm guessing that removeStartScreen(); is being called by the animationend event of rainbowFlashAnim, because the element startScreenContainer is being assigned the classes thisFadeOut & thisRemove at the same time. So thisFadeOutAnim doesn't get chance to run. I have searched online and have found some info on animationName but I can't get my head around how to implement the concept. Or am I just doing everything all wrong!?
My question: Is there a way to add an event listener to events of a specific animation?
var startButton = document.querySelector('#startButton');
startButton.addEventListener('mouseup', startButtonClicked);
function startButtonClicked(){
startButton.classList.remove('startButtonPulse');
startButton.classList.add('startButtonClicked');
startButton.innerHTML = "LET'S GO!";
startButton.addEventListener('animationend', fadeOutStartScreen);
function fadeOutStartScreen(){
var startScreenContainer = document.querySelector('#startScreenContainer');
startScreenContainer.classList.add('thisFadeOut');
startScreenContainer.addEventListener('animationend', removeStartScreen);
function removeStartScreen(){
startScreenContainer.classList.add('thisRemove');
}
}
}
.startButtonPulse{
animation: buttonPulseAnim 1.5s;
animation-iteration-count: infinite;
animation-timing-function: ease;
}
#keyframes buttonPulseAnim {
0% {transform: scale(1);}
12.5% {transform: scale(1.05);}
25% {transform: scale(1);}
37.5% {transform: scale(1.05);}
50% {transform: scale(1);}
}
.startButtonClicked{
animation: rainbowFlashAnim 0.5s;
animation-iteration-count: 4;
animation-fill-mode: forwards;
}
#keyframes rainbowFlashAnim{
20% {background: cyan;}
40% {background: lime;}
60% {background: magenta;}
80% {background: red;}
}
.thisFadeOut {
animation-name: thisfadeOutAnim;
animation-duration: 0.5s;
animation-fill-mode: forwards;
}
#keyframes thisfadeOutAnim {
from {opacity: 1;}
to {opacity: 0;}
}
.thisRemove {
display: none !important;
}

Ok, so I have worked out a way:
element.addEventListener('animationend', function(e){
if(e.animationName === 'nameOfYourAnimation'{
//do something...
}
});
Beautiful!!

I haven't tested it but I don't you can attach an event to some animation.
I think you shall do it like this
btn1 clicked fire function1
function1:
start animation1 for 2s
after 2s call function2 (user setTimeout)
function2:
start animation2 for 1s
after 1s call some other function

Related

Vue.js animation: Enter after Leave and not simultaneously

I have two components and a fade-in/fade-out animation set up for them.
For a brief moment, both components exist on the page at different opacities, and the scrollbar shows up and disappears.
Is there a way to avoid this? A way to start the fade-in animation only after the fade-out animation is done?
The Animation:
.view-leave-active {
transition: opacity 0.5s ease-in-out, transform 0.5s ease;
}
.view-enter-active {
transition: opacity 0.5s ease-in-out, transform 0.5s ease;
transition-delay: 0.5s; /* Increasing this doesn't seem to work */
}
.view-enter, .view-leave-to {
opacity: 0.5; /* It should be 1, but setting it to 0.5 allows you to see exactly what's happening */
}
.view-enter-to, .view-leave {
opacity: 1;
}
Any help would be very much appriciated!
To further elaborate on my comment: VueJS transition components support the mode property, where you can specify the sequence of transitions when toggling between two elements.
Since you do not want both elements to appear at the same time when one is transitioning in while the other is transitioning out, you should be using:
mode="out-in"
Based on the documentation:
out-in: Current element transitions out first, then when complete, the new element transitions in.

bootstrap modal scale and translate

My bootstrap modal has animation with translate.
.modal.in .modal-dialog {
-webkit-transform: translate(0, 0);
-ms-transform: translate(0, 0);
-o-transform: translate(0, 0);
transform: translate(0, 0);
}
So bootstrap modal fade from top to middle. Everything works fine, but transition is reset when i want to apply scale for this modal like :
.modal.in .modal-dialog {
transform: scale(1.5)
}
so it's okay that my scale reset my translate so i apply mutliple transform conditions :
.modal.in .modal-dialog {
transform: scale(1.5) translate(0,0)
}
but in that case my modal behave like translate and scale in same time and the effect is like zoomIn.
How can i apply that modal dialog is first scale and then on scaled modal apply transition from top to middle ?
Please help !
What you are looking for are so called "keyframes" (if you want to know more, have a look here).
I created a fiddle and tested it shortly: Modal example with keyframes
The following code handles the transformations (scale and translate)
#keyframes mymove {
0% {transform: scale(1);}
50% {transform: scale(1.2);}
100% {transform: scale(1.2) translate(0, 100px);
}
Then you call "animation" instead of "transition" to make the keyframe work like this:
animation: mymove 2s ease-out;
Once the animation is finished, the state of the modal will go back to normal (no scale, no transition) - that's why we have to add the following line:
transform: scale(1.2) translate(0, 100px);
Hope this helps!

bootstrap carousel remove gradient on carousel-control with .less

How do you remove the gradient background from the carousel-control in a carousel without overwriting but replacing in the .less files?
Just override the corresponding properties (see https://github.com/twbs/bootstrap/blob/v3.1.1/less/carousel.less#L81-L89), e.g.:
#import ".../bootstrap.less";
.carousel-control {
&.left, &.right {
background-image: none;
.reset-filter(); // reset IE gradient filters
}
}
For me, this worked (I needed orange color):
.carousel-control.left, .carousel-control.right {
background: orange !important;
filter: progid: none !important;
filter:none !important;
background-image:none;
outline: 0;
opacity: 1;
}

LESS: Mixin with a unique argument to manage css3 transitions

Using LESS CSS, I would like to simplify my code using Mixins to put "out" transitions declarations, but the following syntax is wrong. The problem is in the attribute #color-time definition that has 2 arguments:
.links-transition (#color-time:color 1s, border-color 1s)
{
-webkit-transition:#color-time;
-moz-transition:#color-time;
-ms-transition:#color-time;
-o-transition:#color-time;
transition:#color-time;
}
a
{
color:red;
.links-transition;
}
In official documentation I found that putting a ; at the end, teach LESS how to consider arguments, considering them separated by ;, so one argument in my case like this:
.links-transition (#color-time:color 1s, border-color 1s;)
Unfortunately this does not run. I think it depends since white space... is there a correct syntax to obtain the correct CSS without using 2 arguments in Mixin recall?
Thank you.
You can use string escaping and interpolation like this:
.links-transition (#arg:"color 1s, border-color 1s") {
#color-time: ~"#{arg}";
-webkit-transition:#color-time;
-moz-transition:#color-time;
-ms-transition:#color-time;
-o-transition:#color-time;
transition:#color-time;
}
a {
color:red;
.links-transition ("color 2s, border-color 2s");
}
it will return this CSS:
a {
color: red;
-webkit-transition: color 2s, border-color 2s;
-moz-transition: color 2s, border-color 2s;
-ms-transition: color 2s, border-color 2s;
-o-transition: color 2s, border-color 2s;
transition: color 2s, border-color 2s;
}
hope this does what you want.
For more ideas: there are some additinal approaches/solutions that you can find on SO, like this two for example:
Less CSS: Mixins with Variable Number of Arguments
Multiple properties are getting treated as separate arguments in mixins
Update: in LESS 1.4 beta it works the way you wanted to do it:
.links-transition (#color-time: color 1s, border-color 1s;) {
-webkit-transition:#color-time;
-moz-transition:#color-time;
-ms-transition:#color-time;
-o-transition:#color-time;
transition:#color-time;
}
a {
color:red;
.links-transition (color 2s, border-color 2s;);
}
has the same output as the above solution. Comma separated argunets are possible since 1.3.2, however they can apparently not include whitespaces.

webkit translateX animation is rolling back to initial position

I am trying to do a images gallery for mobile webkit,
The only way it is actually fast enough is using the hardware accelerated translateX .
My problem is that the div take back its initial position at the end of the animation. I add the slideGalLeft class cliking on the left button. to the animated div
You can see an example here, in the callback events section:
http://position-absolute.com/jqtouch/demos/main/#home
.slideGalLeft {
-webkit-animation-name: slideColis;
}
#-webkit-keyframes slideColis {
from { -webkit-transform: translateX(0%); }
to { -webkit-transform: translateX(-100%); }
}
Do not use webkit animation for this as it comes back to the default values once played.
Instead define
.slideGalleft{
-webkit-transition: -webkit-transform 1s linear;
-webkit-transform: translateX(0%);
}
and using Javascript, either set -webkit-transform: translateX(100%); or add a CSS class to your element which set the final transform value and webkit will animate it properly
Guillaume's answer is great. However, if you are looking for hardware acceleration, you must let the webkit engine know you want 3D rendering (what makes hardware acceleration active).
According to http://www.html5rocks.com/tutorials/speed/html5/#toc-hardware-accell, this is done by adding translateZ(0) to your rule, like so:
.slideGalleft{
-webkit-transition: -webkit-transform 1s linear;
-webkit-transform: translateX(0%) translateZ(0);
}
Follow Guillaume's advice beyond that.
Use:
-webkit-animation-fill-mode: none/backwards/forwards/both;
This allows you to define at what end of your animation the element remains when the animation is finished.
I was able to make it work by adding a "display:none" style on the finish of the animation. Use the following CSS:
.paused {
-webkit-animation-play-state: paused;
}
.hiddendiv {
display:none;
}
Then in your jQuery code:
$('div.sideimage').click(
function () {
$(this).removeClass("paused").delay(2000).queue(
function(next) {
$(this).addClass("hiddendiv");
next();
}
);
}
);
Should work!