Skip to content
Permalink
Browse files

first commit

  • Loading branch information...
koenbok committed Dec 20, 2012
0 parents commit bcd1a1f2ed5b230fc273e0e8d47f77ee7f4ac61a
@@ -0,0 +1,5 @@
.DS_Store
node_modules

build
dist
@@ -0,0 +1,11 @@
all: build

build:
make clean
mkdir -p build
./node_modules/browserify/bin/cmd.js src/init.coffee -o build/framer.js

clean:
rm -rf dist

.PHONY: build clean
@@ -0,0 +1,4 @@
Framer - www.framerjs.com

Framer is a modern prototyping tool. It can help you to quickly build and test complex interactions and rich animations for both desktop and mobile.

@@ -0,0 +1,139 @@
{Spring} = require "./primitives/spring"
{EventEmitter} = require "./eventemitter"

require "./utils"

PROPERTIES = ["view", "curve", "time"]

parseCurve = (a) ->

# "spring(1, 2, 3)" -> 1, 2, 3

a = a.replace "spring", ""
a = a.replace /\s+/g, ""
a = a.replace "(", ""
a = a.replace ")", ""
a = a.split ","

return a.map (i) -> parseFloat i


class exports.Animation extends EventEmitter

constructor: (args) ->
super

for p in PROPERTIES
@[p] = args[p]

@modifiers = args.modifiers or {}
@endProperties = args.properties

start: (callback) =>

@beginProperties = @view.properties
setTimeout =>
@_start callback
, 0
# @_start callback

stop: ->
@_stop = true

_end: (callback) =>
@emit "end", @
callback?()

_start: (callback) =>

@emit "start", @

@_stop = false

time = @time or 300
curve = @curve or "linear"
# linear, ease, ease-in, ease-out, ease-in-out
# cubic-bezier(0.76, 0.18, 0.25, 0.75)
# spring(tension, friction, velocity)

if curve[..5] == "spring"

if @time
console.log "view.animate: ignoring time for spring"

values = parseCurve curve
options =
tension: values[0]
friction: values[1]
velocity: values[2]
speed: 1/60

@_startSpring options, callback

return

@_animate @endProperties, curve, time, =>
@_end callback


_startSpring: (options, callback) =>

@spring = new Spring options

beginState = {}
deltas = {}

for k, v of @endProperties
deltas[k] = (@endProperties[k] - @beginProperties[k]) / 100.0
beginState[k] = @beginProperties[k]

run = =>

# If the spring stopped moving we can stop
if not @spring.moving or @_stop
return @_end callback

value = @spring.next()

if @modifiers[k]
value = @modifiers[k](value)

nextState = {}

for k, v of beginState

nextState[k] = (deltas[k] * value) + beginState[k]

# Let's round some variables to pixels to avoid pixel cracks. So not scale
# and opacity, but basically all others. I think it makes sense to avoid these
# for designers, but you lose some control wit this magic added.
# if k in ["x", "y", "z", "width", "height"]
# nextState[k] = parseInt nextState[k]

@_animate nextState, "linear", @spring.speed, run

run()

_animate: (properties, curve, time, callback) =>

# @view._animated = true
@view._animationDuration = time
@view._animationTimingFunction = curve

# FIX: we should probarbly do it like this:
# http://stackoverflow.com/questions/2087510/callback-on-css-transition

@timer = setTimeout =>
# @view._animated = false
# @view._animationDuration = 0
callback?()
, time

for k, v of properties
if k in ["rotation", "opacity", "scale", "x", "y", "z", "width", "height"]
@view[k] = properties[k]


pause: ->

revert: ->
@@ -0,0 +1,38 @@
addStyle = (css) ->

head = document.getElementsByTagName "head"
head = head[0] if head

if not head
head = document.body or document.documentElement

baseStyle = document.createElement "style"
baseStyle.id = "UILayer-base-style"
baseStyle.appendChild document.createTextNode(css)

head.appendChild baseStyle

addStyle "
.uilayer {
display: block;
visibility: visible;
position: absolute;
top:auto; right:auto; bottom:auto; left:auto;
width:auto; height:auto;
overflow: visible;
z-index:0;
opacity:1;
-webkit-box-sizing: border-box;
}
.uilayer.textureBacked {
-webkit-transform: matrix3d(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1);
-webkit-transform-origin: 50% 50% 0%;
-webkit-backface-visibility: hidden;
-webkit-transform-style: flat;
}
.uilayer.animated {
-webkit-transition-duration: 500ms;
-webkit-transition-timing-function: linear;
-webkit-transition-delay: 0;
-webkit-transition-property: none;
}"
@@ -0,0 +1,48 @@
class exports.EventEmitter

constructor: ->
@events = {}

emit: (event, args...) ->

if not @events?[event]
return

for listener in @events[event]
listener args...

addListener: (event, listener) ->

# @emit "addListener", event, listener

@events ?= {}
@events[event] ?= []
@events[event].push listener

removeListener: (event, listener) ->

# @emit "removeListener", event, listener

return unless @events
return unless @events[event]

@events[event] = (l for l in @events[event] when l isnt listener)

once: (event, listener) ->

fn = =>
@removeListener event, fn
listener arguments...

@on event, fn


removeAllListeners: (event) ->
return unless @events
return unless @events[event]

for listener in @events[event]
@removeListener event, listener

on: @::addListener
off: @::removeListener
@@ -0,0 +1,56 @@
require "./css"

utils = require "./utils"

{View} = require "./views/view"
{ViewList} = require "./views/view"
{ScrollView} = require "./views/scrollview"
# {CollectionView} = require "./views/collectionview"
{ImageView} = require "./views/imageview"
# {TextView} = require "./views/textview"
{Animation} = require "./animation"

{Frame} = require "./primitives/frame"

Global = {}
Global.View = View
Global.ScrollView = ScrollView
# Global.CollectionView = CollectionView
Global.ImageView = ImageView
# Global.TextView = TextView
Global.Animation = Animation
Global.Frame = Frame

Global.utils = utils
Global.ViewList = ViewList

if window
window.Prothese = Global

for k, v of Global
window[k] = v



Global.debug = (value) ->
for view in ViewList
if value is true
colorValue = -> parseInt(Math.random() * 255)
debugStyle =
backgroundImage: ""
backgroundColor: "rgba(0,100,255,0.2)"
# border: "2px solid rgba(0,100,255,0.1)"
view._debugStyle = {}
for key of debugStyle
view._debugStyle[key] = view.style[key]
view.style = debugStyle
else if value is false
view.style = view._debugStyle
else return
Global._debug = value

toggler = utils.toggle true, false

window.addEventListener "keydown", (e) ->
if e.keyCode is 68 and e.shiftKey
Global.debug toggler()
@@ -0,0 +1,64 @@
Class =
UIEvent: "UIEvent"
FocusEvent: "FocusEvent"
MouseEvent: "MouseEvent"
TouchEvent: "TouchEvent"
WheelEvent: "WheelEvent"
TextEvent: "TextEvent"
KeyboardEvent: "KeyboardEvent"
CompositionEvent: "CompositionEvent"
MutationEvent: "MutationEvent"
MutationNameEvent: "MutationNameEvent"
CustomEvent: "CustomEvent"
TransitionEvent: "TransitionEvent"

Types =
DOMActivate: Class.UIEvent
load: Class.UIEvent
unload: Class.UIEvent
abort: Class.UIEvent
error: Class.UIEvent
select: Class.UIEvent
resize: Class.UIEvent
scroll: Class.UIEvent
blur: Class.FocusEvent
DOMFocusIn: Class.FocusEvent
DOMFocusOut: Class.FocusEvent
focus: Class.FocusEvent
focusin: Class.FocusEvent
focusout: Class.FocusEvent
click: Class.MouseEvent
dblclick: Class.MouseEvent
mousedown: Class.MouseEvent
mouseenter: Class.MouseEvent
mouseleave: Class.MouseEvent
mousemove: Class.MouseEvent
mouseover: Class.MouseEvent
mouseout: Class.MouseEvent
mouseup: Class.MouseEvent
touchstart: Class.TouchEvent
touchmove: Class.TouchEvent
touchend: Class.TouchEvent
touchcancel: Class.TouchEvent
wheel: Class.WheelEvent
textinput: Class.TextEvent
keydown: Class.KeyboardEvent
keypress: Class.KeyboardEvent
keyup: Class.KeyboardEvent
compositionstart: Class.CompositionEvent
compositionupdate: Class.CompositionEvent
compositionend: Class.CompositionEvent
DOMAttrModified: Class.MutationEvent
DOMCharacterDataModified: Class.MutationEvent
DOMNodeInserted: Class.MutationEvent
DOMNodeInsertedIntoDocument: Class.MutationEvent
DOMNodeRemoved: Class.MutationEvent
DOMNodeRemovedFromDocument: Class.MutationEvent
DOMSubtreeModified: Class.MutationEvent
DOMAttributeNameChanged: Class.MutationNameEvent
DOMElementNameChanged: Class.MutationNameEvent
transitionend: Class.TransitionEvent

exports.EventClass = Class
exports.EventTypes = Types

Oops, something went wrong.

0 comments on commit bcd1a1f

Please sign in to comment.
You can’t perform that action at this time.