Reproducing A Clever Animation Product, Part 10

Continuing on from yesterday, once we get the transforms into a nice compact list in time order by type and by element we can go ahead and define the tweens for each type of transformation stream. However, I noticed that I had a particular type of tween that took extra parameters.

The addTransformToList function, however, only allows for a single beginning and ending state parameter. What I chose to do today, which was needlessly complex, was to make the addTransformToList function handle strings with multiple parameters, separated by commas, if they are enclosed in parentheses. Here’s how the calls look, next to the original tween definitions:

Here you’ll notice that the starting and ending state parameters for the scale transformation are in the form "(1.0,1.0)" and "(2.0,2.0)". This is needlessly complex because I could just provide a single value for the scale factor in the addTransformToList function and use it for both the X and Y scale factors in the bcDefineScaleTween function. If I want to be able to manipulate the X and Y scales independently I can just use the scaleX and scaleY transforms, couldn’t I?

Well, I thought it was a good exercise so this is the way I did it. I wouldn’t do this a second before it was needed in a professional environment (in Agile and TDD space you don’t do anything until you absolutely need to, which is supposed to prevent you from taking detours to guild various lilies), but if the point of these exertions is just to learn then the occasional lily will get guilded.

Since I’ve chosen to support this type of compound parameter (and note that different CSS transform functions may take 2, 3, 4, 6, or even 16 parameters) I also found it necessary to do some checking to see if the formats are good. Note the calls to the parseStateDef near the beginning of the addTransformToList function. (I’m using the alert function as a placeholder. I would do something more elegant or “real” if I was going to release this code into the wild.)

The code that actually does the parsing and checking is here. For now I only test to see if the parameters are valid numbers, strings, or booleans. Everything else I don’t worry about for now. If the input value is a string I check to see if the first character is an open parenthesis, in which case it is sent off to the parseStringMultiple function to be broken into parts which are themselves tested separately.

OK, if I don’t get sidetracked I should be able to stitch everything back together and make it run again tomorrow.

Posted in Tools and methods | Tagged , , | Leave a comment

Reproducing A Clever Animation Product, Part 9

Yesterday’s attempt wasn’t too bad; I needed to fix the declaration and use of the object that holds the transform information (yesterday’s form only works if you initialize the internal member values with literals) and I needed to tweak a couple of indexes. The corrected code is shown below, along with an extra function for displaying the information.

Here is how I loaded up the array. It includes a series of three transformations for the left location of the first object, but out of order. It then displays the information before sorting, does the sort, and displays the information again after the sort.

Here’s the output before the sort:

TransformList
Element: handle001
Type: left
start: 301 end: 25 begin: 0 duration: 0.75 method: linear
start: 301 end: 25 begin: 4 duration: 0.5 method: linear
start: 25 end: 301 begin: 2 duration: 1 method: linear
Type: opacity
start: 0 end: 1 begin: 0 duration: 0.75 method: linear
Element: handle002
Type: top
start: -25 end: 125 begin: 0.5 duration: 0.75 method: linear
Type: opacity
start: 0 end: 1 begin: 0.5 duration: 0.75 method: linear

…and here it is after the sort:

TransformList
Element: handle001
Type: left
start: 301 end: 25 begin: 0 duration: 0.75 method: linear
start: 25 end: 301 begin: 2 duration: 1 method: linear
start: 301 end: 25 begin: 4 duration: 0.5 method: linear
Type: opacity
start: 0 end: 1 begin: 0 duration: 0.75 method: linear
Element: handle002
Type: top
start: -25 end: 125 begin: 0.5 duration: 0.75 method: linear
Type: opacity
start: 0 end: 1 begin: 0.5 duration: 0.75 method: linear

Now that this is done I can modify the tween definition functions to write out the full and correct state of every element for every animation step.

Also, it can be argued that it’s unnecessary to specify the beginning and ending state of each transform. The properties to be transformed are already initialized, so in theory the transform functions would only have to specify what the new value should be. That would obviate the need to correctly specify the initial value of a property as being the same as the final value from then end of a previous transformation. I note that the Greensock product does this, including not just a “to” transform but also a “from” transform. If you initialize all the elements where you want them to end up you can get an idea of the final layout, and then the animation sequence can start from where you specify and end up where they were initialized. That said, one thing at a time…

Posted in Tools and methods | Tagged , , | Leave a comment

Reproducing A Clever Animation Product, Part 8

I found it necessary to create a list of elements that will be transformed during the animation. Within each list of elements there will be a sublist of transform types. Within each list of transform types there will be a list of the actual transforms. Element zero of the first two dimensions of the array will contain the name of the element and transform type, respectively.

The first set of calls should be to define the transforms as the programmers thinks of them. Once all the transforms are defined the code sweeps through the list and, where it finds multiple transforms of a specific type for a specific element, reorders that list of transforms by starting time.

I’m assuming that later transforms (in list of like transforms for a given element) will determine the state of the element from their beginning in time through to the end of the animation. It will not be possible to embed transformation streams. For example, if stream A runs from 3.0 seconds to 9.0 seconds and stream B runs from 5.0 seconds to 7.0 seconds, the states defined by stream B will apply from 5.0 seconds to the end of the animation. The animation will not use the values from stream A from 7.0 to 9.0 seconds. There has to be a rule and this is the one I’m choosing. It has the virtue of being simple while also allowing anything to be done at any time.

The code will look something like this. I haven’t got time to debug it today; that will be tomorrow’s project and I’ll post any mods I make then (the chances of this being perfect as is are somewhere between zero and nothing…). Once I know this works I can readjust the previously existing functions to write out the transformation streams.

Once I get this working it should enable me to come up with a better way to specify starting times for each transformation stream. The Greensock product allows the programmer to specify starting times relative to other events and not necessarily in absolute terms, which (as they point out here) is cumbersome to keep track of and modify efficiently. The product also supports a flexible, shorthand notation for specifying transformations of increasing complexity, assuming default values for parameters not supplied. It appears to do this using function parameters in something like the object literal format.

Posted in Tools and methods | Tagged , , | Leave a comment

Reproducing A Clever Animation Product, Part 7

Drawing things out graphically is always good to clarify thoughts, so I’ve done that with the problem at hand.

Here I show the array of animation steps in a shorthand form. The red areas show steps where multiple assignments are given for a particular property but only one is changing (going forward, things might look a little different going backward) and only that one should be used. The green areas show steps where multiple assignments are given for a property, none of them are changing, but only one is supposed to be used. The yellow areas show where multiple assignments might be given for a particular property but it doesn’t matter which one is used. The gray areas show property assignments that a) don’t change and b) should not be used.

This makes it clear why the bcChainFlag variable’s ability to inhibit the assignments in the upper right gray area works. It would also prevent the seconds assignments in steps 7 and 8. Inhibiting the assignments in the lower left gray areas isn’t necessary because if both are written out and executed then only the second one will affect what the user sees. We do waste operations there, however.

What we need, therefore, is a way to ensure that a property assignment gets written for every animation step, since we want to have enough information available in each step to recreate the entire visual state. We can do this in two ways.

One is to write multiple streams of commands that include blanks where another assignment should be used as follows. Running the eval statement with an empty string does nothing so we’re free to fill up the animation array with blanks. It wastes some time but it’s simple and consistent.

The other is to place updated values in the same stream of commands as follows. Either we have to rely on the programmer to specify beginning and ending ranges explicitly or we have to make the generation of subsequent streams of commands smart enough to know what to overwrite. We can do that by scanning through the animation commands to look for the stream that modifies the property in question, or we can maintain an external registry that does the search and returns the index of the array to write the partial stream to.

I think I prefer the latter option. Doing a bit of extra work up front in order to have a cleaner animation stream seems like the right thing to do.

In order to do this we’ll need a few ground rules.

  1. We either have to ensure that the programmer issues the commands in order of increasing time of the beginning of each transition or we have to store information about the transitions in a list and then sort them and process them in time order. Given what I see in the demonstrations it appears that the Greensock product does this or something similar.
  2. In order to keep things straight we need to limit the number of ways to affect individual properties of elements. We do not, for example, want to support six different ways of specifying the left location of an element. Since we control the ‘registry’ we can still do things in a clear and modular way.
  3. This method appears to eliminate the need for specifying begin and end states outside of the animation stream itself since the first and last elements will contain all of the necessary information. This is a good thing.

Come to think of it that may be it. I’ll see how it works out when I try implementing this on Monday.

Oh, one more thing. I’ll also have to think about situations where different properties may produce unexpected results. On the other hand this is clear enough and looks like it would work in both directions.

Posted in Tools and methods | Tagged , , | Leave a comment

Reproducing A Clever Animation Product, Part 6

The next logical thing to think about with the animation capability is the idea of specifying the full state of every element during every time step. If this is done then we don’t have to worry about missing animation steps with important state changes. We can use the slider to advance to random points and we can increase the apparent speed of the animation by advancing by more than one step at a time. The downside is that more data is required to specify the full states during every animation step and it becomes more difficult to manage multiple streams of transitions that affect the same property of an element. The latter of those two issues seems to be the more problematic.

Let’s think about transitions that set the location of the left edge of an element. If there’s only one series of transitions then there’s no problem; we just set the position for every time step whether the element is in view or not. If there’s a second series of transitions that start after the first then we have to figure out how to use the one that applies and ensure that it works when the animation is moving forwards or backwards. We did some of that in a simple way by setting and clearing the bcChainFlag variable but now we need to do the right thing for potentially numerous transition effects for multiple elements.

For now I’m simply going to list all the issues I can think of.

  • Multiple transition types may affect a single characteristic of an element. For example, the left position of an element could be affected by setting the left value directly or by applying the style.transform CSS properties translateX(x), translate(x,y), translate3d(x,y,z), matrix(n,n,n,n,n,n), and matrix3d(n,n,n,n,n,n,n,n,n,n,n,n,n,n,n,n). Depending on the parameters used, setting the display and opacity CSS values may also have the same (or different) effects. That said, there’s no formal need to support every possible transition type.
  • We have to ask how much we should try to get our framework to bail the programmer out of possibly bad decisions or how much we should make the programmers sweat the details.
  • To that end we could add more parameters to the specification of transitions to allow the programmer to control the range of steps that get filled in, by a transition–even when nothing is actually changing. Here I observe that the Greensock product I’m emulating (in a basic form) allows for a very simple specification of transitions and must be doing some of this in the background.
  • Right now I’m writing out full JavaScript statements to be executed by the eval() command. In theory I could accomplish the same thing with a series of codes and a giant switch statement to handle the possibilities. The latter possibility occurs to me because it might be easier to write code to process numbers and parameters directly to figure out how to resolve conflicts between multiple transitions. That said, I feel like the statement/eval() approach makes more sense because the capabilities feel more modular and independent that way. I don’t know that’s true, I just feel it–for now.
  • Also the same prioritizing can be accomplished by parsing out the raw text of the JavaScript statements. In either case I’d have to figure out some kind of hierarchy of effects to know how to resolve potential conflicts.

Basically, I just need to think about this more before moving ahead.

Posted in Tools and methods | Tagged , , | Leave a comment

Reproducing A Clever Animation Product, Part 5

One thing I snuck into yesterday’s code examples without explaining is a way to use different animations for the same property of the same element. The way it works now the functions that generate tween information install commands into the list of animations to perform during each step in the following way, after each element is initialized using bcInitElement function and additional functions for properties not defined therein:

  1. Assign the state in the beginning initialization, in the bcInitializations[0] array.
  2. Assign the same state in the animation step before the main series of transformations is to start, if the series of transformations begins after the first animation step. This is added so the element can be returned to its original state when the animation is run in reverse.
  3. Assign the series of transformations to the desired, contiguous range of animation steps.
  4. Assign the final transformation in the series to the “ending” initialization, in the bcInitializations[1] array. This is used to “initialize” the state of each element when the simulation is run in reverse.

All well and good, but what if I want to do a series of transformations to an element, even if they involve different properties? Suppose I want to make an element visible by changing its opacity from 0 to 1 from second 1 to second 2.5, then move its left edge from 100px to 401px from second 3.5 to second 5?

Most of it would work fine. The second initialization would start where the first left off, so the initialization for the 3.5-second mark minus one animation step would not be a problem (see step 2, above). The series of transformations themselves, described in step 3, above, also would not be a problem (assuming the animator didn’t try to overlap the transformation series in time, in which case the latter one would always be the last called). The “ending” transform, which is actually the beginning transform when running in reverse from the end, would also not be a problem, because the latter transform would be set after the first one. In that case see step 4, above.

The problem comes from step 1, above. If the second transformation is allowed to initialize the element to the spot where the second transformation ends (which should be where the first transformation begins), then it would override the initial setting of the first transformation series.

Fortunately, there’s a way around that. If you’ll notice in yesterday’s code snippets, the initial state is only assigned to the bcInitializations[0] array if a variable called bcChainFlag is not set. That means that the initialization is inhibited is that flag is set, and this is done by calling the bcSetChainFlag function.

Here are the relevant code snippets.

It should be noted that the sequence above would actually work fine without the bcSetChainFlag() call because the series of initializations makes sense. It is absolutely necessary in the following scenario, however, where the visible parent div is 400px wide.

In this case a transformation from 17.70 to 18.40 seconds slides the element onto the visible part of the parent div and and a one that bumps it a little more from 19.40 to 19.90 seconds. If the second set of transforms were allowed to govern the initialized state of the element then it would appear in the middle of the parent div at the beginning of a long animation because the initialization for the 19.40 second state would override the initialization for the 17.70 second state.

The Greensock animation package handles this much more smoothly, of course, but this is an intermediate fix I had to put in while I slowly build up the parts of it that I’m actually going to recreate. Each exercise provides more insight into what is needed.

Finally, I use the “bc” prefix on a lot of functions and variables to indicate that all of these items would ideally be placed in a separate JavaScript package which would be referenced and which would have its own namespace. I haven’t bothered doing this with any of the examples I’ve created so for, but I’ve at least established a convention if I ever decide to do so.

Posted in Tools and methods | Tagged , , | Leave a comment

Reproducing A Clever Animation Product, Part 4

Today I’m adding two new types of tweens, but once this is done the method for doing subsequent ones should be pretty clear.

The first type is for hiding elements using the display property. This is useful for longer animations where older elements must be hidden so new ones can be seen.

The second type is for changing the scale using the transform property. This is interesting because I’ve chosen a form that takes two parameters rather than just one. Note that the scale function works by applying the operation from the center of the affected element. The element being scaled appears to stay in the same location while all edges of the element move to or away from the center in the same proportion along both the the x- and y-axes. The scaling factor for each axis is specified separately but the x-axis factor changes the right and left edges simultaneously while the y-axis factor changes the top and bottom edges simultaneously. If you want the scaling to appear to be based on another location you’ll have to add offsetting animations to the top and left properties of the element. Finally, if the initial scale for an element is anything other than one, then an extra scale command has to be issued to do so. See the example below for how this can be done.

Here’s an updated animation that uses the three new types of tweens we’ve added.

Posted in Tools and methods | Tagged , , | Leave a comment

Reproducing A Clever Animation Product, Part 3

Today I implemented a few more basic animation features and gained more insight into how the Greensock animation product probably works.

The first thing I did was add the capability to pause and continue the animation. That was trivial.

I had previously implemented a list of commands that allows the script to return all animated elements to their original states so everything could be initialized when the user asked to rerun the animation. If I wanted to run the animation in reverse I had to create yet another structure that stored the end state of each element. I did this by adding a second dimension to the bcActivitiesList array. Major element zero holds the list of beginning states while major element one holds the list of ending states. I also had to change the increment step to a negative number when needed. Clicking the rerun button resets the animation step to zero and the increment to positive one. Clicking the run in reverse button resets the animation step to its highest value and sets the increment to negative one. The pause and continue buttons work whether the animation is moving forwards or backwards. So far, so good, right?

Not right.

The way this works not the only information the script has access to for any animation step is about elements that change in some way. If we’re moving forward through the animation this isn’t a big deal because the incremental changes naturally proceed from their initial state. If we walk through the animation in reverse, though, what might we know about the state of an element in the step before we’ve modified it for the first time? We might not know anything, except for the initial value we store in the initialization array. I therefore reasoned that the tween functions should each inset a copy of the initial state into the list of updates in the animation step before modifications begin (assuming they begin after step zero).

This actually works well–if the animation sweeps through every animation step in reverse. That happens when the user clicks on the run in reverse button but it might not happen if the animation step is set to an arbitrary value.

Enter the slider bar.

I added a slider bar with the idea of allowing the user to be able to set the animation to an arbitrary point. First, the slider is only available in browsers that support HTML5, but for my purposes that’s a minor issue. A bigger issue is the previously-mentioned lack of state information for every element during every time step. The slider moves with the animation and when the user moves it when the animation is not running on its own. Moving the slider by hand only returns a value when the user stops moving and releases the slider, which will leave the animation step at an arbitrary value. If no update was performed during that step for a given element then that element might not reflect the state it’s supposed to be in.

This indicates that, in order for the slider mechanism to work properly, the state of each element has to be entered into the activity list for every animation state. This isn’t actually a big deal if the number of animated elements is small, but I wonder how things would look as the number of animated elements grows. What are the limits to the complexity and number of elements we might be able to handle smoothly? (Think of the animated fountain of green balls shown in the Greensock demo linked above.) Those are questions for next week. In the meantime here is the demo in its current state. Play around with it and let me know if you see the same things I do.

And, here is the code in its increasingly entropic glory.

Posted in Tools and methods | Tagged , , | Leave a comment

Reproducing A Clever Animation Product, Part 2

Today I did some experiments to try to figure out why the animations I’ve created seem to hitch and hiccup slightly from time to time. Again, this work is based on recreating the basic functionality of the Greensock animation product described here and especially here.

The first thing I thought of was that the drawing operations themselves might be taking long enough that they don’t complete during every animation step (about 16 ms at 60 frames per second). I therefore set the update loop to only draw the items every other scan. This approach didn’t relieve the hitching and updating at 30 fps left the animation looking slightly choppy.

The next thing I tried was recording the elapsed time for every drawing loop and displaying the value if it was greater than 16 ms. However, the value was never displayed, so it appears that the speed of the drawing isn’t an issue.

Next it occurred to me that if an element has to travel far enough and in fine enough increments that the difference between traveling three or four pixels in an update, particularly when advancing by the smaller number doesn’t happen often, might be enough to look like a hitch. I therefore set the durations of the transitions to be shorter so each increment is larger, and I also incorporated a fade-in by ramping up the opacity. The combination of these two changes made things look pretty smooth.

I also observe that the example animation in the second Greensock link, above, involves transitions that are relatively short, so there isn’t time for anything to hitch. That may be the key to the whole enterprise. That said, there’s an animation in the first link that shows a fountain of green balls. I will try to reproduce something like that and see how it looks. Most of the effects can be replicated (though perhaps not as well as the originals), and I’ll be working through duplicating some of them over the next few posts.

In the meantime, I found it necessary to add an initialization capability so rerunning the animation starts from a good place. Here’s the basic code in its entirety.

Posted in Tools and methods | Tagged , , | Leave a comment

Reproducing A Clever Animation Product, Part 1

I’ve been working on an introductory animation for my soon-to-be-released landing page (what, stumbling into a random WordPress post and a tiny resume link isn’t the pithiest possible introduction?), and I was looking around and playing with various ideas when I stumbled across this site and this video. This company makes what look to be a very impressive set of products with even more impressive licensing terms. However, since the point of this website, for now, is to help me learn new things when I’m not describing and recreating some of the work I’ve done from earlier in my career, I used the information presented as inspiration for creating my own basic animation framework.

The first thing I want to point out as I begin this week of related posts is that I haven’t looked at the company’s and product’s code at all. I’m just trying to recreate some basic functionality and use what I see as inspiration for my own explorations. The things I found helpful were the ideas embodied in the animation product. I would not assume that I’ve figured out exactly how they did what they did but I’ve definitely been able to recreate some of the same functionality in my own way. This is in keeping with my goal of ensuring that all the running code on this site is my own.

If you check out the linked video you see a tool that uses a very terse JavaScript syntax that produces very nice, very controllable effects. The key thing is that the animations produced run quickly and smoothly. I a) needed an animation and b) like to build tools so this was a natural thing to tackle.

I spent some of the past weekend building up a rather cumbersome first attempt at an animation framework. It was big and it was kludgy and it was slow and it sometimes hiccuped. I recognized that I needed a system that carried out the following steps:

  1. specify element
  2. specify initial properties
  3. specify final properties
  4. specify duration
  5. specify start time
  6. build list of commands that run for every animation call

What I originally came up with was a way to create an array with links bunch of elements, create arrays with transformation objects that describe what to do with each element, and a way to cycle through the lists of elements and transformations to see what needs to be done… during every animation step. Since the animation steps might be happening every 60th of a second on a modern device (possibly less often on an older machine… like a Palm Pre like maybe), you can imagine there’s quite a bit of overhead. I also made the original animation space rather large which involved long traversals that took up a decent amount of time. The original animations worked but they took a lot of code to express and like I said, they weren’t always very smooth. Then I noticed a couple of things that helped.

One was that the example animation shown in the linked video was comparatively small, and the transitions all happened rather quickly. I therefore resolved to make my intro animation much smaller. I chose a 400-by-400 pixel space for the animation, which fits my page and should look respectable on any modern device. I don’t promise that any example I develop during these experiments will run well (or even at all) on every device, in every browser, and on every OS, but it should work and look reasonable on anything current. I’m also assuming a 60 frames-per-second refresh rate. I’ll explain why tomorrow.

The other thing I noticed is that the verbiage on the company’s site spoke of creating tweens for each animation step. This suggested that the product wasn’t figuring out what to do during every animation step, but was probably pre-calculating the actions up front. I ended up rewriting something that was much, much more succinct in terms of code and ran a heck of a lot more smoothly.

It takes a certain amount of information to describe the actions to be taken, and the incredibly terse JavaScript that does so in the linked video seems to leave some of it out. Or, rather, it makes certain assumptions about where things begin and end. I created a function that linked to elements in the animation div (I made them all divs themselves but they could be anything and it would probably be more efficient if most of them weren’t divs) and another set of functions that calculate tweens and load them into a list of commands to be executed as the animation proceeds. It occurred to me that the JavaScript files written by the company probably do something similar, and the impossibly pithy code the users write is actually something that gets peeled apart, interpreted, and fed to a series of functions similar to what I wrote. I don’t know that to be true, I just feel like it might be.

The thing that ultimately makes the thing go, and go smoothly, is the list of commands to be processed during each animation step. Remember from a recent post that the basic animation loop works something like this:

What you want, therefore, is the pithiest possible set of commands to run in the doSomeStuff call. I use the animationStep variable as an index into the array of animation commands I set up prior to kicking off the animation loop. The array of animation commands has two dimensions, one for each animation step, and one for each command issued during that step. (I happened to reserve element zero in each secondary array for holding the number of commands to be issued but that isn’t strictly necessary.) When the animation runs for each time step all it has to do is cycle through the list of activities that has to be performed during that animation step.

So, how do you–pithily–tell the program how to manipulate some aspect of an HTML element? Wouldn’t it be nice if we had access to something simple like:

…where we could refer to a known JavaScript handle, a specific property, and a specific value? Well, using the concept of automatic code generation it’s a simple matter to generate a bit of text like the following, which represents a valid line of JavaScript code that can be stored in the second dimension of the array of animation commands.

“handle001.style.left = ‘117px’;”

I also happened to be reading through some advice on JavaScript programming, which says to NOT use the eval() command, but this seemed almost too good to be true. If we feed the generated string to the eval command we can do just about anything. There may be some overhead from using this method, but it certainly gets the job done.

It is entirely possible that the good people at Greensock came up with a better way to do this, and I’m sure that there are, in fact, many ways to accomplish this sort of thing. This method does have the virtue of being compact and straightforward, and, most importantly, it more or less works.

I’ll go into more detail in subsequent posts but here is a very simple example of the process in action.

The red line slides in from the left over one second starting from time zero. The blue line drops down from the bottom over two seconds starting from the 0.5-second mark. All parameters are settable.

As I look at this I see that the process keeps hitching and hiccuping, so it’s very likely that I’m missing something. It’s possible that the eval() function is not the best way to do things, and it’s also possible that the problem lies elsewhere. The elements I’m moving are divs, which require more overhead to move than just raw HTML elements, and I’m also updating every element during every animation step (60 fps on modern devices). It’s possible that I can skip animation steps and still get decent effects.

Posted in Tools and methods | Tagged , , | Leave a comment