-
Notifications
You must be signed in to change notification settings - Fork 479
/
LinearGradient.coffee
79 lines (63 loc) · 2.19 KB
/
LinearGradient.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
{_} = require "./Underscore"
{BaseClass} = require "./BaseClass"
{Color} = require "./Color"
class exports.LinearGradient extends BaseClass
constructor: (options = {}) ->
options.start ?= "black"
options.end ?= "white"
options.angle ?= 0
super options
@define "start",
get: -> @_start
set: (value) ->
@_start = new Color(value)
@define "end",
get: -> @_end
set: (value) ->
@_end = new Color(value)
@define "angle",
get: -> @_angle
set: (value) ->
@_angle = value if _.isNumber(value)
toCSS: =>
return "linear-gradient(#{this.angle}deg, #{this.start}, #{this.end})"
mix: (gradientB, fraction, model) =>
return LinearGradient.mix(@, gradientB, fraction, model)
isEqual: (gradientB) ->
return LinearGradient.equal(@, gradientB)
toInspect: =>
return "<#{@constructor.name} start:#{@start} end:#{@end} angle:#{@angle}>"
##############################################################
## Class methods
@mix: (gradientA, gradientB, fraction = 0.5, model) ->
fraction = Utils.clamp(fraction, 0, 1)
start = Color.mix(gradientA.start, gradientB.start, fraction, false, model)
end = Color.mix(gradientA.end, gradientB.end, fraction, false, model)
startAngle = gradientA.angle
endAngle = gradientB.angle
normalizer = Utils.rotationNormalizer()
normalizer(startAngle)
endAngle = normalizer(endAngle)
angle = startAngle + (endAngle - startAngle) * fraction
return new LinearGradient
start: start
end: end
angle: angle
@random: ->
hue = Math.random() * 360
colorA = new Color h: hue
colorB = new Color h: hue + 40
return new LinearGradient
start: colorA
end: colorB
angle: Math.random() * 360
@isLinearGradient: (gradient) -> return gradient instanceof LinearGradient
@equal: (gradientA, gradientB) ->
return false unless LinearGradient.isLinearGradient(gradientA)
return false unless LinearGradient.isLinearGradient(gradientB)
equalAngle = Math.abs(gradientA.angle - gradientB.angle) % 360 is 0
equalStart = Color.equal(gradientA.start, gradientB.start)
equalEnd = Color.equal(gradientA.end, gradientB.end)
return equalAngle and equalStart and equalEnd
@_asPlainObject: (gradient) ->
_.pick(gradient, ["start", "end", "angle"])