Page Animation Framework

I recently pieced together some web animation machinery. A few items seem to be fairly new to the web development landscape. I share links and lessons below.

HTML and CSS are simple enough that I manually wrote those for my old site (in notepad) years ago, but I had effectively zero prior experience with jQuery before starting work on this new shindig. I know jQuery to be something other than new, but it’s nice how easy and well supported it is now. This page was the instigator for dumping the following into my known universe. Check it out as full working demo.

1. Custom jQuery functions
Event based functions that are guaranteed exactly once per matching element. Allows for Functionality to be logically encapsulated with the element being acted upon rather than from the triggering entity.
I created init and update calls like a barebones little state machine:
jQuery(document).ready(function() { jQuery("#myTexts > span").trigger("span:onInit"); });
jQuery(window).scroll(function() { var y = jQuery(window).scrollTop(); jQuery("#myTexts > span").trigger("span:onUpdate", [y]); });
jQuery("#myTexts > span").on("span:onInit", {a:"a"}, function(event)
jQuery("#myTexts > span").on("span:onUpdate", {a:"a"}, function(event, scrollVal)

2. Data attribute storage and access on DOM elements
The ability to initialize values in the html as well as store and retrieve dynamically and uniquely to individual elements was invaluable for keeping things clean, simple, and ultimately scaleable.
Note that you can even insert arrays in attributes. In HTML like so:
<div data-indices="[1,2,3,4,5]">
And you can even include text elements by using excape characters such as I did for background colors:
<div data-colors="[&#34;#fce2f2&#34;, &#34;#cdf4c1&#34;, &#34;#9ed88d&#34;]">

3. The animation library powering the whole deal
Fast, flexible, easy. What more could you want?
$element.velocity({attributeName:myTargetValue, attribute2Name:myTargetValue2}, {option1:value1, option2:value2, queue:false});
One aspect that snagged me was not understanding the above structure of two lists of parameters with desired values. The silent failure of webpages then led to lots of confusion as I attempted to tune values that weren’t actually doing anything.

Additionally, for anyone wanting to use this – Be warned that the ‘queue:false’ option does not mean that new animations will necessarily overwrite old ones immediately. The old ones still play out, the new ones simply do not wait for the old to finish before starting. (They’re in parallel.) This caught me when I had converse opacity (on/off) animations. If they’re set with different durations then the shorter one could start later than the other and still finish first, causing the end result to be the final value of the ‘older’ animation that was triggered first.
The symptom appeared as the opacity and status flags getting out of sync despite the simple following code:
if(stateOn) {
myText.velocity({opacity:0}, {duration:timeOut, queue:false});
dynData.stateOn = false; }
else {
myText.velocity({opacity:1}, {duration:timeIn, queue:false});
dynData.stateOn = true; }

This tricked me into thinking there might be a threading issue or a failure in the exactly once call guarantee from #1.

4. Clearing and centering floating elements
Covers tons of other info important to someone trying to piece together the anarchy of floating html elements. The section of centering was most relevant for me. With resulting structure:
<div id="fixedWrap">
<div id="floatWrap">
<div id="innerWrap">
<!-- Dynamic floating content -->

The fixed element holds the floating content in the same visual place as the user scrolls down the page triggering animations. The float element effectively “shrink-wraps” the contained elements. And the inner element shifts the whole thing over to be nicely centered.
#fixedWrap { position: fixed; width: 100%; }
#floatWrap { float: left; position: relative; left: 50%; }
#innerWrap { position: relative; left: -50%; }

Leave a Reply

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