-
Notifications
You must be signed in to change notification settings - Fork 0
/
d3-contort.coffee
83 lines (74 loc) · 2.24 KB
/
d3-contort.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# Some helper classses
class xyValue
constructor: (@x=0,@y=0) ->
setValue: (newValue,increment) ->
switch (typeof newValue)
when 'number'
if increment
@x += newValue
@y += newValue
else
@x = newValue
@y = newValue
when 'object'
if increment
@x += newValue.x ?= newValue.x
@y += newValue.y ?= newValue.x
else
@x = newValue.x ?= newValue.x
@y = newValue.y ?= newValue.x
toString: -> @x + "," + @y
class degreeValue
constructor: (@number=0)->
setValue: (newValue,increment)->
if increment then newValue += @number
@number = Math.round((newValue % 360 + ((if newValue >= 0 then 0 else 360)))) unless @number is newValue
toString: -> @number
# The transform object
class Transform
constructor: ()->
@translate ?= new xyValue 0,0
@scale ?= new xyValue 1,1
@rotate ?= new degreeValue
@skewX ?= new degreeValue
@skewY ?= new degreeValue
Transform::order = -> ["translate","scale","rotate","skewX","skewY"]
Transform::toString = ->
@order().map(
(name) -> name + "(" + @[name].toString() + ")"
, @).join " "
# Start contorting d3.selection
for name in Transform::order()
do (name) ->
d3.selection::[name] = (value,increment=false) ->
len = @[0].length
for e,i in @[0]
do (e)->
e.__transform__ ?= new Transform
switch (typeof value)
when 'number','object'
e.__transform__[name].setValue value,increment
when 'function'
e.__transform__[name].setValue value(e.__data__,i,len),increment
@
d3.selection::render = ->
for e in @[0]
do (e)->
e.__transform__ ?= new Transform
e.setAttribute "transform", e.__transform__.toString()
@
d3.selection::animate = (options={}) ->
{duration,ease,opacity,delay} = options
duration ?= 500
ease ?= "ease"
opacity ?= "1"
delay ?= 0
for e in @[0]
do (e)->
e.__transform__ ?= new Transform
d3.select(e).transition()
.duration(duration)
.delay(delay)
.ease(d3.ease(ease))
.attr({transform: e.__transform__.toString(),"opacity": opacity})
@