outro_rails 0.1.9 → 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/views/outro_rails/instruments/_guitar_figure.html.erb +24 -9
- data/app/views/outro_rails/instruments/_guitar_midi.html.erb +14 -8
- data/app/views/outro_rails/instruments/_piano_figure.html.erb +56 -18
- data/app/views/outro_rails/instruments/_piano_midi.html.erb +14 -8
- data/lib/outro_rails/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4af6242d846ea8899602a29bcd733684ace66c2d02c227cc207fdbeeb247cdfa
|
|
4
|
+
data.tar.gz: e0596e3496ae8c0a706005708a054d8bfea06433f458bcf42d02435ec94c6b0a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 99ddf446681ed2f970a173ed974ae06ef62af29d9704239d098c85680f97ad8baa806716b59c729971eaffb6d9d47ef4a98063bac8bb6682446fcd8b60e86f86
|
|
7
|
+
data.tar.gz: ba8b72aceb60a40d8e879def6fac061b57c3bfa042e9ad13da2919529f855334e866954f9494222bbf078e52c60e1c8681499971375dd6bd1a833665f2c921ae
|
|
@@ -14,9 +14,11 @@
|
|
|
14
14
|
"string:fret" strings (string 1 = highest pitch).
|
|
15
15
|
Fret 0 marks the string open (O above the nut);
|
|
16
16
|
strings with no position at all are muted (X).
|
|
17
|
-
highlight_color: any CSS color for the dots
|
|
17
|
+
highlight_color: any CSS color for the dots. Omit to inherit
|
|
18
|
+
--outro-accent from the host app.
|
|
18
19
|
root_frets: subset of positions to mark as roots (default [])
|
|
19
|
-
root_color: any CSS color for root dots
|
|
20
|
+
root_color: any CSS color for root dots. Omit to inherit
|
|
21
|
+
--outro-root from the host app.
|
|
20
22
|
prefer: 'sharps' or 'flats' for the note labels under the
|
|
21
23
|
box (default 'sharps')
|
|
22
24
|
%>
|
|
@@ -36,16 +38,27 @@
|
|
|
36
38
|
highlight_frets = guitar_positions(
|
|
37
39
|
Array(local_assigns.fetch(:highlight_frets, [])).select(&complete)
|
|
38
40
|
)
|
|
39
|
-
highlight_color = local_assigns.fetch(:highlight_color,
|
|
40
|
-
"var(--outro-accent, #2f6bed)")
|
|
41
41
|
root_frets = guitar_positions(
|
|
42
42
|
Array(local_assigns.fetch(:root_frets, [])).select(&complete)
|
|
43
43
|
)
|
|
44
44
|
highlight_frets |= root_frets
|
|
45
|
-
root_color = local_assigns.fetch(:root_color,
|
|
46
|
-
"var(--outro-root, #d1495b)")
|
|
47
45
|
prefer = local_assigns.fetch(:prefer, "sharps").to_sym
|
|
48
46
|
|
|
47
|
+
highlight_color = local_assigns[:highlight_color].presence
|
|
48
|
+
root_color = local_assigns[:root_color].presence
|
|
49
|
+
figure_vars = [
|
|
50
|
+
("--outro-figure-highlight: #{highlight_color};" if highlight_color),
|
|
51
|
+
("--outro-figure-root: #{root_color};" if root_color)
|
|
52
|
+
].compact.join(" ").presence
|
|
53
|
+
|
|
54
|
+
# A caller-passed color can itself be a var() expression, which is no use
|
|
55
|
+
# as a presentation-attribute fallback; fall back to the literal default.
|
|
56
|
+
literal = lambda do |color, default|
|
|
57
|
+
color.nil? || color.to_s.include?("var(") ? default : color
|
|
58
|
+
end
|
|
59
|
+
highlight_fill = literal.call(highlight_color, "#2f6bed")
|
|
60
|
+
root_fill = literal.call(root_color, "#d1495b")
|
|
61
|
+
|
|
49
62
|
open_midis = guitar_open_midis(tuning) # { 1 => 64, ..., 6 => 40 }
|
|
50
63
|
strings = open_midis.keys.sort # 1 (rightmost col) .. N (leftmost)
|
|
51
64
|
string_count = strings.size
|
|
@@ -87,7 +100,8 @@
|
|
|
87
100
|
viewBox="0 0 <%= width %> <%= height %>"
|
|
88
101
|
width="<%= width %>"
|
|
89
102
|
role="img"
|
|
90
|
-
aria-label="Guitar chord box, low to high: <%= frets_label %>"
|
|
103
|
+
aria-label="Guitar chord box, low to high: <%= frets_label %>"
|
|
104
|
+
<%= tag.attributes(style: figure_vars) %>>
|
|
91
105
|
<g stroke="currentColor" stroke-opacity="0.75" stroke-width="0.8">
|
|
92
106
|
<%# strings (vertical) %>
|
|
93
107
|
<% strings.each do |string| %>
|
|
@@ -131,8 +145,9 @@
|
|
|
131
145
|
<% highlight_frets.each do |string, fret| %>
|
|
132
146
|
<% next unless fret.positive? && fret >= row_start %>
|
|
133
147
|
<% root = roots.include?([string, fret]) %>
|
|
134
|
-
<circle
|
|
135
|
-
|
|
148
|
+
<circle class="outro-figure__dot <%= root ? "is-root" : "is-highlighted" %>"
|
|
149
|
+
cx="<%= col_x.call(string) %>" cy="<%= row_y.call(fret) %>"
|
|
150
|
+
r="4.4" fill="<%= root ? root_fill : highlight_fill %>" />
|
|
136
151
|
<% end %>
|
|
137
152
|
|
|
138
153
|
<%# sounded note names under the box %>
|
|
@@ -10,12 +10,14 @@
|
|
|
10
10
|
1 (highest pitch) to 6 (lowest). Accepts [string, fret]
|
|
11
11
|
pairs or "string:fret" strings, e.g.
|
|
12
12
|
[[5, 3], [4, 2], [3, 0], [2, 1], [1, 0]] (open C major)
|
|
13
|
-
highlight_color: any CSS color for the dots
|
|
13
|
+
highlight_color: any CSS color for the dots. Omit to inherit
|
|
14
|
+
--outro-accent from the host app (see note below).
|
|
14
15
|
root_frets: subset of positions to mark as roots with a distinct
|
|
15
16
|
color, same formats as highlight_frets (default []).
|
|
16
17
|
Root positions should also be included in
|
|
17
18
|
highlight_frets so playback covers them.
|
|
18
|
-
root_color: any CSS color for root dots
|
|
19
|
+
root_color: any CSS color for root dots. Omit to inherit
|
|
20
|
+
--outro-root from the host app.
|
|
19
21
|
|
|
20
22
|
When highlight_frets is present, "Play Chord" strums all marked notes
|
|
21
23
|
(lowest first, slightly staggered like a downstroke) and "Play Notes"
|
|
@@ -29,13 +31,18 @@
|
|
|
29
31
|
default_tuning = OutroRails::InstrumentsHelper::GUITAR_STANDARD_TUNING
|
|
30
32
|
tuning = local_assigns.fetch(:tuning, default_tuning)
|
|
31
33
|
highlight_frets = guitar_positions(local_assigns.fetch(:highlight_frets, []))
|
|
32
|
-
highlight_color = local_assigns.fetch(:highlight_color,
|
|
33
|
-
"var(--outro-accent, #2f6bed)")
|
|
34
34
|
root_frets = guitar_positions(local_assigns.fetch(:root_frets, []))
|
|
35
|
-
root_color = local_assigns.fetch(:root_color,
|
|
36
|
-
"var(--outro-root, #d1495b)")
|
|
37
35
|
prefer = local_assigns.fetch(:prefer, 'sharps')
|
|
38
36
|
|
|
37
|
+
# Only emit inline custom properties for colors the caller actually
|
|
38
|
+
# passed; the stylesheet owns the defaults.
|
|
39
|
+
highlight_color = local_assigns[:highlight_color].presence
|
|
40
|
+
root_color = local_assigns[:root_color].presence
|
|
41
|
+
color_vars = [
|
|
42
|
+
("--outro-guitar-highlight: #{highlight_color};" if highlight_color),
|
|
43
|
+
("--outro-guitar-root: #{root_color};" if root_color)
|
|
44
|
+
].compact.join(" ").presence
|
|
45
|
+
|
|
39
46
|
start_fret, end_fret = end_fret, start_fret if start_fret > end_fret
|
|
40
47
|
guitar = OutroRails::Instruments::Guitar
|
|
41
48
|
fret_range = guitar::MIN_FRET..guitar::MAX_FRET
|
|
@@ -62,8 +69,7 @@
|
|
|
62
69
|
|
|
63
70
|
<div class="outro-guitar"
|
|
64
71
|
data-outro-guitar
|
|
65
|
-
style
|
|
66
|
-
--outro-guitar-root: <%= root_color %>;">
|
|
72
|
+
<%= tag.attributes(style: color_vars) %>>
|
|
67
73
|
<div>
|
|
68
74
|
<div class="outro-guitar__board"
|
|
69
75
|
role="group"
|
|
@@ -4,13 +4,33 @@
|
|
|
4
4
|
fills (not CSS backgrounds), they survive printing even when the
|
|
5
5
|
browser skips background graphics.
|
|
6
6
|
|
|
7
|
+
Colors: highlighted and root keys carry `is-highlighted` / `is-root`
|
|
8
|
+
classes and are colored from the stylesheet -
|
|
9
|
+
|
|
10
|
+
.outro-figure__svg {
|
|
11
|
+
--outro-figure-highlight: var(--outro-accent, #2f6bed);
|
|
12
|
+
--outro-figure-root: var(--outro-root, #d1495b);
|
|
13
|
+
}
|
|
14
|
+
.outro-figure__key.is-highlighted { fill: var(--outro-figure-highlight); }
|
|
15
|
+
.outro-figure__key.is-root { fill: var(--outro-figure-root); }
|
|
16
|
+
|
|
17
|
+
The `fill="..."` attributes below are literal-color fallbacks, not the
|
|
18
|
+
real styling. Browsers ignore them, because any author stylesheet rule
|
|
19
|
+
outranks an SVG presentation attribute; renderers that don't understand
|
|
20
|
+
CSS custom properties (wkhtmltopdf, resvg, Prawn) fall back to them.
|
|
21
|
+
Note that var() does NOT work in a presentation attribute - custom
|
|
22
|
+
properties are only substituted in CSS declarations - which is why the
|
|
23
|
+
colors live in the stylesheet rather than in a fill="" here.
|
|
24
|
+
|
|
7
25
|
Takes the same locals as instruments/_piano_midi (all optional):
|
|
8
26
|
start_note: first key, e.g. "C3" (default "C3")
|
|
9
27
|
end_note: last key, e.g. "C5" (default "C5")
|
|
10
28
|
highlight_keys: array of note names to highlight, e.g. %w[C4 E4 G4]
|
|
11
|
-
highlight_color: any CSS color for highlighted keys
|
|
29
|
+
highlight_color: any CSS color for highlighted keys. Omit to inherit
|
|
30
|
+
--outro-accent from the host app.
|
|
12
31
|
root_keys: subset of keys to mark as roots (default [])
|
|
13
|
-
root_color: any CSS color for root keys
|
|
32
|
+
root_color: any CSS color for root keys. Omit to inherit
|
|
33
|
+
--outro-root from the host app.
|
|
14
34
|
prefer: 'sharps' or 'flats' for spelling (default 'sharps')
|
|
15
35
|
%>
|
|
16
36
|
|
|
@@ -18,13 +38,24 @@
|
|
|
18
38
|
start_note = local_assigns.fetch(:start_note, nil).presence || "C3"
|
|
19
39
|
end_note = local_assigns.fetch(:end_note, nil).presence || "C5"
|
|
20
40
|
highlight_keys = Array(local_assigns.fetch(:highlight_keys, []))
|
|
21
|
-
highlight_color = local_assigns.fetch(:highlight_color,
|
|
22
|
-
"var(--outro-accent, #2f6bed)")
|
|
23
41
|
root_keys = Array(local_assigns.fetch(:root_keys, []))
|
|
24
|
-
root_color = local_assigns.fetch(:root_color,
|
|
25
|
-
"var(--outro-root, #d1495b)")
|
|
26
42
|
prefer = local_assigns.fetch(:prefer, "sharps").to_sym
|
|
27
43
|
|
|
44
|
+
highlight_color = local_assigns[:highlight_color].presence
|
|
45
|
+
root_color = local_assigns[:root_color].presence
|
|
46
|
+
figure_vars = [
|
|
47
|
+
("--outro-figure-highlight: #{highlight_color};" if highlight_color),
|
|
48
|
+
("--outro-figure-root: #{root_color};" if root_color)
|
|
49
|
+
].compact.join(" ").presence
|
|
50
|
+
|
|
51
|
+
# A caller-passed color can itself be a var() expression, which is no use
|
|
52
|
+
# as a presentation-attribute fallback; fall back to the literal default.
|
|
53
|
+
literal = lambda do |color, default|
|
|
54
|
+
color.nil? || color.to_s.include?("var(") ? default : color
|
|
55
|
+
end
|
|
56
|
+
highlight_fill = literal.call(highlight_color, "#2f6bed")
|
|
57
|
+
root_fill = literal.call(root_color, "#d1495b")
|
|
58
|
+
|
|
28
59
|
keys = piano_keys_between(start_note, end_note, prefer: prefer)
|
|
29
60
|
highlighted_midis = highlight_keys.map { |n| note_to_midi(n) }
|
|
30
61
|
root_midis = root_keys.map { |n| note_to_midi(n) }
|
|
@@ -48,16 +79,20 @@
|
|
|
48
79
|
end
|
|
49
80
|
end
|
|
50
81
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
elsif
|
|
56
|
-
|
|
57
|
-
else "#ffffff"
|
|
82
|
+
# => [state class or nil, literal fill fallback]
|
|
83
|
+
key_paint = lambda do |key|
|
|
84
|
+
if root_midis.include?(key[:midi]) then ["is-root", root_fill]
|
|
85
|
+
elsif highlighted_midis.include?(key[:midi]) then ["is-highlighted", highlight_fill]
|
|
86
|
+
elsif key[:black] then [nil, "#222222"]
|
|
87
|
+
else [nil, "#ffffff"]
|
|
58
88
|
end
|
|
59
89
|
end
|
|
60
90
|
|
|
91
|
+
key_classes = lambda do |key, variant|
|
|
92
|
+
state = key_paint.call(key).first
|
|
93
|
+
["outro-figure__key", "outro-figure__key--#{variant}", state].compact.join(" ")
|
|
94
|
+
end
|
|
95
|
+
|
|
61
96
|
label =
|
|
62
97
|
if highlight_keys.any?
|
|
63
98
|
"Piano voicing: #{highlight_keys.join(', ')}"
|
|
@@ -75,17 +110,20 @@
|
|
|
75
110
|
width="<%= (vb_w * 0.9).round %>"
|
|
76
111
|
height="<%= (vb_h * 0.9).round %>"
|
|
77
112
|
role="img"
|
|
78
|
-
aria-label="<%= label %>"
|
|
113
|
+
aria-label="<%= label %>"
|
|
114
|
+
<%= tag.attributes(style: figure_vars) %>>
|
|
79
115
|
<% whites.each do |key| %>
|
|
80
|
-
<rect
|
|
116
|
+
<rect class="<%= key_classes.call(key, "white") %>"
|
|
117
|
+
x="<%= key[:x] %>" y="0"
|
|
81
118
|
width="<%= white_w %>" height="<%= white_h %>"
|
|
82
|
-
rx="1.5" fill="<%=
|
|
119
|
+
rx="1.5" fill="<%= key_paint.call(key).last %>"
|
|
83
120
|
stroke="#444444" stroke-width="<%= stroke_w %>" />
|
|
84
121
|
<% end %>
|
|
85
122
|
<% blacks.each do |key| %>
|
|
86
|
-
<rect
|
|
123
|
+
<rect class="<%= key_classes.call(key, "black") %>"
|
|
124
|
+
x="<%= key[:x] %>" y="0"
|
|
87
125
|
width="<%= black_w %>" height="<%= black_h %>"
|
|
88
|
-
rx="1.5" fill="<%=
|
|
126
|
+
rx="1.5" fill="<%= key_paint.call(key).last %>"
|
|
89
127
|
stroke="#111111" stroke-width="<%= stroke_w %>" />
|
|
90
128
|
<% end %>
|
|
91
129
|
</svg>
|
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
end_note: last key, e.g. "C5" (default "C5")
|
|
7
7
|
highlight_keys: array of note names to highlight,
|
|
8
8
|
e.g. %w[C4 E4 G4] (default [])
|
|
9
|
-
highlight_color: any CSS color for highlighted keys
|
|
9
|
+
highlight_color: any CSS color for highlighted keys. Omit to inherit
|
|
10
|
+
--outro-accent from the host app (see note below).
|
|
10
11
|
root_keys: subset of keys to mark as roots with a distinct color,
|
|
11
12
|
e.g. %w[C4 C5] (default []). Root keys should also be
|
|
12
13
|
included in highlight_keys so playback covers them.
|
|
13
|
-
root_color: any CSS color for root keys
|
|
14
|
+
root_color: any CSS color for root keys. Omit to inherit
|
|
15
|
+
--outro-root from the host app.
|
|
14
16
|
|
|
15
17
|
When highlight_keys is present, "Play Chord" plays all highlighted notes
|
|
16
18
|
at once and "Play Notes" plays them one at a time (low to high).
|
|
@@ -21,13 +23,18 @@
|
|
|
21
23
|
start_note = local_assigns.fetch(:start_note, "C3")
|
|
22
24
|
end_note = local_assigns.fetch(:end_note, "C5")
|
|
23
25
|
highlight_keys = Array(local_assigns.fetch(:highlight_keys, []))
|
|
24
|
-
highlight_color = local_assigns.fetch(:highlight_color,
|
|
25
|
-
"var(--outro-accent, #2f6bed)")
|
|
26
26
|
root_keys = Array(local_assigns.fetch(:root_keys, []))
|
|
27
|
-
root_color = local_assigns.fetch(:root_color,
|
|
28
|
-
"var(--outro-root, #d1495b)")
|
|
29
27
|
prefer = local_assigns.fetch(:prefer, 'sharps').to_sym
|
|
30
28
|
|
|
29
|
+
# Only emit inline custom properties for colors the caller actually
|
|
30
|
+
# passed; the stylesheet owns the defaults.
|
|
31
|
+
highlight_color = local_assigns[:highlight_color].presence
|
|
32
|
+
root_color = local_assigns[:root_color].presence
|
|
33
|
+
color_vars = [
|
|
34
|
+
("--outro-piano-highlight: #{highlight_color};" if highlight_color),
|
|
35
|
+
("--outro-piano-root: #{root_color};" if root_color)
|
|
36
|
+
].compact.join(" ").presence
|
|
37
|
+
|
|
31
38
|
keys = piano_keys_between(start_note, end_note, prefer: prefer)
|
|
32
39
|
highlighted_midis = highlight_keys.map { |n| note_to_midi(n) }
|
|
33
40
|
root_midis = root_keys.map { |n| note_to_midi(n) }
|
|
@@ -37,8 +44,7 @@
|
|
|
37
44
|
|
|
38
45
|
<div class="outro-piano"
|
|
39
46
|
data-outro-piano
|
|
40
|
-
style
|
|
41
|
-
--outro-piano-root: <%= root_color %>;">
|
|
47
|
+
<%= tag.attributes(style: color_vars) %>>
|
|
42
48
|
<div class="outro-piano__keys" role="group"
|
|
43
49
|
aria-label="<%= keys_label %>">
|
|
44
50
|
<% keys.each do |key| %>
|
data/lib/outro_rails/version.rb
CHANGED