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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: be553169a45e21824a1d92e6287d3777e7bf78839cce188fe86d708d40496f26
4
- data.tar.gz: 186d0ebf8b817cc88fde9561873e9949ed8f200658c0265f25162cfec56e9471
3
+ metadata.gz: 4af6242d846ea8899602a29bcd733684ace66c2d02c227cc207fdbeeb247cdfa
4
+ data.tar.gz: e0596e3496ae8c0a706005708a054d8bfea06433f458bcf42d02435ec94c6b0a
5
5
  SHA512:
6
- metadata.gz: 9c6dc62087ae7a8a0c7e393ef4ad6767a846205e3fd87a797b6e7c9c6546f0da1c4be21056e48b3a797cb82352f51b057a729a3f828f15b4eb02b3d3ac68adad
7
- data.tar.gz: 0dce5f67e95e032c29638e1da8799b626482f37efebb60ff7ec1daf678992732b54c42fbe34a1b30dd86a0e5ce17633e61b24b9d8a0d4b311bf6e83f97e94a35
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 (default blue)
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 (default red)
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 cx="<%= col_x.call(string) %>" cy="<%= row_y.call(fret) %>"
135
- r="4.4" fill="<%= root ? root_color : highlight_color %>" />
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 (default blue)
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 (default red)
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="--outro-guitar-highlight: <%= highlight_color %>;
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 (default blue)
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 (default red)
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
- width = [white_index, 1].max * white_w
52
-
53
- fill_for = lambda do |key|
54
- if root_midis.include?(key[:midi]) then root_color
55
- elsif highlighted_midis.include?(key[:midi]) then highlight_color
56
- elsif key[:black] then "#222222"
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 x="<%= key[:x] %>" y="0"
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="<%= fill_for.call(key) %>"
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 x="<%= key[:x] %>" y="0"
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="<%= fill_for.call(key) %>"
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 (default blue)
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 (default red)
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="--outro-piano-highlight: <%= highlight_color %>;
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| %>
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OutroRails
4
- VERSION = "0.1.9"
4
+ VERSION = "0.1.11"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: outro_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.9
4
+ version: 0.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - endtoendpaper