Permalink
Browse files

Fix being able to set parents in states

  • Loading branch information...
koenbok committed May 3, 2016
1 parent 908bfd0 commit 94e779d0175cd391605e2291e00494f4b65799d1
Showing with 70 additions and 29 deletions.
  1. +50 −29 framer/LayerStates.coffee
  2. +20 −0 test/tests/LayerStatesTest.coffee
@@ -57,12 +57,6 @@ class exports.LayerStates extends BaseClass
# Switches to a specific state. If animationOptions are
# given use those, otherwise the default options.
# We actually do want to allow this. A state can be set to something
# that does not equal the property values for that state.
# if stateName is @_currentState
# return
if not @_states.hasOwnProperty(stateName)
throw Error "No such state: '#{stateName}'"
@@ -84,7 +78,9 @@ class exports.LayerStates extends BaseClass
continue
# Allow dynamic properties as functions
value = value.call(@layer, @layer, propertyName, stateName) if _.isFunction(value)
if _.isFunction(value)
value = value.call(@layer, @layer, propertyName, stateName)
# Set the new value
properties[propertyName] = value
@@ -93,40 +89,45 @@ class exports.LayerStates extends BaseClass
animatablePropertyKeys = []
for k, v of properties
# We can animate numbers
if _.isNumber(v)
animatablePropertyKeys.push(k)
# We can animate colors
else if Color.isColorObject(v)
animatablePropertyKeys.push(k)
else if v == null
animatablePropertyKeys.push(k)
# If we don't have any animatable properties, we always switch instant
if animatablePropertyKeys.length == 0
instant = true
if instant is true
# We want to switch immediately without animation
if instant
@layer.props = properties
@emit Events.StateDidSwitch, _.last(@_previousStates), @_currentState, @
@emit(Events.StateDidSwitch, _.last(@_previousStates), @_currentState, @)
return
# If there are, we start the animation here
animationOptions ?= @animationOptions
animationOptions.properties = properties
else
# Start the animation and update the state when finished
animationOptions ?= @animationOptions
animationOptions.properties = properties
@_animation?.stop()
@_animation = @layer.animate(animationOptions)
@_animation?.stop()
@_animation = @layer.animate animationOptions
@_animation.once "stop", =>
# Once the animation is done, we set all the keys that we could not animate
@_animation.once "stop", =>
# Set all the values for keys that we couldn't animate
for k, v of properties
@layer[k] = v unless _.isNumber(v) or Color.isColorObject(v)
for k, v of properties
@layer[k] = v if v not in animatablePropertyKeys
@emit(Events.StateDidSwitch, _.last(@_previousStates), @_currentState, @) unless _.last(@_previousStates) is stateName
# If we changed the state, we send the event that we did
if _.last(@_previousStates) isnt stateName
@emit(Events.StateDidSwitch, _.last(@_previousStates), @_currentState, @)
switchInstant: (stateName) ->
@switch stateName, null, true
@switch(stateName, null, true)
@define "state", get: -> @_currentState
@define "current", get: -> @_currentState
@@ -138,7 +139,7 @@ class exports.LayerStates extends BaseClass
animatingKeys: ->
# Get a list of all the propeties controlled by states
# Get a list of all the properties controlled by states
keys = []
@@ -177,11 +178,31 @@ class exports.LayerStates extends BaseClass
# TODO: Maybe we want to support advanced data structures like objects in the future too.
for k, v of properties
# We check if the property name ends with color, because we don't want
# to convert every string that looks like a Color, like the html property containing "add"
if _.isString(v) and _.endsWith(k.toLowerCase(),"color") and Color.isColorString(v)
if @_isValidColor(k, v)
stateProperties[k] = new Color(v)
else if _.isNumber(v) or _.isFunction(v) or _.isBoolean(v) or _.isString(v) or Color.isColorObject(v) or v == null
continue
if @_isValidProperty(k, v)
stateProperties[k] = v
return stateProperties
@_isValidColor: (k, v) ->
# We check if the property name ends with color, because we don't want
# to convert every string that looks like a Color, like the html property containing "add"
if _.endsWith(k.toLowerCase(), "color") and _.isString(v) and Color.isColorString(v)
return true
return false
@_isValidProperty: (k, v) ->
return true if _.isNumber(v)
return true if _.isFunction(v)
return true if _.isBoolean(v)
return true if _.isString(v)
return true if Color.isColorObject(v)
return true if v is null
return true if v?.constructor?.name is "Layer"
return false
@@ -1,3 +1,5 @@
assert = require "assert"
describe "LayerStates", ->
describe "Events", ->
@@ -179,3 +181,21 @@ describe "LayerStates", ->
layer.states.switchInstant "default"
layer.x.should.equal 0
it "should set the parent", ->
layerA = new Layer
layerB = new Layer
parent: layerA
layerB.states.add
stateA:
parent: null
assert.equal(layerB.parent, layerA)
layerB.states.switchInstant "stateA"
assert.equal(layerB.parent, null)
layerB.states.switchInstant "default"
# assert.equal(layerB.parent, layerA)

0 comments on commit 94e779d

Please sign in to comment.