2/3/12
- Refactored
Character.makeAction()
to do the function application itself rather than return a function that does the work. This allowsCharacter.show()
,Character.hide()
andCharacter.start()
to get rid of themaker
variable and its intermediate call tomakeAction()
.
2/2/12
- Fixed the gradient display. Turned all the gradient objects in times_polevault.js to an array of instructions. They need to be in an array because they need to be read in a specific order. All in one pass, the gradient object is created, color stops are added, and the fill style is set to the gradient.
1/31/12
- Created a local version of all the Times styles and saved them to times_styles.css Removed all the other stylesheet calls and plugged in this one.
1/30/12
- Removed all
Character.show()
calls from times_polevault.js. Characters are visible by default, making this call unnecessary.
1/29/12
-
Removed an obsolete
if
clause fromCharacter.advance()
. -
Wrapped
Character.advance()
's instructions in anif
test to allow Characters with laterstarting_frame
values to begin further along in the animation. To allow this, we're now passingCharacter.advance()
an argument: the current frame. Updated all calls accordingly. Everything works. -
In times_polevault.js, adjusted
pitshadow
's starting frame to 86 to sync with the vaulter's fall. -
Changed the
Action
constructor and the way Actions are instantiated and called. They now define a named function; this name is also the name of the Action instance. The constructor no longer expects afunc_name
argument. -
Character.visible
istrue
by default. -
Expanded
Action.onFrame
to test for the name of the function and branch accordingly. -
Added
Character.start()
, an Action.
1/28/12
-
Character.hide()
is now a working Action. -
show()
andhide()
are called before the Character constructor returns, initalizing them. The first time the developer would need to call them, they'll behave as expected.
1/27/12
-
Added
Character.makeAction()
, a wrapper that simulates a constructor's assignment ofthis
. A constructor can't return a function, so this allows me to callvaulter.show()
as well asvaulter.show.onFrame(22)
. -
EventDispatcher.init()
now stores trigger objects for each frame. -
Fixed a bug by defining
triggers
within the Button and Slider constructors. -
Animator.animate()
now fires Actions based on the frame. -
Got rid of
Action.prototype.
We can't take advantage of it, soonFrame()
becomes an instance method. In the grand scheme, this doesn't seem that costly.
1/26/12
- Added a
triggers
property toEventDispatcher
: an empty object. (For now.)
1/21/12
- Firing
vaulter.show.onFrame(7)
works. For now, this is done by includingvaulter
's visibility function in theTimeline.frames[current_frame]
array. I'm thinking it should be moved elsewhere, though, like intoAnimator.animate()
.
1/20/12
-
Added unit tests for
Action
. -
Added
Character.triggers
andCharacter.checkTrigger()
. -
Added unit tests for
Character.triggers
andCharacter.checkTrigger()
. -
Testing for triggers inside
Character.makeFrameInstructions()
.
1/18/12
- Added an
Action
object so Characters can have chainableonFrame()
methods for their "doer" functions. MadeCharacter.show()
andCharacter.hide()
Action
instances.
1/17/12
-
Fixed the redraw problem by incrementing
Timeline.current_frame
before the frame is drawn, then exiting on the final frame by testing for(Timeline.frame_total - 2)
. -
Removed the extraneous conditions for
Slider.drawBoundary()
.
1/16/12
-
Added
Character.init()
andCharacter.initHandlers()
. -
Restored the old
EventDispatcher.makeDispatchers()
. It became clear the new aggregated handler instructions complicate things unnecessarily. Trying a new branch out of this old base. -
Moved
isPointInPath()
test from the dispatcher function to the individual handlers. We need to define behavior for when the mouse is on either side of the boundary, and this can't be done from within the dispatcher. -
Added
Character.initBoundary()
. -
Slider and buttons are mostly fixed, though there's a problem with setting the frame after the slider is dragged.
-
Changed all references to
EventDispatcher.mouse_x
toEventDispatcher.mx
. -
Merged
compare()
from the unusedEventDispatcher.getUserEvents()
methodintoEventDispatcher.init().
compare()
's recursive looping allows us to properly store the handler functions. And now I barely have to change the wiki. Bonus. -
Got rid of
EventDispatcher.getUserEvents()
now that its most important pieces are insideEventDispatcher.init()
. Ditto related unnecessary code.
1/14/12
-
Added the
isNotEmpty()
helper insideEventDispatcher.getUserEvents()
. -
Added the
setKey()
helper insideEventDispatcher.getUserEvents()
. -
Removed the old
EventDispatcher.makeDispatchers()
function and other obsolete code. Listeners seem attached, and there are no compile-time errors. But I can only get an event forSlider
, the first loaded item with handlers. -
Renamed
getUserEvents()
tomakeDispatchers()
, which is now what it does.
1/11/12
-
Removed the
false
argument from theButton
instantiations. We don't need it. Buttons are always touchable. -
Added unit tests for the
Button
andEventDispatcher
objects.
1/10/12
- Added
EventDispatcher.getUserEvents()
to collect all the user event strings it will need to attach listeners to the Canvas.
1/5/12
- Added a tests directory that includes unit tests in Jasmine. Playing catch-up on testing the code I've already written. But from now on, anything that doesn't pass won't get committed.
1/4/12
- Moved the
isPointInPath()
tests out ofEventDispatcher.makeDispatchers()
and into the handlers. Testing this now.
1/2/12
- Renamed
Button.mouseoverHandler()
toButton.mousemoveHandler()
. It's challenging to set a mouseover event handler on the Canvas, so I'm simulating a mouseover event by testing for mousemove within the button boundaries. Still working this out.
1/1/12
-
Fixed the scrubber boundary bug.
-
Updated
Timeline.frameBack()
andTimeline.frameForward()
to cycle through to the other end of the timeline once they've reached its opposite. -
Noted out the assignment of current_frame to 0 inside
Timeline.play()
. I'm toying with the idea of the play button not resetting the animation from the beginning, but simply picking up from the current frame, wherever that happens to be. -
Got rid of
Animator.getAllCels()
,Animator.resetAllCels()
, andAnimator.advanceAll()
. They're unused in the new system. -
Updated the
Button
constructor to defineenabled
,disabled
,over
,out
andclick
states.enabled
is -- forgive the pun -- enabled and populated by default.
12/31/11
In terms of functionality, I'm all caught up with last week when I decided to change the playthrough system. It was a challenge, but so far, it's made many of the Animator
, Timeline
and EventDispatcher
methods much less complicated and the animation machinery seems more streamlined and sensible.
There are a lot of closures here, so I'll be keeping a close eye on memory and testing for leaks. But all the important math is done before runtime, which gives the browser an easier task of rapid-fire drawing.
-
Adapted
Button.drawBoundary()
to the new playthrough system and made it self-defining. After initialization, it works with the event system right out of the box. -
Updated
Slider.drawBoundary()
to the new playthrough system. This required a new storage step inSlider.makeFrameInstructions()
that pushes the scrubber boundary instructions toScrubber.boundary.cels
on every frame. The movement of the scrubber boundary is now in sync with the movement of the scrubber itself. -
Updated
Slider.mousemoveHandler()
to the new playthrough system. It works! The whole reason I wanted to make a new playthrough system -- the engine that powers these animations -- was to enable this very important feature. Yes. -
Scrapped
Timeline.controls
. The slowdown of having the browser loop through and draw from two arrays concurrently was unacceptable. -
Also got rid of all the drawing methods inside
Character
. We don't need them in this new system. -
Lost an unnecessary
else if
test fromSlider.drawBoundary()
. -
Removed the assignments to
Slider
properties insideSlider.scale()
and the scrubber mouse event handlers. Don't need 'em. -
Added a
last_action
property toEventDispatcher
that will hold a string:scrubber
,play
,step
,ff
orrw
. -
Got rid of
Timeline.jumpToFrame()
. -
Activated
Timeline.frameForward()
andTimeline.frameBack()
. These are called from the click event dispatchers on the forward and back buttons.
12/30/11
-
Modified
Animator.animate()
to define itself, settingthis
to theAnimator
constructor the first time it's called. The result: It retains its scope during repeated calls bywindow.setTimeout()
. This makesAnimator.makeAnimate()
unnecessary -- it's gone. -
Gave the
Slider
prototype a modified version ofmakeFrameInstructions()
that always draws the track before drawing the scrubber on every frame. It defines atrack_operation
property and sets it totrue
right before drawing the track, andfalse
right before drawing the scrubber. -
Modified
Character.plotX()
andCharacter.plotY()
to test whethertrack_operation
is true. If it is, the distance is excluded from the calculation so the track stays put while the scrubber moves.
12/28/11
-
Removed the
Character.span
test fromTimeline.store()
. Cels seem to be spread evenly across frames and early animation tests in this new system look good in Chrome, Firefox, Safari and Opera on OSX. -
Started the animator from within
Timeline.init()
just for testing. I'll remove it once the EventDispatcher is working. -
Renamed
Animator.drawFrame()
toAnimator.draw()
. This name change accompanies an abstraction to work with any collection of drawing instructions, not just those in the timeline... Drawing boundaries on demand for mouse event detection, for instance. -
Modified
Character.parseDrawingObject()
to return an array of drawing instructions if an existing array isn't passed as the function's second argument. -
Added a test to
Timeline.setFinalBreakpoint()
to fire only if the final frame is not already the final breakpoint.
12/27/11
- Added a
controls
array to theTimeline
object.
12/26/11
The overhaul of the playthrough system continues. I read somewhere that it's bad to check in code that breaks the build, so I'm refraining from the atomic commits until everything works without errors.
-
Got rid of
Animator.renderCharacter().
In this system,Animator.drawFrame()
is all that's necessary. -
Got rid of
Timeline.setInFrames()
. -
Converted members of the
Character.sequence.cels
array from functions to arrays of objects. The key is the Canvas drawing instruction and the value is the argument. An example follows. -
Made
Character.parseDrawingObject()
, which converts the object in theCharacter.sequence.cels
array into a function that performs one drawing instruction when fired.
So, given the two updates immediately above:
celhelper.sh turns the Canvas drawing instruction into a JavaScript object ...
{ lineTo : [ 487.8, 45.2 ] }
... then, before runtime, math is done on the coordinates array in this object and it's made into a function by Character.parseDrawingObject()
...
function () {
context["lineTo"](497.8, 45.2);
}
... before it's pushed to the Timeline.frames
array for the current frame. When the user hits the "play" button, the functions in this array are fired off in sequence, drawing the entire image on the canvas for a split second. Then it happens again for the next frame, and so on...
12/23/11
-
Revamping the timeline playthrough system. Instead of doing all the calculations right before each frame is drawn, I can calculate and save the drawing instructions for every frame before anything gets drawn to the screen.
Timeline.store()
is the first step in this effort. -
Changed
back
andforward
from instances ofCharacter
to instances ofButton
. Gave them boundaries and click handlers that fireTimeline.play()
.
12/21/11
-
Added
xorigin
andyorigin
members to each sequence in theCharacter
prototype. These are added to aCharacter
's original coordinates on every draw to offset its position on the Canvas. They also freexdistance
andydistance
to be cumulative, and to be reset to zero without affecting theCharacter
's current position. -
Updated
Character.advance()
to addxorigin
andyorigin
toxpos
andypos
. -
Removed unnecessary JavaScript calls from times_polevault.html.
-
Added
setOrigins()
,setOriginX()
andsetOriginY()
methods toCharacter
. -
Created
EventDispatcher
, a constructor for an object that manages events. AnEventDispatcher
instance is now expected as the second argument to theTimeline
constructor. -
Moved
makeDispatchers()
fromTimeline
toEventDispatcher
and call it onEventDispatcher.init()
. -
Timeline.load()
puts references to theEventDispatcher
instance into every loadedCharacter
. -
Added
min_edge
andmax_edge
properties to theSlider
prototype. The constructor now expects them as the second and third arguments. -
Got rid of
Animator
's running property and changed itsthis.running
condition to test forthis.event_dispatch.timeline_live
instead. -
Got rid of
Timeline.injectBreakpoint()
andTimeline.extractBreakpoint()
. More or less replaced them withTimeline.stop()
andTimeline.ready()
, which are much simpler. -
The scrubber is draggable. Oh, fraptious day! In that effort,
Slider
gotselectScrubber()
andreleaseScrubber()
methods.
12/20/11
-
Got rid of the
cache
property andstore()
,emptyCache()
andemptyAllCaches()
methods forCharacter
. They're not being used, and we can calculate positions on the Canvas withx
- andydistance
. -
Added MIT license language.
-
A
Character
'sxdistance
carries over from one sequence to another. This allows aCharacter
to move evenly across the screen while cycling through all its sequences. -
Updated
Timeline.init()
to remember which dispatch handlers are listening for events. -
Gave the
Slider
object aselected
property that turns true on mousedown and false on mouseup. -
Added
Timeline.injectBreakpoint()
andTimeline.extractBreakpoint()
to pause and resume the animation. Made these mousedown and mouseup event handlers forSlider
.
12/19/11
-
Character
s now have auserEvents
property -- an array of events they need to listen for -- and an event handler method named accordingly. So aCharacter
that responds to a mouse click needs to define a method namedclickHandler
. -
Timeline.init()
now automatically adds event listeners forCharacters
that need them.
12/18/11
-
First set of changes in this new repo, the library's new home. A
Copy
object collects all the behavior and details for any text that needs to respond to events. -
Made a
Button
object withCharacter
as its prototype. Sequences includeoff
,on
,hover
andclick
. -
Moved the
dispatch
methods into theTimeline
object.Timeline.init()
identifies touchable Characters -- the goal is to attach event listeners accordingly. -
Moved the constructors into their own "core" file: chuck.js.
-
Working in a new example file named times_polevault.html. You can see it in progress here.
12/16/11
-
Made an
Animator
object that collects all the machinery for drawing images to the screen. You can pass its constructor an optional number representing frames per second in milliseconds; the default is 75. TheTimeline
constructor now expects anAnimator
instance as its first argument. -
Moved
playthrough_count
intoTimeline
. -
Adapted
Timeline.storeInFrames()
to store thexdistance
andydistance
of every cel. -
Rounded all
xdistance
andydistance
calculations to two decimal places.
12/15/11
-
Added
xlimit
andylimit
members to thescrubber
sequence inSlider
. These represent the far extremes of the slider, the scrubber's position after it's traveled 100 percent of the track distance. -
Created
Slider.drawBoundary()
, which helps click detection for the scrubber by drawing a path before runningisPointInPath()
. This was tricky, because it needs to follow the scrubber as it moves, andSlider
calls two different sequences on each draw.
12/14/11
-
Finished making the
Slider
object and combined the previousslider
andscrubber
into a new instance of it.Slider
inherits fromCharacter
-- it borrows its prototype. -
Adapted
renderCharacter()
to sniff outSlider
instances and make sure the track is drawn before the scrubber on each frame.
12/13/11
-
Fixed
Timeline.init()
. The timeline remembers the current cel, current sequence and current iteration for everyCharacter
instance on every frame in the animation. -
Moved
current_frame
,current_bp
andbreakpoints
insideTimeline
. Scrapped these andfps
fromstage
's scope. Everything works.
12/12/11
-
Added a constructor and prototype for a
Timeline
object.Timeline
stores history and methods for every frame in the animation.frame_total
,current_frame
, thebreakpoints
array,current_breakpoint
andfps
are moving into this object. -
Timeline.init()
is now working, though I was wrong about how theframes
array should store members. I'm revising this function. -
Added
Character.countSpan()
to store the total number of cels aCharacter
puts on the timeline. Having this number handy makes it easier to do some of the mathTimeline.init()
needs. -
Switched
pit
andpitforeground
to theCharacter
drawing methods.
12/11/11
-
Painstakingly removed all references to
Character.sequence
. I initially thought it would be a true collection, but it never got used that way. Leaving it seems like it costs an unnecessary lookup. So far, no ill effects. -
Updated
Character.reset()
to cycle through all sequences within aCharacter
and setcurrent_seq
to zero when it's finished. -
Updated
Character.setSequenceOrder()
to automatically resetstarting_frame
for any sequence following the first one. This letssetFrameTotal
keep an accurate count and saves the developer from having to set this value explicitly. -
Found out the hard way that
Character.setSequenceOrder()
can't set thestarting_frame
s accurately if it's called on a sequence that hasn't yet been populated with cels. It fails silently. So I added an error message to catch this. -
For testing, made
vaulter
's run-up sequence loop for 4 iterations. It, and the functions above, seem to work. -
Removed comments and the unused call to pv_cels.js from polevault.html.
12/10/11
-
Added a
sequenceOrder
property and asetSequenceOrder()
method to theCharacter
prototype. These store and alter the calling order of drawing instructions for aCharacter
's sequences. -
Modified
setFrameTotal()
to work with these new values. -
Added a
runup
sequence tovaulter
: a loopable series of strides to show the vaulter approaching the pit. -
Moved
sequenceOrder
out of theCharacter
prototype and into its constructor, fixing the mistake I just introduced. -
sequenceOrder
is now calledsequence_order
to stick with the naming convention for variables. -
Updated
Character.advance()
to cycle through sequences. -
Fixed a bad assignment in
Character.advance()
that incrementedcurrent_seq
too early.
12/9/11
- Added the pit, the shadow and the updated vaulter to the stage.
12/5/11
-
The scrubber now moves in time with the action, thanks to the new drawing methods.
Character.cache
is almost obsolete. The methods do all the calculations before rendering. -
Fixed the problems with the Play and Step Through button boundaries. The Play path never closed before the Step Through path was drawn.
-
Moved the
record
methods into theCharacter
prototype. This means the functions can accept fewer arguments to know to which objects they're applied -- almost all of them are back to the arguments they'd expect as regularCRC
methods. This also means I removed the "record" part of the name. They live in the namespace of their parent and that's how you call them:vaulter.lineTo(100.0, 200.0);
. -
Started making a
Scrubber
object that inherits fromCharacter
. -
Added
xdistance
,ydistance
,xinc
andyinc
members to each sequence inCharacter
. These are meant to remember x and y increments and total distances from the axes as aCharacter
moves across the stage.
12/3/11
-
Moved
emptyAllCaches()
to the top ofdrawFrame()
. This is a better solution than calling it fromanimate()
, ensuring it gets called once per drawing cycle -- even the first one. -
Added
store()
to theCharacter
prototype. -
Added
recordBeginPath()
,recordClosePath()
,recordFillStyle()
,recordLineWidth()
,recordLineJoin()
,recordMiterLimit()
,recordLinearGradient()
,recordAddColorStop()
,recordStroke()
,recordStrokeStyle()
,recordSave()
andrecordRestore()
. -
Renamed
advanceCels()
toadvance()
andadvanceAllCels()
toadvanceAll()
. -
Moved the scrubber to the far left of the track (by subtracting 155.8 from all the x-values).
11/30/11
-
Gave the new controls
record
methods. -
Made the new controls a little bigger for easier use on touch screens.
11/28/11
- Added new
Character
instances:slider
,scrubber
,back
andforward
. These draw controls on the stage, though they're not active yet.
11/27/11
-
Made a
Character
instance calledtrack
, drawing a track on the canvas. -
Added a condition to
play()
andstepThrough()
that prevents them from being fired before the previous animation is finished running. -
Gave
animate()
arunning
property. -
Added
emptyCache()
to theCharacter
prototype and the helperemptyAllCaches()
. These clear thecache
array of saved coordinates inside eachCharacter
's sequence. -
Gave each
Character
aqueue_index
property that stores theCharacter
's index position withina_queue
.
11/25/11
-
Combined new_polevault.js and polevault.js into one file named polevault.js. Got rid of obsolete comments. Commented out the tests.
-
vaulter
is an instance ofCharacter
. -
Commented out the triggers in polevault.html
11/22/11
- Added
recordBezierCurveTo()
.
11/21/11
-
Added a condition to
Character.advanceCels()
to resetcurrent_cel
andcurrent_iteration
to 0 when thebreakpoints
array rolls over. -
Added another call to
Character.advanceCels()
fromanimate()
11/20/11
-
Created a
setFinalBreakpoint
function to programatically set the last breakpoint to the last frame in the animation. The user (the developer) doesn't have to do this manually. -
Added a condition to
animate()
to exit whencurrent_frame
is equal to or greater thantotal_frames
.
11/12/11
-
Moved
updateCels()
into theCharacter
prototype. -
Added an
advanceCels()
method to theCharacter
prototype. -
Changed
drawFrame()
to expect an argument: an array ofCharacter
s. All these measures are designed to replace theanim_queue
object I was using before, which added an extra step to the animation looping. -
Added a
setFrameTotal()
method.
11/11/11
-
Put 5 new members in the
breakpoints
array to test it out. -
Added
advanceBreakpoint()
to incrementcurrentBreakpoint
. -
Made
play()
andstepThrough()
functions that set different breakpoints before runninganimate()
.
11/10/11
-
Renamed
ftha()
toupdateCels()
. RenamedCharACTer()
toCharacter()
. The internal capitlization was designed to help avoid namespace collisions, but really, it was annoying. I'll keep it out of the global space or wrap it or something. -
Modified the last
if
test in updateCels to comparecurrent_cel
tocels.length
. -
Added a condition to
renderCharacter()
to check whether it's been passed an function. If not, it renders the last cel in the sequence. -
CharACTer.create()
isn't necessary. I removed it. -
CharACTer
's methods have been moved into a prototype. Don't see why each instance needs its own unique copy. -
animate()
once again incrementscurrent_frame
on every draw. It's clear there needs to be a master count of which frame we're on. -
ftha
doesn't resetcurrent_cel
when aCharACTer
leavesanim_queue
. This leaves theCharACTer
at its last position on the stage while others continue to move.
11/9/11
-
CharACTer
gets acreate()
method for instantiation. -
The
sequence
object in everyCharACTer
now has astarting_frame
member. This tellsftha
the frame on which to start animating theCharActer
. -
breakpoints
is now an array, usingcurrent_bp
to identify the index of the current breakpoint.
11/8/11
-
Made the
CharACTers
constructor, for creating objects that keep their own distinct drawing rules. A CharACTer represents an autonomous object on the stage and might be thought of as a cel in traditional animation. -
Created
ftha
(function that handles advancement) which updates the drawing instructions for every CharACTer on every redraw. I'll come up with a better name. -
The
CharACTer
methodsrecordMoveTo
,recordLineTo
,recordStrokeRect
, andrecordFillRect
create paths and cache the results of the coordinates passed to them. This is designed to make it easier to do math on the coordinates between redraws. More of these recorder functions to come.