Skip to content

Commit

Permalink
Fix being able to set parents in states
Browse files Browse the repository at this point in the history
  • Loading branch information
koenbok committed May 3, 2016
1 parent 908bfd0 commit 94e779d
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 29 deletions.
79 changes: 50 additions & 29 deletions framer/LayerStates.coffee
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -57,12 +57,6 @@ class exports.LayerStates extends BaseClass
# Switches to a specific state. If animationOptions are # Switches to a specific state. If animationOptions are
# given use those, otherwise the default options. # 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) if not @_states.hasOwnProperty(stateName)
throw Error "No such state: '#{stateName}'" throw Error "No such state: '#{stateName}'"


Expand All @@ -84,7 +78,9 @@ class exports.LayerStates extends BaseClass
continue continue


# Allow dynamic properties as functions # 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 # Set the new value
properties[propertyName] = value properties[propertyName] = value


Expand All @@ -93,40 +89,45 @@ class exports.LayerStates extends BaseClass
animatablePropertyKeys = [] animatablePropertyKeys = []


for k, v of properties for k, v of properties

# We can animate numbers
if _.isNumber(v) if _.isNumber(v)
animatablePropertyKeys.push(k) animatablePropertyKeys.push(k)

# We can animate colors
else if Color.isColorObject(v) else if Color.isColorObject(v)
animatablePropertyKeys.push(k) 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 if animatablePropertyKeys.length == 0
instant = true instant = true


if instant is true if instant
# We want to switch immediately without animation
@layer.props = properties @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 @_animation?.stop()
# Start the animation and update the state when finished @_animation = @layer.animate(animationOptions)
animationOptions ?= @animationOptions
animationOptions.properties = properties


@_animation?.stop() # Once the animation is done, we set all the keys that we could not animate
@_animation = @layer.animate animationOptions @_animation.once "stop", =>
@_animation.once "stop", =>


# Set all the values for keys that we couldn't animate for k, v of properties
for k, v of properties @layer[k] = v if v not in animatablePropertyKeys
@layer[k] = v unless _.isNumber(v) or Color.isColorObject(v)


@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) -> switchInstant: (stateName) ->
@switch stateName, null, true @switch(stateName, null, true)


@define "state", get: -> @_currentState @define "state", get: -> @_currentState
@define "current", get: -> @_currentState @define "current", get: -> @_currentState
Expand All @@ -138,7 +139,7 @@ class exports.LayerStates extends BaseClass


animatingKeys: -> animatingKeys: ->


# Get a list of all the propeties controlled by states # Get a list of all the properties controlled by states


keys = [] keys = []


Expand Down Expand Up @@ -177,11 +178,31 @@ class exports.LayerStates extends BaseClass


# TODO: Maybe we want to support advanced data structures like objects in the future too. # TODO: Maybe we want to support advanced data structures like objects in the future too.
for k, v of properties 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 @_isValidColor(k, v)
if _.isString(v) and _.endsWith(k.toLowerCase(),"color") and Color.isColorString(v)
stateProperties[k] = new Color(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 stateProperties[k] = v


return stateProperties 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
20 changes: 20 additions & 0 deletions test/tests/LayerStatesTest.coffee
Original file line number Original file line Diff line number Diff line change
@@ -1,3 +1,5 @@
assert = require "assert"

describe "LayerStates", -> describe "LayerStates", ->


describe "Events", -> describe "Events", ->
Expand Down Expand Up @@ -179,3 +181,21 @@ describe "LayerStates", ->


layer.states.switchInstant "default" layer.states.switchInstant "default"
layer.x.should.equal 0 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.