Modern JavaScript HTML5 Engine Flow in Details
Animatron Player API
Anton shaman.sir KotenkoAnimatron, June 2013
Place to go
http://animatron.com/player
Docs
Sandbox
Games
Files
player.js
builder.js
*.module.js
*.import.js
internals
API
Extending API
Import scenes
Files
player.js
builder.js
*.module.js
*.import.js
var pl = createPlayer('...'); var scene = new anm.Scene(); var oval = new anm.Element('oval', null, function(ctx) { ... }); scene.add(oval); player.load(scene).play();
createPlayer('...').load( b('oval').oval(...) ).play();
b(this.$).collides(...)
createPlayer('...').load(project, new AnimatronImporter());
Flow
Scene consists of Elements
A B
...actually, internally structured
ABX
A Aw
Everything is an Element
Ashape path text image
Everything is an Element
Ashape path text even sprite
Everything is an Element
Ashape path text sprite
b('my-star').star(5)
b('fish').path('...');
b('a-letter').text('A');b('alien').sprite('...');
Elements may have children
ABXiA Aw
Elements may have children
ABXiA Aw
b('parent').sprite(...).add(b('child').star(5))
...even while not being something for themselves
BXiA Aw
b('parent').add(b('child').star(5))
Which way a single element is rendered?
It stores transformations (state)
It stores transformations (state)
...and a brush (visuals)
A
It stores transformations (state)
...and a brush (visuals)
state visuals
state visuals
f(t) →f(t) →f(t) →
← f(ctx)← f(ctx)← f(ctx)
PaintModify
state visuals
f(t) →f(t) →f(t) →
← f(ctx)← f(ctx)← f(ctx)
PaintersModifiers
state visuals
f(t) →f(t) →f(t) →
← f(ctx)← f(ctx)← f(ctx)
PaintersModifiers
Time
band
state visuals
f(t) →f(t) →f(t) →
← f(ctx)← f(ctx)← f(ctx)
PaintersModifiers
Time
band
state visuals
tweens →events →
f(t) →
← f(ctx)← morphs
← f(ctx, t)
PaintersModifiers
Time
band
state visuals
tweens →events →
f(t) →
← f(ctx)← morphs
← f(ctx, t)
PaintersModifiers
Time
bandBrowser
time between calls is unpredictable,
though has delta
δ
δ
δ
δ
δ
Animatron Player
Animatron Player
createPlayer('canvas-id').load(my_scene).play();
Animatron Player
createPlayer('canvas-id').load(my_scene).play(3);
33
createPlayer('canvas-id', { 'mode': C.M_VIDEO,
// C.M_PREVIEW (no controls) or C.M_DYNAMIC (for games)
'zoom': 1.0,
'repeat': false,
'bgcolor': '#ffffff',
'anim': { 'width': 400, 'height': 250,
'bgfill': { color: '#fff' }, 'duration': 10 } }
).load(my_scene);
Options
⚙10
Import and Export
createPlayer('canvas-id').load(my_scene, new AnimatronImporter());
new AnimatronExporter().create(source_scene) (NYI)
Embedding
• w and h — forced width and forced height of the player. Will add black ribbons if scene ratio will be different.
• bg — the background color of the player in format of ff00a6; Default is transparent. Appears below the scene background.
• m — mode of the player, PREVIEW (no controls, no handling mouse/kb) is 0, DYNAMIC (no controls, handling mouse/kb) is 4, VIDEO (controls are shown, no mouse/kb handling, default) is 11.
• r — repeating mode, 1 is to repeat (loop), 0 (default) — play once.
• z is zoom of the scene, may be a float value
• t is time to start play from when scene is loaded. t=370 means "play from 3s 700ms"
• p is time to pause at when scene is loaded. p=370 means "pause at 3s 700ms"
• debug flag (0 or 1, off by default) allows to turn on debug information such as FPS and exact time.
Any of the parameters is optional, here is a definition for each one
http://player.animatron.com/go/3f68b131-8a6a-4e0f-82f8-99a2576ab9d9?w=600&h=500&bg=f0fff0&m=0&r=0&z=1&t=25&p=37&debug=0
<iframe/>
⚙
Supports
• Еmbedding
• Static modification
• Structures of any deep
• Masks
• Tweens and Easings
• Jumping in time
• Sprites
• Time bands
• Repeat modes
• Events
• Live changes
• Simple collisions
• Band-restricted modifiers
• Relative modifiers
</>
α
5
0.3:1
9:17
!
x,y
Overview
Construction
• b() — unnamed empty element
• b('name') — empty element with a name
• b(this.$) — from low-level element
• b(b()) — find in cache & return
• b().add(b()) — add child (even live)
• b().remove(child) — remove child (even live)
'name'
A
Shapes
• b().rect([30, 30], [53, 53]).fill('#00f') — square | rectangle
• b().oval([30, 30], [53, 53]).fill('#00f') — circle | oval
• b().path([30, 30], 'M0 0...').stroke('#000').nofill() — path
• b().image([30, 30], '/....jpg') — image
• b().text([30, 30], 'A', 53).stroke('#000').nofill() — text
• b().sprite([30, 30], '/....png', [53, 53]) — sprite
A
Shapes
• b().rect([30, 30], 53).fill('#00f') — square | rectangle
• b().oval([30, 30], 53).fill('#00f') — circle | oval
• b().path([30, 30], B.path([...])).stroke('#000').nofill() — path
• b().image([30, 30], '/....svg') — image
• b().text([30, 30], 'A', 53).stroke('#000').nofill() — text
• b().sprite([30, 30], '/....png', 53) — sprite
Base state change (NYI)
• b()...pos([30, 30]) — move
• b()...angle(Math.PI / 3) — rotate
• b()...size([2, 7], [2, 1.5]) — scale
• b()...opacity(0.8) — change opacity
Bands & Repeat Modes
• b().band([2, 10]) — lives from 0s to 10s of parent time
• b().band([2, 10]).once() — the same
• b().band([2, 10]).stay() — keep last state inst. of disappearing
• b().band([2, 10]).loop() — loop during life of a parent
• b().band([2, 10]).bounce() — bounce during life of a parent
Tweens
• b()...trans([2, 7], [[5, 5], [10, 10]) — translate
• b()...transP([2, 7], [...pts...]) — translate by path
• b()...rotate([2, 7], [0, Math.PI * 2]) — rotate
• b()...rotateP([2, 7], [...pts...]) — rotate to path
• b()...scale([2, 7], [[2, 2], [0.5, 0.3]) — scale
• b()...xscale([2, 7], [2, .5]) — equally scale
• b()...alpha([2, 7], [0, 0.8]) — alpha
Tweens
• b()...trans([2, 7], [[5, 5], [10, 10]) — translate
• b()...transP([2, 7], [...pts...]) — translate by path
• b()...rotate([2, 7], [0, Math.PI * 2]) — rotate
• b()...rotateP([2, 7], [...pts...]) — rotate to path
• b()...scale([2, 7], [[2, 2], [0.5, 0.3]) — scale
• b()...xscale([2, 7], [2, .5]) — equally scale
• b()...alpha([2, 7], [0, 0.6]) — alpha
Relative Tweens
• b()...rtrans([0.18, 0.6], [[5, 5], [10, 10]) — translate
• b()...rtransP([0.18, 0.6], [...pts...]) — translate by path
• b()...rrotate([0.18, 0.6], [0, Math.PI * 2]) — rotate
• b()...rrotateP([0.18, 0.6], [...pts...]) — rotate to path
• b()...rscale([0.18, 0.6], [[2, 2], [0.5, 0.3]) — scale
• b()...rxscale([0.18, 0.6], [2, .5]) — equally scale
• b()...ralpha([0.18, 0.6], [0, 0.6]) — alpha
Composing Tweens
b()...xscale([2, 7], [.5, 2.2]).rotate([2, 7], [0, Math.PI / 2]).alpha([2, 7], [0, 1])
Composing Tweens
b()...xscale([2, 7], [.5, 2.2]).rotate([2, 7], [0, Math.PI / 2]).alpha([2, 7], [0, 1])
Composite Tweens (NYI)
b()...rotate([2, 3, 5, 7], [0, 1/2 * Math.PI, Math.PI, 2 * Math.PI])
0
π / 2
π
2π
0 2 5 73
Relative Composite Tweens (NYI)
b()...rrotate([0.3, 0.5, 0.6, 1], [0, 1/2 * Math.PI, Math.PI, 2 * Math.PI])
0
π / 2
π
2π
0 0.3 0.6 10.5
Easings
• b()...trans([2, 2], [[5, 5], [10, 10]], C.E_IN) — predefined IN
• b()...trans([2, 2], [[5, 5], [10, 10]], C.E_OUT) — predefined OUT
• b()...trans([2, 2], [[5, 5], [10, 10]], C.E_INOUT) — predefined INOUT
• b()...trans([2, 2], [[5, 5], [10, 10]], C.E_CIN) — predefined CIN
• b()...trans([2, 2], [[5, 5], [10, 10]], C.E_COUT) — predefined COUT
• ...
• b()...trans([2, 2], [[5, 5], [10, 10]], [...pts...]) — path-based easing
• b()...trans([2, 2], [[5, 5], [10, 10]], function(t) { return 1 - t; }) — custom
Modifiers & Painters
• b().modify(function(t) { this.x = y / t; }) — normal modifier
• b().modify([6, 7], function(t) { this.x = y / t; }) — band-restricted modifier
• b().rmodify([0.25, 0.9], function(t) { this.x = y / t; }) — relative band-restricted modifier
• b().modify(5, function(t) { this.x = y / t; }) — trigger-modifier (NYI)
• b().rmodify(0.3, function(t) { this.x = y / t; }) — relative trigger-modifier (NYI)
• b().modify(function(t) { this.x = y / t; }, C.E_IN) — modifier with easing
• b().paint(function(ctx, t) { ctx.fillText(0, 0, t); }) — painter10 f(t)
Events
• b().on(C.M_CLICK, function(evt, t) { this.x = evt.x; })
• b().on_click(function(evt, t) { this.x = evt.x; })
• ...double-click, mouseover, mouseout, mousemove, mouseup, mousedown, keydown, keypress, keyup, draw
• NYI: touchstart, touchend, touchmove...
on()A
Timing
• b().on(C.M_CLICK, function(evt, t) { this.t = 5; }) — jump to time
• b().on(C.M_CLICK, function(evt, t) { this.rt = 0.3; }) — jump to relative time
• b().key(5, 'jump').on(C.M_CLICK, function(evt, t) { this.key = 'jump'; }) — jump by key
• b().rkey(0.2, 'jump').on(C.M_CLICK, function(evt, t) { this.key = 'jump'; }) — (NIY) relative
• b().time(C.E_QIN) — predefined time easing
• b().time(function(t) { return t / 2; }) — time easing
• b().rtime(function(t) { return 1 - t; }) — relative time easing (NYI)
t
5
.3
jump
.jump
Sprites
• b().sprite([30, 30], 'my_sprite.png', [40, 40], ...) — create sprite and define frames / frames names
• b().switch(['jump', 'walk'], 10) — switch to given frames and FPS, waiting for run() call
• b().run(7) — animate stored frames starting from given time
• b().animate(7, ['jump', 'walk'], 10) — animate frames starting from given time with given FPS
Composition & Masks
• b().acomp(C.C_SRC_OVER) — Source over
• b().acomp(C.C_SRC_IN) — Source in
• b().acomp(C.C_DST_ATOP) — Destination atop
• b().acomp(C.C_LIGHTER) — Lighter
• ...
• b().mask(b()) — Use element as a mask SRC_IN
Other• b().enable() — enable
• b().disable() — disable element
• b().show() — (NYI) show element
• b().hide() — (NYI) hide element
• b().each(function(elm) { ... }) — iterate over direct children
• b().deach() — iterate deeply over sub*-children
• b().take(b()) — copy another element
• b().use(b()) — clone another element
• B.grad(...), B.path(...), B.sheet(...), B.easing(...) ... — helpers for you to make things
Everything with the help of modifiers and painters
May be head to the docs now?)
...or Sandbox?
Version 1.0 is coming soon
Thank you!
Top Related