-
Notifications
You must be signed in to change notification settings - Fork 477
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Animation API refactor #420
Changes from 19 commits
f6f49f1
d1e2b23
6b32cae
80190f2
d70650e
0c02b31
db79bef
a19b1b4
674c420
1708166
f1af6bd
9601a55
6f204e8
73b5332
b59908e
4573856
01947b5
c430c6f
60f0ae8
f1d41c3
a76c862
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,7 +11,7 @@ Utils = require "./Utils" | |
{Matrix} = require "./Matrix" | ||
{Animation} = require "./Animation" | ||
{LayerStyle} = require "./LayerStyle" | ||
{LayerStateMachine} = require "./LayerStateMachine" | ||
{LayerStates} = require "./LayerStates" | ||
{LayerDraggable} = require "./LayerDraggable" | ||
{LayerPinchable} = require "./LayerPinchable" | ||
{Gestures} = require "./Gestures" | ||
|
@@ -133,7 +133,6 @@ class exports.Layer extends BaseClass | |
@[p] = options[p] | ||
|
||
@animationOptions = {} | ||
@_stateMachine = new LayerStateMachine(@) | ||
@_context.emit("layer:create", @) | ||
|
||
############################################################## | ||
|
@@ -885,30 +884,25 @@ class exports.Layer extends BaseClass | |
############################################################## | ||
## ANIMATION | ||
|
||
# Used to animate to a state with a specific name | ||
# We lookup the stateName and call 'animate' with the properties of the state | ||
animateToState: (stateName, options={}) -> | ||
return @_stateMachine.switchTo(stateName, options) | ||
|
||
animate: (properties, options={}) -> | ||
|
||
# print "layer.animate", properties, options | ||
|
||
# If the properties are a string, we assume it's a state name | ||
if _.isString(properties) | ||
return @animateToState(properties, options) | ||
# Support options as an object | ||
options = options.options if options.options? | ||
return @states.machine.switchTo(properties, options) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nicer to put properties in a new variable |
||
|
||
# Support the old properties syntax, we add all properties top level and | ||
# move the options into an options property. | ||
if properties.hasOwnProperty("properties") | ||
if properties.properties? | ||
options = properties | ||
properties = options.properties | ||
delete options.properties | ||
|
||
# With the new api we treat the properties as animatable properties, and use | ||
# the special options keyword for animation options. | ||
if properties.hasOwnProperty("options") | ||
options = _.defaults(properties.options, options) | ||
if properties.options? | ||
options = _.defaults({}, options, properties.options) | ||
delete properties.options | ||
|
||
# Merge the animation options with the default animation options for this layer | ||
|
@@ -920,13 +914,13 @@ class exports.Layer extends BaseClass | |
|
||
return animation | ||
|
||
switchInstant: (properties, options={}) -> | ||
@animate(properties, _.merge(options, {instant: true})) | ||
|
||
animateToNextState: (args..., options={}) -> | ||
stateCycle: (args..., options={}) -> | ||
states = [] | ||
states = _.flatten(args) if args.length | ||
@animate(@_stateMachine.next(states), options) | ||
@animate(@states.machine.next(states), options) | ||
|
||
stateSwitch: (stateName, options={}) -> | ||
@animate(stateName, _.defaults({}, options, {instant:true})) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to support There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Meh. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well ok. |
||
|
||
animations: -> | ||
# Current running animations on this layer | ||
|
@@ -986,17 +980,18 @@ class exports.Layer extends BaseClass | |
enumerable: false | ||
exportable: false | ||
importable: false | ||
get: -> @_stateMachine.states | ||
get: -> | ||
@_states ?= new LayerStates(@) | ||
return @_states | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I really dislike this behaviour of capturing the state inside of a getter, leads to unexpected behaviour. Can't we add it to the creation / addition of states? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, I'd like that, but:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree with 2), we could fix 1) if we ever move to initial, but am I correct that in order to drop this, we would also need to drop the backwards compatibility of |
||
set: (states) -> | ||
@_stateMachine.reset() | ||
for name, state of states | ||
@_stateMachine.states[name] = state | ||
@states.machine.reset() | ||
_.extend(@states, states) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could capture the current state of the layer here, we should however be aware of the setting of states individually... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not really, because this should work too:
|
||
|
||
@define "stateNames", | ||
enumerable: false | ||
exportable: false | ||
importable: false | ||
get: -> @_stateMachine.stateNames | ||
get: -> @states.machine.stateNames | ||
|
||
############################################################################# | ||
## Draggable, Pinchable | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,47 +1,46 @@ | ||
# {_} = require "./Underscore" | ||
# | ||
# {Events} = require "./Events" | ||
{BaseClass} = require "./BaseClass" | ||
# {Defaults} = require "./Defaults" | ||
|
||
{LayerStates} = require "./LayerStates" | ||
|
||
class exports.LayerStateMachine extends BaseClass | ||
|
||
constructor: (layer) -> | ||
constructor: (@_layer, @_states) -> | ||
super | ||
@_layer = layer | ||
@properties = {} | ||
@initial = LayerStates.filterStateProperties(layer.props) | ||
|
||
@reset() | ||
|
||
@define "layer", | ||
get: -> @_layer | ||
|
||
@define "current", | ||
get: -> @states[@currentName] | ||
get: -> @currentName | ||
|
||
@define "previous", | ||
get: -> @previousName | ||
|
||
|
||
@define "currentName", | ||
get: -> @_currentName | ||
|
||
@define "previous", | ||
get: -> @states[@previousName] | ||
|
||
@define "previousName", | ||
get: -> _.last(@_previousNames) | ||
get: -> _.last(@_previousNames) or "default" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do we need this? (I don't understand the case where _.last(@_previousNames) is null) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's better to always return something here so you don't have to do a null check (if you just created a layer and ask for |
||
|
||
@define "stateNames", | ||
get: -> _.keys(@states) | ||
get: -> Object.keys(@states) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why use Object.keys and not _.keys here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They are both equal, and I want to be sure |
||
|
||
@define "states", | ||
get: -> @_states | ||
|
||
switchInstant: (stateName) -> | ||
@switchTo(stateName, {instant: true}) | ||
|
||
switchTo: (stateName, options={}) -> | ||
|
||
# Check if the state exists, if not this is a pretty serious error | ||
throw Error "No such state: '#{stateName}'" unless @states.hasOwnProperty(stateName) | ||
throw Error "No such state: '#{stateName}'" unless @states[stateName] | ||
|
||
# Prep the properties and the options. The options come from the state, and can be overriden | ||
# with the function arguments here. | ||
properties = @states[stateName] | ||
options = _.defaults(properties.options, options) if properties.options | ||
options = _.defaults({}, options, properties.options) if properties.options | ||
|
||
stateNameA = @currentName | ||
stateNameB = stateName | ||
|
@@ -84,12 +83,21 @@ class exports.LayerStateMachine extends BaseClass | |
states = @stateNames | ||
Utils.arrayNext(states, @currentName) | ||
|
||
emit: (args...) -> | ||
super | ||
# Also emit this to the layer with self as argument | ||
@_layer.emit args... | ||
|
||
reset: -> | ||
@states = new LayerStates(@) | ||
|
||
for k in _.keys(@states) | ||
delete @states[k] unless k is "default" | ||
|
||
@_previousNames = [] | ||
@_currentName = _.first(@stateNames) | ||
@_currentName = "default" | ||
|
||
emit: (args...) -> | ||
super | ||
# Also emit this to the layer with self as argument | ||
@_layer.emit args... | ||
# _namedState: (name) -> | ||
# return _.extend(_.clone(@states[name]), {name: name}) | ||
|
||
toInspect: (constructor) -> | ||
return "<#{@constructor.name} id:#{@id} layer:#{@layer.id} current:'#{@currentName}'>" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this in this PR?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:-/