-
Notifications
You must be signed in to change notification settings - Fork 0
/
stickers.html
210 lines (194 loc) · 16.9 KB
/
stickers.html
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Piano stickers</title>
<link rel="stylesheet" href="stickers.css">
<script type="importmap">
{
"imports": {
"vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
}
}
</script>
<script type="module">
import { createApp } from 'vue';
import MainComponent from './stickers.js';
createApp(MainComponent).mount('#app');
</script>
</head>
<body>
<p class="githubproject">The source-code for this project is available at <a href="https://github.com/denilsonsa/piano_keys_stickers">https://github.com/denilsonsa/piano_keys_stickers</a>.</p>
<template id="staffsvgtemplate">
<!--
This SVG code is based on the images from:
https://commons.wikimedia.org/wiki/Category:Musical_score_components_(2)
Their license is Public Domain.
-->
<svg class="staffsvg" :view-box.camel="`0 0 ${total_width} 57`">
<!-- rect x="0" y="0" :width="total_width" height="60" fill="#eee" /-->
<g class="staff" fill="#000000">
<rect :x="-2 * base_width" :y="1 + line_y(10)" :width="total_width + 4 * base_width" height="1" />
<rect :x="-2 * base_width" :y="1 + line_y( 8)" :width="total_width + 4 * base_width" height="1" />
<rect :x="-2 * base_width" :y="1 + line_y( 6)" :width="total_width + 4 * base_width" height="1" />
<rect :x="-2 * base_width" :y="1 + line_y( 4)" :width="total_width + 4 * base_width" height="1" />
<rect :x="-2 * base_width" :y="1 + line_y( 2)" :width="total_width + 4 * base_width" height="1" />
</g>
<g class="clef F" fill="#000000" transform="translate(0,17)" v-if="clef === 'F' || clef === 'F8'">
<circle cx="15" cy="3" r="1" />
<circle cx="15" cy="8" r="1" />
<g transform="translate(-230.9546,-533.6597)" >
<path d="M 243.97900,540.86798 C 244.02398,543.69258 242.76360,546.43815 240.76469,548.40449 C 238.27527,550.89277 235.01791,552.47534 231.69762,553.53261 C 231.25590,553.77182 230.58970,553.45643 231.28550,553.13144 C 232.62346,552.52289 234.01319,552.00050 235.24564,551.18080 C 237.96799,549.49750 240.26523,546.84674 240.82279,543.61854 C 241.14771,541.65352 241.05724,539.60795 240.56484,537.67852 C 240.20352,536.25993 239.22033,534.79550 237.66352,534.58587 C 236.25068,534.36961 234.74885,534.85905 233.74057,535.88093 C 233.47541,536.14967 232.95916,536.89403 233.04435,537.74747 C 233.64637,537.27468 233.60528,537.32732 234.09900,537.10717 C 235.23573,536.60031 236.74349,537.32105 237.02700,538.57272 C 237.32909,539.72295 237.09551,541.18638 235.96036,541.79960 C 234.77512,542.44413 233.02612,542.17738 232.36450,540.90866 C 231.26916,538.95418 231.87147,536.28193 233.64202,534.92571 C 235.44514,533.42924 238.07609,533.37089 240.19963,534.13862 C 242.38419,534.95111 243.68629,537.21483 243.89691,539.45694 C 243.95419,539.92492 243.97896,540.39668 243.97900,540.86798 z" />
</g>
</g>
<g class="clef F8" fill="#000000" transform="scale(0.66) translate(-19,-12)" v-if="clef === 'F8'">
<!-- Modified from: https://commons.wikimedia.org/wiki/File:Octaveclef.svg license CC BY-SA 3.0 -->
<path d="M26.4,68.3c-0.3-0.4-0.5-0.8-0.6-1.1s-0.2-0.7-0.2-1.1c0-0.7,0.2-1.3,0.7-1.7s1.1-0.7,1.9-0.7c0.7,0,1.3,0.2,1.7,0.6 s0.6,0.9,0.6,1.4c0,0.4-0.1,0.7-0.3,1s-0.4,0.6-0.7,0.8c-0.2,0.1-0.5,0.3-1,0.5c0.5,0.7,0.9,1.2,1,1.5s0.2,0.6,0.2,1 c0,0.8-0.3,1.5-0.9,2.1s-1.3,0.9-2.2,0.9c-0.8,0-1.4-0.2-1.9-0.6s-0.7-1-0.7-1.6c0-0.4,0.1-0.8,0.3-1.2s0.5-0.7,0.9-1 C25.5,68.7,25.9,68.5,26.4,68.3z M26.7,68.6c-0.2,0.2-0.4,0.4-0.5,0.5c-0.1,0.2-0.3,0.6-0.4,1s-0.2,0.9-0.2,1.5 c0,0.4,0.1,0.7,0.2,0.9s0.4,0.3,0.7,0.3c0.3,0,0.6-0.2,0.8-0.5c0.3-0.4,0.5-0.9,0.5-1.5c0-0.4-0.1-0.7-0.2-1.1S27.1,69.1,26.7,68.6 z M28.1,67.5c0.2-0.2,0.4-0.4,0.5-0.5c0.2-0.4,0.3-1,0.3-1.7c0-0.4-0.1-0.8-0.2-0.9S28.4,64,28.2,64c-0.2,0-0.4,0.1-0.6,0.3 c-0.2,0.3-0.3,0.7-0.3,1.3c0,0.3,0.1,0.6,0.2,0.9S27.8,67.1,28.1,67.5z" />
</g>
<g class="clef C" fill="#000000" transform="translate(3,16)" v-if="clef === 'C'">
<g transform="matrix(1,0,0,1.030698,-309.364,-543.8647)">
<path d="M 325.90302,546.76398 C 325.77565,548.73599 324.67385,550.74769 322.76364,551.48291 C 321.1258,552.0885 319.0617,552.18049 317.638,551.0277 C 316.57277,550.23951 316.16568,548.44596 317.27983,547.51996 C 318.34407,546.51189 320.39149,547.42114 320.26891,548.90426 C 320.68605,549.92222 318.52287,550.54748 319.66017,551.2611 C 320.96855,551.60188 322.30255,550.53315 322.63842,549.29104 C 323.1266,547.50862 323.10071,545.58499 322.67301,543.79274 C 322.44295,542.90899 321.89729,541.53645 320.73027,541.89426 C 319.20285,542.2489 318.34585,543.75774 317.865,545.13 C 317.58677,543.18531 316.36388,541.50362 314.958,540.192 C 314.958,544.09834 314.95801,548.00467 314.95801,551.91101 L 314.08301,551.91554 C 314.08301,543.88753 314.08301,535.6966 314.08301,527.66859 L 314.95801,527.66785 C 314.95801,531.51886 314.95801,535.529 314.95801,539.38 C 316.35227,538.08767 317.58034,536.43374 317.844,534.505 C 318.34775,535.94355 319.32246,537.53197 320.97,537.755 C 322.1809,537.82161 322.52686,536.34503 322.76844,535.42539 C 323.08591,533.68738 323.12057,531.8389 322.56968,530.14452 C 322.17561,528.95315 320.88042,527.97772 319.60389,528.29761 C 318.57267,529.04912 320.60708,529.59275 320.26318,530.5613 C 320.48284,531.95228 318.76106,533.04005 317.57439,532.3192 C 316.28904,531.61505 316.38273,529.72095 317.37337,528.80541 C 318.04771,528.10885 319.33076,527.65914 320.27066,527.66651 C 321.22932,527.67403 321.7886,527.74487 322.64672,528.04424 C 324.56799,528.72938 325.72882,530.70423 325.88682,532.67197 C 326.17716,534.90335 324.92877,537.33821 322.82569,538.21926 C 321.45806,538.74967 319.87609,538.29068 318.827,537.317 C 318.65552,538.29407 318.22016,539.2263 317.68074,539.9006 C 318.11632,540.61049 318.58743,541.75295 318.82791,542.14434 C 320.14125,540.94807 322.46143,540.80379 323.82848,541.98977 C 325.22049,543.13189 326.08868,544.95009 325.90302,546.76398 z" />
</g>
<g transform="matrix(1,0,0,1.030928,-309.364,-543.9805)" >
<path d="M 312.208,551.911 L 309.364,551.911 L 309.364,527.661 L 312.208,527.661 L 312.208,551.911 z" />
</g>
</g>
<g class="clef G" fill="#000000" transform="translate(-213,-507.5)" v-if="clef === 'G' || clef === 'G8'">
<path d="M 225.4624,521.10094 C 225.76676,524.2272 223.44258,526.75724 221.38475,528.80243 C 220.44987,529.69959 221.22979,528.95062 220.74106,529.39673 C 220.63891,528.9171 220.4425,527.66516 220.46085,527.2863 C 220.59134,524.5924 222.78068,520.69883 224.69872,519.26276 C 225.00763,519.83947 225.26235,519.88587 225.4624,521.10094 z M 226.1134,537.24297 C 224.88087,536.33701 223.26304,536.09953 221.7794,536.35796 C 221.58806,535.1033 221.39673,533.84864 221.20539,532.59398 C 223.55643,530.26494 226.11198,527.56209 226.24646,524.05491 C 226.30521,521.82297 225.97021,519.38356 224.56771,517.57134 C 222.86757,517.69957 221.66851,519.7273 220.76611,520.98784 C 219.2772,523.65834 219.6247,526.90476 220.19607,529.7843 C 219.38668,530.73602 218.26654,531.52774 217.4687,532.5181 C 215.1126,534.8268 213.06023,537.94835 213.46406,541.39645 C 213.64742,544.73044 216.05349,547.83082 219.33428,548.62377 C 220.57998,548.93799 221.89823,548.96898 223.1584,548.72196 C 223.37834,550.97205 224.18546,553.35162 223.2509,555.53506 C 222.55016,557.13364 220.46335,558.53977 218.9184,557.72696 C 218.31903,557.41163 218.80473,557.6762 218.44035,557.47569 C 219.51021,557.21838 220.44,556.43919 220.70042,555.91077 C 221.5382,554.44657 220.30058,552.27158 218.54502,552.55196 C 216.28302,552.59874 215.35456,555.69274 216.8094,557.23696 C 218.15619,558.75735 220.6424,558.54915 222.23951,557.55497 C 224.05248,556.37502 224.27872,554.01178 224.07165,551.99297 C 224.00217,551.31557 223.66932,549.32312 223.62812,548.60614 C 224.32534,548.35778 223.83738,548.54706 224.8209,548.15762 C 227.48112,547.10426 229.17841,543.8988 228.41503,541.03484 C 228.09684,539.56602 227.37134,538.12115 226.1134,537.24297 z M 226.6744,542.99999 C 226.88844,544.99168 225.62069,547.32146 223.59538,547.95989 C 223.45912,547.16492 223.4232,546.94908 223.3324,546.48576 C 222.85018,544.02504 222.5884,541.49789 222.2164,539.00396 C 223.84132,538.83591 225.67403,539.54718 226.2393,541.18872 C 226.48303,541.7651 226.58156,542.38546 226.6744,542.99999 z M 221.5254,548.19597 C 218.98126,548.33744 216.52586,546.60099 215.89113,544.11562 C 215.14212,541.96246 215.36282,539.48536 216.7118,537.61088 C 217.82694,535.90898 219.31831,534.50651 220.7404,533.06796 C 220.9234,534.19529 221.1064,535.32261 221.28939,536.44994 C 218.29876,537.23208 216.28479,541.1752 218.0744,543.90096 C 218.60684,544.66522 220.05087,546.12411 220.8399,545.53496 C 219.73792,544.85259 218.83658,543.67652 219.03041,542.30836 C 218.94828,541.0259 220.40026,539.39775 221.6817,539.11003 C 222.12011,541.97928 222.62298,545.18372 223.0614,548.05297 C 222.55601,548.15299 222.04025,548.19594 221.5254,548.19597 z" />
</g>
<g class="clef G8" fill="#000000" transform="scale(0.66) translate(-10,-58)" v-if="clef === 'G8'">
<!-- Modified from: https://commons.wikimedia.org/wiki/File:Octaveclef.svg license CC BY-SA 3.0 -->
<path d="M26.4,68.3c-0.3-0.4-0.5-0.8-0.6-1.1s-0.2-0.7-0.2-1.1c0-0.7,0.2-1.3,0.7-1.7s1.1-0.7,1.9-0.7c0.7,0,1.3,0.2,1.7,0.6 s0.6,0.9,0.6,1.4c0,0.4-0.1,0.7-0.3,1s-0.4,0.6-0.7,0.8c-0.2,0.1-0.5,0.3-1,0.5c0.5,0.7,0.9,1.2,1,1.5s0.2,0.6,0.2,1 c0,0.8-0.3,1.5-0.9,2.1s-1.3,0.9-2.2,0.9c-0.8,0-1.4-0.2-1.9-0.6s-0.7-1-0.7-1.6c0-0.4,0.1-0.8,0.3-1.2s0.5-0.7,0.9-1 C25.5,68.7,25.9,68.5,26.4,68.3z M26.7,68.6c-0.2,0.2-0.4,0.4-0.5,0.5c-0.1,0.2-0.3,0.6-0.4,1s-0.2,0.9-0.2,1.5 c0,0.4,0.1,0.7,0.2,0.9s0.4,0.3,0.7,0.3c0.3,0,0.6-0.2,0.8-0.5c0.3-0.4,0.5-0.9,0.5-1.5c0-0.4-0.1-0.7-0.2-1.1S27.1,69.1,26.7,68.6 z M28.1,67.5c0.2-0.2,0.4-0.4,0.5-0.5c0.2-0.4,0.3-1,0.3-1.7c0-0.4-0.1-0.8-0.2-0.9S28.4,64,28.2,64c-0.2,0-0.4,0.1-0.6,0.3 c-0.2,0.3-0.3,0.7-0.3,1.3c0,0.3,0.1,0.6,0.2,0.9S27.8,67.1,28.1,67.5z" />
</g>
<template v-for="(note, index) in notes" :key="note">
<g class="auxiliary" fill="#000000">
<rect :x="5 + index_x(index)" :y="1 + line_y(line)" width="10" height="1" v-for="line in auxiliary_lines(note)" />
</g>
<g class="note" fill="#000000" :transform="`translate(${index_x(index)}, ${line_y(note)})`">
<g transform="translate(-170,-538)">
<path d="M 181.26500,536.34802 C 179.71640,536.34776 178.25135,537.14037 177.19237,538.23274 C 176.42387,539.05628 175.83001,540.19719 176.04725,541.35163 C 176.20962,542.20095 176.93309,542.88353 177.78220,543.02495 C 179.09952,543.28080 180.47023,542.85267 181.54815,542.09005 C 182.60831,541.38586 183.53015,540.33185 183.77300,539.05209 C 183.92825,538.24242 183.65657,537.34045 182.98100,536.83829 C 182.49428,536.46538 181.86559,536.34722 181.26500,536.34802 z" />
</g>
<rect class="stem" x="13" y="-19" width="1" height="20" v-if="note < 6" />
<rect class="stem" x=" 6" y="3" width="1" height="20" v-else />
</g>
</template>
</svg>
</template>
<div id="app">
<form>
<fieldset>
<legend>Layout settings (configure this to your needs)</legend>
<div>
<span>White key width (mm):</span>
<input type="number" name="width_white" v-model="dimensions.width_white" min="1" max="99" step="0.1">
</div>
<div>
<span>Black key width (mm):</span>
<input type="number" name="width_black" v-model="dimensions.width_black" min="1" max="99" step="0.1">
</div>
<div>
<span>White key height (mm):</span>
<input type="number" name="height_white" v-model="dimensions.height_white" min="1" max="99" step="0.1">
</div>
<div>
<span>Black key height (mm):</span>
<input type="number" name="height_black" v-model="dimensions.height_black" min="1" max="99" step="0.1">
</div>
<div>
<span>Note range (MIDI values):</span>
<input type="number" name="min_code" v-model="min_note_code" min="0" max="127" step="1">
<input type="number" name="max_code" v-model="max_note_code" min="0" max="127" step="1">
<input type="button" value="25 keys" @click="min_note_code = 48; max_note_code = 72">
<input type="button" value="49 keys" @click="min_note_code = 36; max_note_code = 84">
<input type="button" value="61 keys" @click="min_note_code = 36; max_note_code = 96">
<input type="button" value="76 keys" @click="min_note_code = 28; max_note_code = 103">
<input type="button" value="88 keys" @click="min_note_code = 21; max_note_code = 108">
</div>
<div>
{{ white_notes_count + black_notes_count }} keys ({{ white_notes_count }} white keys + {{ black_notes_count }} black keys), {{ (white_notes_count * dimensions.width_white + black_notes_count * dimensions.width_black).toFixed(1) }}mm total.
</div>
</fieldset>
<fieldset>
<legend>Visual tweaks (that you don't need to change)</legend>
<div>
<span>Frequency precision:</span>
<label><input type="radio" name="frequency_precision" :value="2" v-model="frequency_precision"> 2 digits</label>
<label><input type="radio" name="frequency_precision" :value="3" v-model="frequency_precision"> 3 digits</label>
<label><input type="radio" name="frequency_precision" :value="4" v-model="frequency_precision"> 4 digits</label>
<label><input type="radio" name="frequency_precision" :value="5" v-model="frequency_precision"> 5 digits</label>
<label><input type="radio" name="frequency_precision" :value="6" v-model="frequency_precision"> 6 digits</label>
</div>
<div>
<span>Frequency for A4 (tuning):</span>
<input type="number" name="frequency_a4" v-model="note_opts.frequency_a4" min="390" max="500" step="0.1">
</div>
<div>
<span>Clefs:</span>
<label><input type="radio" name="clefs_visible" :value="true" v-model="clefs_visible"> Visible</label>
<label><input type="radio" name="clefs_visible" :value="false" v-model="clefs_visible"> Hidden</label>
</div>
<div>
<span>Clef for middle C:</span>
<label><input type="radio" name="middle_c_clef" value="G" v-model="note_opts.middle_c_clef"> 𝄞</label>
<label><input type="radio" name="middle_c_clef" value="C" v-model="note_opts.middle_c_clef"> 𝄡</label>
<label><input type="radio" name="middle_c_clef" value="F" v-model="note_opts.middle_c_clef"> 𝄢</label>
<label><input type="radio" name="middle_c_clef" value="" v-model="note_opts.middle_c_clef"> none, show both 𝄞 and 𝄢 positions without showing the clef</label>
</div>
<div>
<span>Octave number for middle C:</span>
<label><input type="radio" name="middle_c_octave" :value="3" v-model="note_opts.middle_c_octave"> 3</label>
<label><input type="radio" name="middle_c_octave" :value="4" v-model="note_opts.middle_c_octave"> 4</label>
</div>
<div>
<span>Solfège note names:</span>
<label><input type="radio" name="solfege_do" value="Do" v-model="note_opts.solfege.do"> Do</label>
<label><input type="radio" name="solfege_do" value="Doh" v-model="note_opts.solfege.do"> Doh</label>
;
<label><input type="radio" name="solfege_sol" value="Sol" v-model="note_opts.solfege.sol"> Sol</label>
<label><input type="radio" name="solfege_sol" value="So" v-model="note_opts.solfege.sol"> So</label>
;
<label><input type="radio" name="solfege_si" value="Si" v-model="note_opts.solfege.si"> Si</label>
<label><input type="radio" name="solfege_si" value="Ti" v-model="note_opts.solfege.si"> Ti</label>
</div>
</fieldset>
</form>
<main :style="inline_styles">
<article class="strip">
<div class="folding-margin"></div>
<div class="keys-container">
<template v-for="note in all_notes" :key="note.code">
<div
class="whitenote"
:class="[ note.letter, { 'has_flat': note.left_is_flat, 'has_sharp': note.right_is_sharp } ]"
v-if="note.is_major"
>
<span class="accidental flat "><img src="Flat.svg" alt="flat symbol" ></span>
<span class="accidental sharp"><img src="Sharp.svg" alt="sharp symbol"></span>
<span class="name solfege">{{ note.solfege }}</span>
<span class="name letter">{{ note.letter }}</span>
<span class="octave">{{ note.octave }}</span>
<span class="frequency"><span class="number">{{ note.frequency_digits(frequency_precision) }}</span><span class="unit">Hz</span></span>
<span class="code">{{ note.code }}</span>
<span class="color"></span>
<span class="staff">
<template v-if="note.is_middle_c">
<staff-svg
:clef="clefs_visible && note_opts.middle_c_clef ? note.staff_clef : null"
:notes="note_opts.middle_c_clef ? [ note.note_position ] : [ note.note_position_in_clef('F'), note.note_position_in_clef('G') ]"
></staff-svg>
</template>
<template v-else>
<staff-svg :clef="clefs_visible ? note.staff_clef : null" :notes="[ note.note_position ]" v-if="note.note_position !== undefined"></staff-svg>
</template>
</span>
</div>
<div class="blacknote" v-else>
<span class="frequency"><span class="number">{{ note.frequency_digits(frequency_precision) }}</span><span class="unit">Hz</span></span>
</div>
</template>
</div>
</article>
</main>
</div>
</body>
</html>