Skip to content
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
@@ -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.
You can’t perform that action at this time.