Telef Parol
Telef Parol

Reputation: 15

How to improve this animation?

I have three divs on the same line. You can check the example here: http://yoyo.ro/abw just scroll to the bottom of the page to the three boxes: Made to Measure, Instagram and Video Tracking.

When I click the left one, I want the other two to slide to the right and some text to appear. I tried to do it, but it seems that I complicated it so much and it isn't even smooth.

function hideTest(){
         $(".instagram").addClass("slideout");
         $(".videotracking").addClass("slideout");
         $(".instagram").animate({left:"150%"},500);
         $(".videotracking").animate({left:"150%"},500);
         }
function showTest(){
         $(".instagram").animate({left:"33.3%"},500);
         $(".videotracking").animate({left:"66.6%"},500);
         $(".instagram").removeClass("slideout");
         $(".videotracking").removeClass("slideout");
         }

     $(".madetomeasure").on('click',function(){
         var testwidth = $(this).find(".vc_btn3-container").width();
         $(this).find(".vc_btn3-container").css("width", testwidth);

     if(!$(this).hasClass("openslide")){
         hideTest();
         $(".madetomeasure").addClass("openslide");
         $(this).find(".txtbox").animate({left:0},500);}

      else {
            $(this).find(".txtbox").animate({left:"-100%"},500);
            $(".madetomeasure").removeClass("openslide");
            showTest();
             }

         });

here is the css relevant to the JS

   .txtbox{
-webkit-transition: all 0.3s ease-out;
        -moz-transition: all 0.3s ease-out;
        -o-transition: all 0.3s ease-out;
        transition: all 0.3s ease-out;
        width: 66.5%;
        display:none;
        left:-100%;
        padding:0px 15px;
        float:left;
        position:relative;}
   .instagram, .videotracking{position:static;}
   .instagram {left:33.3%;}
   .videotracking{left:66.5%;}
   .instagram.slideout{position:absolute;}
   .videotracking.slideout{position:absolute;}
   .madetomeasure .button{
     z-index:1;
     height:300px;
     background: url(http://yoyo.ro/abw/wp-content/uploads/2016/02/instagram.jpg) 100% 30% !important;
     border: none !important;}
   .madetomeasure.openslide {width:100%;}
   .madetomeasure.openslide .wpb_wrapper {display:flex;}
   .madetomeasure.openslide .txtbox {display:block;}

Thank you so much for the patience... :) I really appreciate it

Upvotes: 0

Views: 56

Answers (1)

Daniel Cheung
Daniel Cheung

Reputation: 4819

As far as I know, your problem of smoothness is because:

  1. jQuery change the inline styling of the animated element per frame. That is a lot of work and you can actually see the action if you inspect your element when it's animating.

  2. CSS does poorly on animating left and right. There are many articles about this but here's one if you don't want to search: https://css-tricks.com/tale-of-animation-performance/


The Solution

Fiddle: https://jsfiddle.net/kv5twc64/1/

The solution is very common, and is used by many CSS libraries, a trick using .active, CSS animation and some JS.

Here I used the transition property for .card:

.card {
  display:inline-block;
  float:left;
  max-width:33.333%;
  position:relative;
  cursor: pointer;
  transition: 0.5s all ease-out;
}

If you don't know, transition will create a tweening effect when the elements' property has changed.

And here is the trick: By using ~ selecting the siblings in CSS and the transform property:

.card.active .desc {
  transform: translateX(0);
}

.card.active ~.card {
  transform: translateX(66.666vw);
}

There are several upsides on using CSS in this case:

  • You can simplify your JS. The JS became:

    $(function(){
        $(".card").eq(0).click(function(){
        $(this).toggleClass("active");
      })
    })
    
  • You can improve webpage performance

  • You can have more choices on (simple) easing functions in CSS (jQuery only offers "swing" by default). Check this out: http://easings.net You can do something like this:

    transition: all 600ms cubic-bezier(0.77, 0, 0.175, 1);
    

Hope this can help. But the lesson here is: Use CSS rather than JS when you can!


P.S. 66.666vw means 2/3 the width of the viewport width.

Upvotes: 1

Related Questions