Recently I've come across a few sites that will tie window scrolling with animation. When used in a subtle, small fashion, this is kind of cool. When used to change large portions of the view or really screw with scrolling, I detect it. Like most things, it all comes down to how you use it I suppose. But I was thinking recently - how can we do this with Edge Animate? Turns out it is rather simple.

I began by creating a simple animation of a box moving from left to right. That is - unfortunately - the best I can design. Don't blame Edge Animate. Blame me. Next, I disabled autoplay for the animation. If you can't find this, be sure the Stage is selected and uncheck the box.

With autoplay turned off, I then figured out what I needed to do to tie scrolling to animation.

  • First, I need to ensure the animation stays visible.
  • Second, I need to detect a scroll event.
  • Third, I then need to figure out how much the person has scrolled against the total amount they can scroll. Basically, what percentage?
  • Finally, I need to set the animation's current position to that percentage.

Let's break this down. I began by working in the animation's creationComplete event. I added an onscroll event first.

window.onscroll = function(e) {
    var perc = getScrollPerc();
    var animPos = (perc/100) * animSize;
    sym.stop(animPos);
}

So, the first thing I do is get the scrolled percentage. That comes from this function:

//scroll perc - http://www.sitepoint.com/jquery-capture-vertical-scroll-percentage/
	  function getScrollPerc() {
		var wintop = $(window).scrollTop(), docheight = $(document).height(), winheight = $(window).height();
		return (wintop/(docheight-winheight))*100;
	  }

Thankfully Sam Deering had figured this out for me already and posted it here. Next, I figured out where I was, percentage wise, in my animation's timeline. The value animSize is simply the size (timewise) of my animation:

var animSize = sym.getDuration();

Finally, that last line is what moves the animation to a specific point. I was stuck on this for a while as the JavaScript API for Edge Animate does not specifically call out how to do this. My coworker Elaine Finnell pointed out that the stop() method lets you move to a particular position. This is documented but I had not even considered looking at stop() as an option!

This worked great, but I wanted to add one more thing. If I had scrolled down a bit on my test page and reloaded, I wanted the application to recognize this on load and animate accordingly. I added some code to run immediately on load:

//handle initial scroll
if(getScrollPerc() > 0) {
	  console.log('do initial move');
	  var perc = getScrollPerc();
 	  var animPos = (perc/100) * animSize;
	  //timeout is from bugs with the DOM not being 100% ready
	  setTimeout(function() { sym.stop(animPos);}, 0);
}

Basically this is a repeat of my other code, which is kinda bad, but notice the setTimeout. Edge Animate has a bug - or quirk - with working with the DOM in creationComplete. I've run into this before and setTimeout, while lame, works around it. Here is my creationComplete code then as a whole.

(function($, Edge, compId){
var Composition = Edge.Composition, Symbol = Edge.Symbol; // aliases for commonly used Edge classes

   //Edge symbol: 'stage'
   (function(symbolName) {
      
      //scroll perc - http://www.sitepoint.com/jquery-capture-vertical-scroll-percentage/
	  function getScrollPerc() {
		var wintop = $(window).scrollTop(), docheight = $(document).height(), winheight = $(window).height();
		return (wintop/(docheight-winheight))*100;
	  }
	  	   
      Symbol.bindSymbolAction(compId, symbolName, "creationComplete", function(sym, e) {
		  
		  var animSize = sym.getDuration();

		  //handle initial scroll
		  if(getScrollPerc() > 0) {
			  console.log('do initial move');
			  var perc = getScrollPerc();
 			  var animPos = (perc/100) * animSize;
			  //timeout is from bugs with the DOM not being 100% ready
			  setTimeout(function() { sym.stop(animPos);}, 0);
		  }
		  
		  window.onscroll = function(e) {
			  var perc = getScrollPerc();
 			  var animPos = (perc/100) * animSize;
			  sym.stop(animPos);
		  }
		  

      });
      //Edge binding end

   })("stage");
   //Edge symbol end:'stage'

})(jQuery, AdobeEdge, "EDGE-257179350");

And it works awesome! Well, to me anyway. Check it out here: https://static.raymondcamden.com/demos/2014/sep/29/stickandscroll/Untitled-2.html.

Of course, that's my ugly version. Imagine if someone with some decent design skills tried it. Elaine did so - and with help from other Adobians (Max Vujovic and Bem Jones-Bey) came up with this much cooler version: https://static.raymondcamden.com/demos/2014/sep/29/elainesample/scroll.html. Check it out!