Permalink
Browse files

Add screen scaling functions

  • Loading branch information...
koenbok committed Oct 27, 2014
1 parent f6816e1 commit f86b69aeac5d20b0d8ce4082d8ba8295be5c7756
Showing with 137 additions and 36 deletions.
  1. +51 −36 framer/Layer.coffee
  2. +61 −0 test/tests/ContextTest.coffee
  3. +25 −0 test/tests/LayerTest.coffee
View
@@ -316,44 +316,37 @@ class exports.Layer extends BaseClass
# TODO: I don't think this is correct yet because you have to account
# for scale+origin and rotation+origin each step in the layer hierarchy.
_superOrParentLayer: ->
if @superLayer
return @superLayer
if @_context._parentLayer
return @_context._parentLayer
screenOriginX = ->
if @_superOrParentLayer()
return @_superOrParentLayer().screenOriginX()
return @originX
screenOriginY = ->
if @_superOrParentLayer()
return @_superOrParentLayer().screenOriginY()
return @originY
screenScaleX: ->
if @_superOrParentLayer()
return @_superOrParentLayer().screenScaleX()
return @scale * @scaleX
screenScaleY: ->
if @_superOrParentLayer()
return @_superOrParentLayer().screenScaleY()
return @scale * @scaleY
screenRotationX: ->
screenRotationY: ->
screenRotationZ: ->
scaledScreenFrame = ->
frame = @screenFrame
frame.width *= @screenScaleX()
frame.height *= @screenScaleY()
screenScale: ->
scale = @scale
for superLayer in @superLayers()
scale = scale * superLayer.scale
return scale
scaledFrame: ->
frame = @frame
frame.width *= @scale
frame.height *= @scale
frame.x += (1 - @scale) * @originX * @width
frame.y += (1 - @scale) * @originY * @height
frame
screenScaledFrame: ->
frame =
x: 0
y: 0
width: @width * @screenScale()
height: @height * @screenScale()
frame.x += (@width - frame.width) * @screenOriginX
frame.y += (@height - frame.height) * @screenOriginY
layers = @superLayers()
layers.push(@)
layers.reverse()
for superLayer in layers
factor = if superLayer.superLayer then superLayer.superLayer.screenScale() else 1
layerScaledFrame = superLayer.scaledFrame()
frame.x += layerScaledFrame.x * factor
frame.y += layerScaledFrame.y * factor
return frame
##############################################################
@@ -593,6 +586,20 @@ class exports.Layer extends BaseClass
subLayersByName: (name) ->
_.filter @subLayers, (layer) -> layer.name == name
superLayers: ->
superLayers = []
currentLayer = @
while currentLayer.superLayer
superLayers.push(currentLayer.superLayer)
currentLayer = currentLayer.superLayer
return superLayers
_superOrParentLayer: ->
if @superLayer
return @superLayer
if @_context._parentLayer
return @_context._parentLayer
##############################################################
## ANIMATION
@@ -759,3 +766,11 @@ class exports.Layer extends BaseClass
on: @::addListener
off: @::removeListener
##############################################################
## DESCRIPTOR
toString: ->
if @name
return "<Layer id:#{@id} name:#{@name} (#{@x},#{@y}) #{@width}x#{@height}>"
return "<Layer id:#{@id} (#{@x},#{@y}) #{@width}x#{@height}>"
@@ -0,0 +1,61 @@
assert = require "assert"
describe "Context", ->
describe "Reset", ->
# Todo: event cleanup
# Todo: paren layer on context cleanup
describe "Events", ->
it "should emit reset", (callback) ->
context = new Framer.Context(name:"Test")
context.on "reset", -> callback()
context.reset()
it "should emit layer create", (callback) ->
context = new Framer.Context(name:"Test")
context.on "layer:create", ->
context.getLayers().length.should.equal 1
callback()
context.run ->
layer = new Layer
it "should emit layer destroy", (callback) ->
context = new Framer.Context(name:"Test")
context.on "layer:create", ->
context.getLayers().length.should.equal 1
context.on "layer:destroy", ->
context.getLayers().length.should.equal 0
callback()
context.run ->
layer = new Layer
layer.destroy()
it "should keep layer id count per context", ->
context = new Framer.Context(name:"Test")
context.run ->
layer = new Layer
layer.id.should.equal 1
layer = new Layer
layer.id.should.equal 2
context.reset()
context.run ->
layer = new Layer
layer.id.should.equal 1
layer = new Layer
layer.id.should.equal 2
@@ -553,6 +553,12 @@ describe "Layer", ->
layerA.subLayersByName("B").should.eql [layerB]
layerA.subLayersByName("C").should.eql [layerC, layerD]
it "should get a superlayers", ->
layerA = new Layer
layerB = new Layer superLayer:layerA
layerC = new Layer superLayer:layerB
layerC.superLayers().should.eql [layerB, layerA]
describe "Frame", ->
it "should set on create", ->
@@ -648,6 +654,25 @@ describe "Layer", ->
assert.equal layerB.screenFrame.x, 900
assert.equal layerB.screenFrame.y, 900
it "should calculate scale", ->
layerA = new Layer scale:0.9
layerB = new Layer scale:0.8, superLayer:layerA
layerB.screenScale().should.equal 0.9 * 0.8
it "should calculate scaled frame", ->
layerA = new Layer x:100, width:500, height:900, scale:0.5
layerA.scaledFrame().should.eql {"x":225,"y":225,"width":250,"height":450}
it "should calculate scaled screen frame", ->
layerA = new Layer x:100, width:500, height:900, scale:0.5
layerB = new Layer y:50, width:600, height:600, scale:0.8, superLayer:layerA
layerC = new Layer y:-60, width:800, height:700, scale:1.2, superLayer:layerB
layerA.screenScaledFrame().should.eql {"x":225,"y":225,"width":250,"height":450}
layerB.screenScaledFrame().should.eql {"x":255,"y":280,"width":240,"height":240}
layerC.screenScaledFrame().should.eql {"x":223,"y":228,"width":384,"height":336}
describe "Center", ->
it "should center", ->

0 comments on commit f86b69a

Please sign in to comment.