jQuery – Animation on scroll

Intermediate jQuery tutorial: There are many plugins available out there that provide scrolling interactions and animations like Scroll Magic and Skrollr (I have used Skrollr in the past). However, in a recent project, I needed a single animation to occur when the user scrolls to the panel and using a plugin just for this would add unnecessary weight. So I created some jQuery code and this tutorial will be covering how I achieved this.

 

Demo

 
This tutorial is similar to Hamburger icon animation tutorial. It may help to read that tutorial first as it covers the basics that won’t be repeated in this tutorial. I will be using jQuery to apply a class name which will be the animation defined in CSS. The difference in this tutorial will be the animation will activate in an event of scroll rather than on click.
 
In my example, I have shapes in a SVG that will be animating on scroll. I have used two empty DIVs with a set height to enable scrolling on the page. In a real example, there would be content on the page. Your animated element would be to be further down the page to animate on scroll.
 

  1. First, you need to define your animation in CSS. In my animation, I have circles that will “grow” in size when the user scrolls to the panel. The circles will have zero opacity and be scaled down to zero at first. The transform origin is used to keep my circles in the same position despite being resized.
     
    When the user scrolls to the panel, a class name of “animated” is going to be applied to the circles which will make the circles ease-in to full opacity and scale into its original size.

    #Circle_Discover_1,#Circle_Trust_2,#Circle_Describe_3,#Circle_Predict_4,#Circle_Optimise_5,#Circle_Empower_6,#Circle_Embed_7 {
    	opacity:0;
    	-webkit-transform:scale(0);
    	-ms-transform:scale(0);
    	transform:scale(0);
    	-ms-transform-origin:50% 50%;
    	-webkit-transform-origin:50% 50%;
    	transform-origin:50% 50%;
    	transition:all ease-in .3s;
    }
    #Circle_Discover_1.animated,#Circle_Trust_2.animated,#Circle_Describe_3.animated,#Circle_Predict_4.animated,#Circle_Optimise_5.animated,#Circle_Empower_6.animated,#Circle_Embed_7.animated {
    	opacity:1;
    	-webkit-transform:scale(1);
    	-ms-transform:scale(1);
    	transform: scale(1);
    }
    
  2. NOTE: At the time of writing this tutorial, jQuery doesn’t have support for using addClass, hasClass and removeClass to SVG so I have used this plugin below to do so. Alternatively, you can use $(“.element”).attr(“class”, “yourClassName”);
    (function($) {
        // addClass shim
        var addClass = $.fn.addClass;
        $.fn.addClass = function(value) {
            var orig = addClass.apply(this, arguments);
    
            var elem,
                i = 0,
                len = this.length;
    
            for (; i < len; i++) {
                elem = this[i];
                if (elem instanceof SVGElement) {
                    var classes = $(elem).attr('class');
                    if (classes) {
                        var index = classes.indexOf(value);
                        if (index === -1) {
                            classes = classes + " " + value;
                            $(elem).attr('class', classes);
                        }
                    } else {
                        $(elem).attr('class', value);
                    }
                }
            }
            return orig;
        };
    
        // removeClass shim
        var removeClass = $.fn.removeClass;
        $.fn.removeClass = function(value) {
            var orig = removeClass.apply(this, arguments);
    
            var elem,
                i = 0,
                len = this.length;
    
            for (; i < len; i++) {
                elem = this[i];
                if (elem instanceof SVGElement) {
                    var classes = $(elem).attr('class');
                    if (classes) {
                        var index = classes.indexOf(value);
                        if (index !== -1) {
                            classes = classes.substring(0, index) + classes.substring((index + value.length), classes.length);
                            $(elem).attr('class', classes);
                        }
                    }
                }
            }
            return orig;
        };
    
        // hasClass shim
        var hasClass = $.fn.hasClass;
        $.fn.hasClass = function(value) {
            var orig = hasClass.apply(this, arguments);
    
            var elem,
                i = 0,
                len = this.length;
    
            for (; i < len; i++) {
                elem = this[i];
                if (elem instanceof SVGElement) {
                    var classes = $(elem).attr('class');
    
                    if (classes) {
                        if (classes.indexOf(value) === -1) {
                            return false;
                        } else {
                            return true;
                        }
                    } else {
                        return false;
                    }
                }
            }
            return orig;
        };
    })(jQuery);
    
  3. In the code below, I am binding an event namespace called “scroll.startAnim” to the window of the webpage. Event namespaces enables me to control specific functions that occurs at events such as click, scroll and mouseenter by defining them by name. An example issue would be that I have a variety of functions that happens when I click on a button such as add a class name as well as open a modal. Maybe I would like to disable the modal from opening on click but still add the class name in a particular situation. Instead of disabling all functions on click, I use an event namespace so that I can disable something in particular.
     
    The event namespace in my example, is using event type of “scroll”, the event name is “startAnim” and I am initialising a function called “startAnimation();” in the event. I will be binding and unbinding this event. The syntax for an event namespace is (‘type.namespace’).

    $(function() {
    	$(window).bind('scroll.startAnim', function() {
    		startAnimation();
    	});
    });
    
  4. Next, I am creating my function, “StartAnimation()“. I will begin with defining the variables that I will be used in this function. You can define multiple variables in one rather than repeating “var = ” each time by separating them using a comma like in the example below.
     
    “winHeight” gets the height of the browser height in pixels. “winTop” will return the vertical scrollbar position of the window by using scrollTop(), “animated” is all the circles within my SVG that I will be animating and “topCoords” will find the distance between the top of the page and my SVG on the page.

    $(function() {
    	$(window).bind('scroll.startAnim', function() {
    		startAnimation();
    	});
            function startAnimation() {
        	var winHeight = $(window).height(),
        	    winTop = $(window).scrollTop(),
        	    svg = $('#Data_Possibilities'),
        	    animated = svg.find("g"),
        	    topCoords = svg.offset().top;
           }
    });
    
  5. Now I am going to use these variables to create the magic. The class name “animated” is going to be applied to the groups inside my SVG and then I will unbind my eventnamespace mentioned earlier because it’s now finished.
     
    This will all happen when the window has been scrolled down to 30% of the window’s height above where my SVG is placed on the page. Increasing this number will make the animation activate sooner. If I were to use if(winTop > topCoords), the animation would only activate when the SVG has reached the top of the window when scrolling but there’s a risk that the animation never starts especially if it was near the bottom of the page because there’s no more scrolling for the panel to reach the top of the page.

    $(function() {
    	$(window).bind('scroll.startAnim', function() {
    		startAnimation();
    	});
            function startAnimation() {
        	var winHeight = $(window).height(),
        	    winTop = $(window).scrollTop(),
        	    svg = $('#Data_Possibilities'),
        	    animated = svg.find("g"),
        	    topCoords = svg.offset().top;
           }
           if (winTop + (winHeight * .3) > topCoords) {
               $(animated).addClass('animated');
               $(window).unbind('scroll.startAnim');
           }
    });
    

And now you have an animation on scroll! You can see the demo of this result here. I would greatly appreciate any feedback and feel free to request a tutorial.

Share
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Leave a Reply

Your email address will not be published. Required fields are marked *