Thursday, August 25, 2016

CSS3 Animation Trigger with JQuery Click to Other Element

Leave a Comment

I have a reddit-like upvote/downvote situation going on in my Rails app and I'm trying to make a CSS3 animation so that when the user clicks any of the downvote links it triggers the animation.

I'm using JQuery like this:

<div class="animations">   <%= image_tag "ballerino.png", class: "fixed no-display", id: "to-animate", style: "margin-top: 80px; width: 40%" %>    <script>     $("#downvote").on('click',function() {       $('#to-animate').removeClass('fixed');       $('#to-animate').removeClass('no-display');       $('#to-animate').addClass('animation-left-to-right');     });   </script>  </div> <!-- animations --> 

With this further on down the page as a rendered partial for each Joke object:

<div class="text-center col-xs-1">   <% if current_user %>     <div class="width: 100%"><%= link_to " ", joke_up_vote_path(joke), id: "upvote", class: 'glyphicon glyphicon-chevron-up', method: :post, style: "margin-right: 0; margin-left: 0" %></div>   <% else %>     <div class="width: 100%"><%= link_to " ", new_user_session_path, id: "upvote", class: 'glyphicon glyphicon-chevron-up', method: :post, style: "margin-right: 0; margin-left: 0" %></div>   <% end %>   <div class="width: 100%"><h3 style="margin-top: 0; margin-bottom: 0"><strong><%= joke.points %></strong></h3></div>   <% if current_user %>     <div class="width: 100%"><%= link_to " ", joke_down_vote_path(joke), id: "downvote", class: 'glyphicon glyphicon-chevron-down', method: :post, style: "margin-right: 0; margin-left: 0" %></div>   <% else %>     <div class="width: 100%"><%= link_to " ", new_user_session_path, id: "downvote", class: 'glyphicon glyphicon-chevron-down', method: :post, style: "margin-right: 0; margin-left: 0" %></div>   <% end %> </div> 

And finally, here's my CSS for my animations from my application.scss file:

/* ANIMATIONS */  .animation-left-to-right{   animation: l-r-ballerina linear 4s;   animation-iteration-count: 1;   transform-origin: 50% 50%;   animation-fill-mode:forwards; /*when the spec is finished*/   -webkit-animation: l-r-ballerina linear 4s;   -webkit-animation-iteration-count: 1;   -webkit-transform-origin: 50% 50%;   -webkit-animation-fill-mode:forwards; /*Chrome 16+, Safari 4+*/   -moz-animation: l-r-ballerina linear 4s;   -moz-animation-iteration-count: 1;   -moz-transform-origin: 50% 50%;   -moz-animation-fill-mode:forwards; /*FF 5+*/   -o-animation: l-r-ballerina linear 4s;   -o-animation-iteration-count: 1;   -o-transform-origin: 50% 50%;   -o-animation-fill-mode:forwards; /*Not implemented yet*/   -ms-animation: l-r-ballerina linear 4s;   -ms-animation-iteration-count: 1;   -ms-transform-origin: 50% 50%;   -ms-animation-fill-mode:forwards; /*IE 10+*/ }  @keyframes l-r-ballerina{   0% { transform:  translate(-400px,0px)  rotate(0deg) ; }   10% { transform:  translate(-200px,0px)  rotate(-10deg) ; }   20% { transform:  translate(-100px,0px)  rotate(10deg) ; }   30% { transform:  translate(0px,0px)  rotate(-10deg) ; }   40% { transform:  translate(100px,0px)  rotate(10deg) ; }   50% { transform:  translate(300px,0px)  rotate(-10deg) ; }   100% { transform:  translate(3000px,0px)  rotate(-10deg) ; } }  @-moz-keyframes l-r-ballerina{   0% { -moz-transform:  translate(-400px,0px)  rotate(0deg) ; }   10% { -moz-transform:  translate(-200px,0px)  rotate(-10deg) ; }   20% { -moz-transform:  translate(-100px,0px)  rotate(10deg) ;  }   30% { -moz-transform:  translate(0px,0px)  rotate(-10deg) ; }   40% { -moz-transform:  translate(100px,0px)  rotate(10deg) ; }   50% { -moz-transform:  translate(300px,0px)  rotate(-10deg) ; }   100% {-moz-transform:  translate(3000px,0px)  rotate(-10deg) ; } }  @-webkit-keyframes l-r-ballerina {   0% { -webkit-transform:  translate(-400px,0px)  rotate(0deg) ; }   10% { -webkit-transform:  translate(-200px,0px)  rotate(-10deg) ; }   20% { -webkit-transform:  translate(-100px,0px)  rotate(10deg) ; }   30% { -webkit-transform:  translate(0px,0px)  rotate(-10deg) ; }   40% { -webkit-transform:  translate(100px,0px)  rotate(10deg) ; }   50% { -webkit-transform:  translate(300px,0px)  rotate(-10deg) ; }   100% { -webkit-transform:  translate(3000px,0px)  rotate(-10deg) ; } }  @-o-keyframes l-r-ballerina {   0% { -o-transform:  translate(-400px,0px)  rotate(0deg) ; }   10% { -o-transform:  translate(-200px,0px)  rotate(-10deg) ; }   20% { -o-transform:  translate(-100px,0px)  rotate(10deg) ; }   30% { -o-transform:  translate(0px,0px)  rotate(-10deg) ; }   40% { -o-transform:  translate(100px,0px)  rotate(10deg) ; }   50% { -o-transform:  translate(300px,0px)  rotate(-10deg) ; }   100% { -o-transform:  translate(3000px,0px)  rotate(-10deg) ; } }  @-ms-keyframes l-r-ballerina {   0% { -ms-transform:  translate(-400px,0px)  rotate(0deg) ; }   10% { -ms-transform:  translate(-200px,0px)  rotate(-10deg) ; }   20% { -ms-transform:  translate(-100px,0px)  rotate(10deg) ; }   30% { -ms-transform:  translate(0px,0px)  rotate(-10deg) ; }   40% { -ms-transform:  translate(100px,0px)  rotate(10deg) ; }   50% { -ms-transform:  translate(300px,0px)  rotate(-10deg) ; }   100% { -ms-transform:  translate(3000px,0px)  rotate(-10deg) ; } }  .fixed {   position: fixed; }  .no-display {   display: none; } 

Can anyone help me troubleshoot this? I'm new to animations and to JQuery...a bad combination.

ADDED FIDDLE

$(".downvote").on('click', function() {    $('#to-animate').removeClass('fixed');    $('#to-animate').removeClass('no-display');    $('#to-animate').addClass('animation-left-to-right');  });
/* ANIMATIONS */    .animation-left-to-right {    animation: l-r-ballerina linear 4s;    animation-iteration-count: 1;    transform-origin: 50% 50%;    animation-fill-mode: forwards;    /*when the spec is finished*/    -webkit-animation: l-r-ballerina linear 4s;    -webkit-animation-iteration-count: 1;    -webkit-transform-origin: 50% 50%;    -webkit-animation-fill-mode: forwards;    /*Chrome 16+, Safari 4+*/    -moz-animation: l-r-ballerina linear 4s;    -moz-animation-iteration-count: 1;    -moz-transform-origin: 50% 50%;    -moz-animation-fill-mode: forwards;    /*FF 5+*/    -o-animation: l-r-ballerina linear 4s;    -o-animation-iteration-count: 1;    -o-transform-origin: 50% 50%;    -o-animation-fill-mode: forwards;    /*Not implemented yet*/    -ms-animation: l-r-ballerina linear 4s;    -ms-animation-iteration-count: 1;    -ms-transform-origin: 50% 50%;    -ms-animation-fill-mode: forwards;    /*IE 10+*/  }  @keyframes l-r-ballerina {    0% {      transform: translate(-400px, 0px) rotate(0deg);    }    10% {      transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      transform: translate(-100px, 0px) rotate(10deg);    }    30% {      transform: translate(0px, 0px) rotate(-10deg);    }    40% {      transform: translate(100px, 0px) rotate(10deg);    }    50% {      transform: translate(300px, 0px) rotate(-10deg);    }    100% {      transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-moz-keyframes l-r-ballerina {    0% {      -moz-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -moz-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -moz-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -moz-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -moz-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -moz-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -moz-transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-webkit-keyframes l-r-ballerina {    0% {      -webkit-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -webkit-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -webkit-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -webkit-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -webkit-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -webkit-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -webkit-transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-o-keyframes l-r-ballerina {    0% {      -o-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -o-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -o-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -o-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -o-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -o-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -o-transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-ms-keyframes l-r-ballerina {    0% {      -ms-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -ms-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -ms-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -ms-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -ms-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -ms-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -ms-transform: translate(3000px, 0px) rotate(-10deg);    }  }  .fixed {    position: fixed;  }  .no-display {    display: none;  }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>    <div class="fixed no-display" id="to-animate" style="margin-top: 80px; width: 40%; background: blue; height: 20px;">    Box to Animate  </div>    <div class="text-center col-xs-1">        <div class="width: 100%">      <a class="upvote glyphicon glyphicon-chevron-up" style="margin-right: 0; margin-left: 0" rel="nofollow" data-method="post" href="#"></a>    </div>    <div class="width: 100%">      <h3 style="margin-top: 0; margin-bottom: 0"><strong>0</strong></h3>    </div>    <div class="width: 100%">      <a class="downvote glyphicon glyphicon-chevron-down" style="margin-right: 0; margin-left: 0" rel="nofollow" data-method="post" href="#"></a>    </div>  </div>

I think this simulates the problem. I added a div instead of an image, but with the same id so it's visible...

2 Answers

Answers 1

I am not really sure that I understood your problem, but are you expecting something like this ?

$(".downvote").on('click', function() {    //$('#to-animate').removeClass('fixed');    $('#to-animate').removeClass('no-display');    $('#to-animate').addClass('animation-left-to-right');  });
/* ANIMATIONS */    .animation-left-to-right {    animation: l-r-ballerina linear 4s;    animation-iteration-count: 1;    transform-origin: 50% 50%;    animation-fill-mode: forwards;    /*when the spec is finished*/    -webkit-animation: l-r-ballerina linear 4s;    -webkit-animation-iteration-count: 1;    -webkit-transform-origin: 50% 50%;    -webkit-animation-fill-mode: forwards;    /*Chrome 16+, Safari 4+*/    -moz-animation: l-r-ballerina linear 4s;    -moz-animation-iteration-count: 1;    -moz-transform-origin: 50% 50%;    -moz-animation-fill-mode: forwards;    /*FF 5+*/    -o-animation: l-r-ballerina linear 4s;    -o-animation-iteration-count: 1;    -o-transform-origin: 50% 50%;    -o-animation-fill-mode: forwards;    /*Not implemented yet*/    -ms-animation: l-r-ballerina linear 4s;    -ms-animation-iteration-count: 1;    -ms-transform-origin: 50% 50%;    -ms-animation-fill-mode: forwards;    /*IE 10+*/  }  @keyframes l-r-ballerina {    0% {      transform: translate(-400px, 0px) rotate(0deg);    }    10% {      transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      transform: translate(-100px, 0px) rotate(10deg);    }    30% {      transform: translate(0px, 0px) rotate(-10deg);    }    40% {      transform: translate(100px, 0px) rotate(10deg);    }    50% {      transform: translate(300px, 0px) rotate(-10deg);    }    100% {      transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-moz-keyframes l-r-ballerina {    0% {      -moz-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -moz-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -moz-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -moz-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -moz-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -moz-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -moz-transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-webkit-keyframes l-r-ballerina {    0% {      -webkit-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -webkit-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -webkit-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -webkit-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -webkit-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -webkit-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -webkit-transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-o-keyframes l-r-ballerina {    0% {      -o-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -o-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -o-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -o-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -o-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -o-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -o-transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-ms-keyframes l-r-ballerina {    0% {      -ms-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -ms-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -ms-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -ms-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -ms-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -ms-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -ms-transform: translate(3000px, 0px) rotate(-10deg);    }  }  .fixed {    position: fixed;  }  .no-display {    display: none;  }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>        <div class="fixed no-display" id="to-animate" style="margin-top: 80px; width: 40%; background: blue; height: 20px;">    Box to Animate  </div>    <div class="text-center col-xs-1">        <div class="width: 100%">      <a class="upvote glyphicon glyphicon-chevron-up" style="margin-right: 0; margin-left: 0" rel="nofollow" data-method="post" href="#"></a>    </div>    <div class="width: 100%">      <h3 style="margin-top: 0; margin-bottom: 0"><strong>0</strong></h3>    </div>    <div class="width: 100%">      <a class="downvote glyphicon glyphicon-chevron-down" style="margin-right: 0; margin-left: 0" rel="nofollow" data-method="post" href="#"></a>    </div>  </div>

Answers 2

If you want your page to refresh after the animation end fires or the transition end event fires, you'll need to listen for one or the other. I've added a listener for both including browser prefixes. Your animation is long and continues off screen, so it looks pretty quirky, but you get the general idea.

$(".downvote").on('click', function() {    var href = "http://stackoverflow.com/questions/38934608/css3-animation-trigger-with-jquery-click-to-other-element";     $('#to-animate').one("webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend webkitAnimationEnd oanimationend oAnimationEnd msAnimationEnd animationend", function(e) {      //Stub handler      //Your logic goes here      if(confirm("Detected " + e.type + " event.  Redirect to " + href + "?")){        window.location.href = href;      }      })    $('#to-animate').removeClass('fixed');    $('#to-animate').removeClass('no-display');    $('#to-animate').addClass('animation-left-to-right');  });
/* ANIMATIONS */    .animation-left-to-right {    animation: l-r-ballerina linear 4s;    animation-iteration-count: 1;    transform-origin: 50% 50%;    animation-fill-mode: forwards;    /*when the spec is finished*/    -webkit-animation: l-r-ballerina linear 4s;    -webkit-animation-iteration-count: 1;    -webkit-transform-origin: 50% 50%;    -webkit-animation-fill-mode: forwards;    /*Chrome 16+, Safari 4+*/    -moz-animation: l-r-ballerina linear 4s;    -moz-animation-iteration-count: 1;    -moz-transform-origin: 50% 50%;    -moz-animation-fill-mode: forwards;    /*FF 5+*/    -o-animation: l-r-ballerina linear 4s;    -o-animation-iteration-count: 1;    -o-transform-origin: 50% 50%;    -o-animation-fill-mode: forwards;    /*Not implemented yet*/    -ms-animation: l-r-ballerina linear 4s;    -ms-animation-iteration-count: 1;    -ms-transform-origin: 50% 50%;    -ms-animation-fill-mode: forwards;    /*IE 10+*/  }  @keyframes l-r-ballerina {    0% {      transform: translate(-400px, 0px) rotate(0deg);    }    10% {      transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      transform: translate(-100px, 0px) rotate(10deg);    }    30% {      transform: translate(0px, 0px) rotate(-10deg);    }    40% {      transform: translate(100px, 0px) rotate(10deg);    }    50% {      transform: translate(300px, 0px) rotate(-10deg);    }    100% {      transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-moz-keyframes l-r-ballerina {    0% {      -moz-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -moz-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -moz-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -moz-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -moz-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -moz-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -moz-transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-webkit-keyframes l-r-ballerina {    0% {      -webkit-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -webkit-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -webkit-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -webkit-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -webkit-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -webkit-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -webkit-transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-o-keyframes l-r-ballerina {    0% {      -o-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -o-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -o-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -o-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -o-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -o-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -o-transform: translate(3000px, 0px) rotate(-10deg);    }  }  @-ms-keyframes l-r-ballerina {    0% {      -ms-transform: translate(-400px, 0px) rotate(0deg);    }    10% {      -ms-transform: translate(-200px, 0px) rotate(-10deg);    }    20% {      -ms-transform: translate(-100px, 0px) rotate(10deg);    }    30% {      -ms-transform: translate(0px, 0px) rotate(-10deg);    }    40% {      -ms-transform: translate(100px, 0px) rotate(10deg);    }    50% {      -ms-transform: translate(300px, 0px) rotate(-10deg);    }    100% {      -ms-transform: translate(3000px, 0px) rotate(-10deg);    }  }  .fixed {    position: fixed;  }  .no-display {    display: none;  }
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>    <div class="fixed no-display" id="to-animate" style="margin-top: 80px; width: 40%; background: blue; height: 20px;">    Box to Animate  </div>    <div class="text-center col-xs-1">        <div class="width: 100%">      <a class="upvote glyphicon glyphicon-chevron-up" style="margin-right: 0; margin-left: 0" rel="nofollow" data-method="post" href="#"></a>    </div>    <div class="width: 100%">      <h3 style="margin-top: 0; margin-bottom: 0"><strong>0</strong></h3>    </div>    <div class="width: 100%">      <a class="downvote glyphicon glyphicon-chevron-down" style="margin-right: 0; margin-left: 0" rel="nofollow" data-method="post" href="#"></a>    </div>  </div>

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment