-
Notifications
You must be signed in to change notification settings - Fork 19
/
colours.rb
105 lines (92 loc) · 3.7 KB
/
colours.rb
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# https://en.wikipedia.org/wiki/Farnsworth-Munsell_100_hue_test
SQUARES = 22
SQUARE_SIZE = 50
SQUARE_PADDING = 2
TITLE = "Farnsworth-Munsell 100 Hue Color Vision Test [COMPLETED %d%%]"
HUES = [
[[172, 118, 114], [143, 140, 74]],
[[143, 140, 74], [84, 151, 137]],
[[84, 151, 137], [128, 136, 165]],
[[128, 136, 165], [173, 119, 118]]
]
def generate_rgb(rgb_start, rgb_end, segments = 2)
rstep, gstep, bstep = 3.times.collect { |n|
rgb_start[n].to_f.step(
by: ((rgb_end[n] - rgb_start[n]) / (segments - 1).to_f),
to: rgb_end[n]
).to_a
}
segments.times.collect { |n| rgb(rstep[n].floor, gstep[n].floor, bstep[n].floor) }
end
Shoes.app(width: (SQUARE_SIZE + SQUARE_PADDING) * SQUARES + SQUARE_PADDING, height: (SQUARE_SIZE + SQUARE_PADDING) * HUES.size + SQUARE_PADDING, title: TITLE % 0, resizable: false) do
flow(top: SQUARE_PADDING, left: SQUARE_PADDING / 2, width: (SQUARE_SIZE + SQUARE_PADDING) * SQUARES) do
@hues = HUES.collect { |rgb_start, rgb_end| generate_rgb(rgb_start, rgb_end, SQUARES) }
@hues.collect { |n| [n.first, n[1..-2].shuffle, n.last].flatten }.each_with_index { |list, index|
SQUARES.times { |n|
(@r ||= []) << rect(left: (SQUARE_SIZE + SQUARE_PADDING) * n, top: (SQUARE_SIZE + SQUARE_PADDING) * ((n + (index * SQUARES)) / SQUARES), width: SQUARE_SIZE, height: SQUARE_SIZE)
@r.last.fill = @r.last.stroke = list[n]
}
}
end
@top_rect = rect(width: SQUARE_SIZE, height: SQUARE_SIZE).hide
motion do |left, top|
@top_rect.move(left - (@controller.width / 2), top - (@controller.height / 2)) unless @controller.nil?
end
@anim = animate(10) do |frame|
if 0 == frame % 5
set_window_title(TITLE % (@completed * 100 / @r.size)) unless @completed.nil?
if @highlight
@hues.flatten.each_with_index { |item, index|
@r[index].stroke = item.eql?(@r[index].fill) ? @r[index].fill : rgb(255, 0, 0)
}
else
@r.each { |n| n.stroke = n.fill }
end
end
if @success
5.times {
a, b = rand(@r.size), rand(@r.size)
@r[a].fill, @r[b].fill = @r[b].fill, @r[a].fill
}
end
end
keypress do |k|
@highlight ^= true if k.eql?("h")
end
start do
@highlight = false
@r.each_with_index { |n, skip|
next if 0 == skip % SQUARES or (SQUARES - 1) == (skip % SQUARES)
n.click do |btn, left, top|
if @success
set_window_title(TITLE % (@completed = 0))
@hues.collect { |n| [n.first, n[1..-2].shuffle, n.last].flatten }.flatten.each_with_index { |item, index|
@r[index].fill = @r[index].stroke = item
}
@success = false
@top_rect.hide unless @top_rect.nil?
@controller = nil
next
end
unless @controller.nil?
if n.top.eql?(@controller.top)
n.fill, @controller.fill = @controller.fill, n.fill
n.stroke, @controller.stroke = @controller.stroke, n.stroke
@top_rect.hide
@controller = nil
end
else
@controller = n
@top_rect.left, @top_rect.top = n.left, n.top
@top_rect.fill, @top_rect.stroke = n.fill, n.stroke
@top_rect.show
end
@success = true
@completed = 0
@hues.flatten.each_with_index { |item, index|
item.eql?(@r[index].fill) ? @completed += 1 : @success = false
}
end
}
end
end