Wednesday, January 16, 2013

new_group 2500 300 45 "x" make_effect trans

Every once in a while I write some code that is so cool it makes me ecstatic.
new_group 2500 300 45 "x" make_effect trans
I'm working on a single-page HTML document that implements a kind of theatrical stage using SVG and D3.js with my Xerblin user interface metaphor.

Last night I got it to a stable point where my task shifted from creating the internal structure to "sculpting" a set of commands that will make it easy to create animations.

I started with a simple command word new_group that creates a new SVG "group" element (this is a kind of invisible container, like a HTML div element) inside a D3 selection and puts it on the stack.  In order to see it I made it also automatically create a green rectangle in the group.

The idea is that you create a new group and add visible SVG elements to it to create "characters" or "props" for animation.

I'll write some words to do that later, but for now I have created a command word set_attr that takes three things from the stack: a D3 selection, an attribute name, and a value, and it sets the attribute on the selection.

This lets you directly and immediately modify all the SVG attributes of an element (or set of elements) including position and transforms!

I also created a make_effect command word that takes just an attribute name and value from the stack and returns a function that can be used to modify attributes as part of a D3 transition.

To provide D3 transitions (awesome animations!) I made a trans command word that takes a D3 selection, a delay value, duration value, and an effect function (as created by the make_effect command word) and applies the effect to the selection with the given delay and duration.

So, breaking it down:

new_group
This creates a new group with a green rectangle in it to make it visible. It will be put on the stack.

2500 300
This puts two integers onto the stack. These will be our duration and delay values in milliseconds.

45 "x" make_effect
These three commands first put 45 and the string "x" onto the stack, and then the make_effect word turns them into an "effect function".  At this point the stack has the group/selection on it, followed by the duration and delay, then the effect function.

trans
Then the call to trans applies the effect to the group with the given duration and delay.

If you go to the demo page and put that command into the text entry and press "run" you should see a green rectangle appear and move to the left. Wow, right?  I know!

update

I forgot to include information on the command system "Xerblin" itself.

This is an old project of mine that defines a really simple but complete programmable command system.

The original project page has some basic description: https://code.google.com/p/xerblin/

I've merged the Xerblin user interface into my educational Pigeon Computer project, and the manual for that has more info:
http://phoenixbureau.github.com/PigeonComputer/user_interface.html

On the live page http://calroc.github.com/aum-gravity/xerblin-stand-alone.html you'll see:

  • "Hi There!"
  • The SVG window, about 3X wider than high.
  • Buttons for each of the command words in the dictionary.  (If you "inscribe" new words in the dictionary they automatically get a button here.)
  • A long text entry for "command line" interaction. (Don't hit enter, there's a bug that I'm about to fix that makes the page reload! D'oh!)
  • Two sets of three buttons that provide "meta" commands, interface commands that aren't in the dictionary.

I should write up the meta-controls but for now just put this in the text entry and click "run" button:

new_group 2500 300 45 "x" make_effect trans

You should see a green rectangle appear and immediately animate moving to the left.

Yay!


Just as a hint:  already with this interface and these controls you can create as many of these "groups" (visually represented by the green rectangle outlines) and animate them (including scale and rotation!!) and attach the animations to new buttons/words in the dictionary.

Not bad, eh?

No comments: