Changeset 3364816
- Timestamp:
- 09/20/2025 05:12:06 AM (6 months ago)
- Location:
- ptpiano/tags/1.2.9
- Files:
-
- 1 edited
- 43 copied
-
. (copied) (copied from ptpiano/trunk)
-
PT-piano-icon.png (copied) (copied from ptpiano/trunk/PT-piano-icon.png)
-
PT_Piano_Player.php (copied) (copied from ptpiano/trunk/PT_Piano_Player.php) (6 diffs)
-
PT_Piano_Setting.php (copied) (copied from ptpiano/trunk/PT_Piano_Setting.php) (4 diffs)
-
functions.php (copied) (copied from ptpiano/trunk/functions.php) (6 diffs)
-
icon.png (copied) (copied from ptpiano/trunk/icon.png)
-
ir (copied) (copied from ptpiano/trunk/ir)
-
js (copied) (copied from ptpiano/trunk/js)
-
js/admin-settings.js (copied) (copied from ptpiano/trunk/js/admin-settings.js)
-
js/control.js (copied) (copied from ptpiano/trunk/js/control.js)
-
js/midiwriter.min.js (copied) (copied from ptpiano/trunk/js/midiwriter.min.js)
-
js/piano.augmented.mark.js (copied) (copied from ptpiano/trunk/js/piano.augmented.mark.js) (1 diff)
-
js/piano.diminished.mark.js (copied) (copied from ptpiano/trunk/js/piano.diminished.mark.js) (1 diff)
-
js/piano.major.mark.js (copied) (copied from ptpiano/trunk/js/piano.major.mark.js) (1 diff)
-
js/piano.major.scale.js (copied) (copied from ptpiano/trunk/js/piano.major.scale.js) (1 diff)
-
js/piano.minor.mark.js (copied) (copied from ptpiano/trunk/js/piano.minor.mark.js) (1 diff)
-
js/piano.minor.scale.js (copied) (copied from ptpiano/trunk/js/piano.minor.scale.js) (1 diff)
-
js/piano.recorder.js (copied) (copied from ptpiano/trunk/js/piano.recorder.js)
-
js/piano.reverb.js (copied) (copied from ptpiano/trunk/js/piano.reverb.js)
-
js/piano.sound.js (copied) (copied from ptpiano/trunk/js/piano.sound.js) (1 diff)
-
js/piano.web.midi.js (copied) (copied from ptpiano/trunk/js/piano.web.midi.js)
-
ptpiano.php (copied) (copied from ptpiano/trunk/ptpiano.php) (2 diffs)
-
readme.txt (copied) (copied from ptpiano/trunk/readme.txt) (3 diffs)
-
speaker.png (copied) (copied from ptpiano/trunk/speaker.png)
-
styles (copied) (copied from ptpiano/trunk/styles)
-
styles/admin-settings.css (copied) (copied from ptpiano/trunk/styles/admin-settings.css)
-
styles/frontend-dynamic.css (copied) (copied from ptpiano/trunk/styles/frontend-dynamic.css) (1 diff)
-
styles/piano.css (copied) (copied from ptpiano/trunk/styles/piano.css) (1 diff)
-
theme (copied) (copied from ptpiano/trunk/theme)
-
theme/thumb0.png (modified) (previous)
-
tunes (copied) (copied from ptpiano/trunk/tunes)
-
tunes/4.wav (copied) (copied from ptpiano/trunk/tunes/4.wav)
-
tunes/5.wav (copied) (copied from ptpiano/trunk/tunes/5.wav)
-
tunes/6.wav (copied) (copied from ptpiano/trunk/tunes/6.wav)
-
tunes/b.wav (copied) (copied from ptpiano/trunk/tunes/b.wav)
-
tunes/c.wav (copied) (copied from ptpiano/trunk/tunes/c.wav)
-
tunes/k.wav (copied) (copied from ptpiano/trunk/tunes/k.wav)
-
tunes/l.wav (copied) (copied from ptpiano/trunk/tunes/l.wav)
-
tunes/n.wav (copied) (copied from ptpiano/trunk/tunes/n.wav)
-
tunes/o.wav (copied) (copied from ptpiano/trunk/tunes/o.wav)
-
tunes/p.wav (copied) (copied from ptpiano/trunk/tunes/p.wav)
-
tunes/v.wav (copied) (copied from ptpiano/trunk/tunes/v.wav)
-
tunes/x.wav (copied) (copied from ptpiano/trunk/tunes/x.wav)
-
tunes/z.wav (copied) (copied from ptpiano/trunk/tunes/z.wav)
Legend:
- Unmodified
- Added
- Removed
-
ptpiano/tags/1.2.9/PT_Piano_Player.php
r3361001 r3364816 3 3 exit; // Exit if accessed directly 4 4 } 5 ?> 6 <?php 5 7 6 if ( ! function_exists( 'get_plugin_data' ) ) { 8 7 require_once ABSPATH . 'wp-admin/includes/plugin.php'; … … 11 10 $plugin_data = get_plugin_data( plugin_dir_path(__FILE__) . 'ptpiano.php' ); 12 11 $plugin_version = $plugin_data['Version']; 12 13 $record_duration = get_option('ptpian_record_duration', 30); // fallback to 30 13 14 ?> 14 15 <div class="ptpiano-wrapper"> … … 18 19 <p>Please wait, PTPiano loading...</p> 19 20 </div> 21 <!-- Record Poppop only for this section --> 22 <div id="recordLimitPopup" class="popup-overlay"> 23 <div class="popup-content"> 24 <h3>⏰ Time Limit Reached</h3> 25 <p>Max recording length <?php echo esc_html($record_duration); ?> seconds.</p> 26 <button id="closePopupBtn" class="play-icon-btn" title="Close">▶️ Play</button> 27 </div> 28 </div> 29 20 30 <div class="ptpiano-content" style="display:none;"> 21 31 <!-- your existing plugin content --> 22 <div class=" wrapper">32 <div class="content-wrapper"> 23 33 <header> 24 34 <div class="columnbox"> … … 138 148 <option value="">Major</option> 139 149 <option value="C">C Chords</option> 150 <option value="C#">C♯ Chords</option> 140 151 <option value="D">D Chords</option> 152 <option value="D#">D♯ Chords</option> 141 153 <option value="E">E Chords</option> 142 154 <option value="F">F Chords</option> 155 <option value="F#">F♯ Chords</option> 143 156 <option value="G">G Chords</option> 157 <option value="G#">G♯ Chords</option> 144 158 <option value="A">A Chords</option> 159 <option value="A#">A♯ Chords</option> 160 <option value="B">B Chords</option> 145 161 </select> 146 162 147 163 <select id="minorchord" name="minorchord" class="<?php echo esc_attr($minor_hidden_class); ?>"> 148 164 <option value="">Minor</option> 149 <option value="c">c Chords</option> 150 <option value="d">d Chords</option> 151 <option value="e">e Chords</option> 152 <option value="f">f Chords</option> 153 <option value="g">g Chords</option> 154 <option value="a">a Chords</option> 165 <option value="C">C Chords</option> 166 <option value="C#">C♯ Chords</option> 167 <option value="D">D Chords</option> 168 <option value="D#">D♯ Chords</option> 169 <option value="E">E Chords</option> 170 <option value="F">F Chords</option> 171 <option value="F#">F♯ Chords</option> 172 <option value="G">G Chords</option> 173 <option value="G#">G♯ Chords</option> 174 <option value="A">A Chords</option> 175 <option value="A#">A♯ Chords</option> 176 <option value="B">B Chords</option> 155 177 </select> 156 178 157 179 <select id="diminishedchord" name="diminishedchord" class="<?php echo esc_attr($dim_hidden_class); ?>"> 158 180 <option value="">Diminished</option> 159 <option value="c">c Chords</option> 160 <option value="d">d Chords</option> 161 <option value="e">e Chords</option> 162 <option value="f">f Chords</option> 163 <option value="g">g Chords</option> 164 <option value="a">a Chords</option> 181 <option value="C">C DIM</option> 182 <option value="C#">C# DIM</option> 183 <option value="D">D DIM</option> 184 <option value="D#">D# DIM</option> 185 <option value="E">E DIM</option> 186 <option value="F">F DIM</option> 187 <option value="F#">F# DIM</option> 188 <option value="G">G DIM</option> 189 <option value="G#">G# DIM</option> 190 <option value="A">A DIM</option> 191 <option value="A#">A# DIM</option> 192 <option value="B">B DIM</option> 193 </select> 194 165 195 </select> 166 196 <select id="augmentedchord" name="augmentedchord" class="<?php echo esc_attr($agu_hidden_class); ?>"> 167 197 <option value="">Augmented</option> 168 <option value="Caug">C Augmented</option> 169 <option value="C#aug">C# Augmented</option> 170 <option value="Daug">D Augmented</option> 171 <option value="D#aug">D# Augmented</option> 172 <option value="Eaug">E Augmented</option> 173 <option value="Faug">F Augmented</option> 174 <option value="F#aug">F# Augmented</option> 175 <option value="Gaug">G Augmented</option> 176 <option value="G#aug">G# Augmented</option> 177 <option value="Aaug">A Augmented</option> 178 <option value="A#aug">A# Augmented</option> 179 <option value="Baug">B Augmented</option> 180 </select> 181 </div> 198 <option value="C">C Augmented</option> 199 <option value="C#">C# Augmented</option> 200 <option value="D">D Augmented</option> 201 <option value="D#">D# Augmented</option> 202 <option value="E">E Augmented</option> 203 <option value="F">F Augmented</option> 204 <option value="F#">F# Augmented</option> 205 <option value="G">G Augmented</option> 206 <option value="G#">G# Augmented</option> 207 <option value="A">A Augmented</option> 208 <option value="A#">A# Augmented</option> 209 <option value="B">B Augmented</option> 210 </select> 211 </div> 212 <span id="common-progression" class="ctl-label"></span> 182 213 </div> 183 214 </div> … … 254 285 </div> 255 286 256 <div class="right-column"> 257 287 <div class="right-column"> 258 288 <?php if ($res_chordtxt): ?> 259 <input id="showchord" value="NOTE / CHORD" type="text" readonly style=" 260 appearance: none; 261 border: none; 262 outline: none; 263 border: .2em solid #0BBAFB; 264 background: #252424; 265 border-radius: .2em .2em 0 0; 266 text-align: center; 267 padding: .6em; 268 margin:0 auto; 269 color: <?php echo esc_attr($res_txt_color); ?>;" /> 289 <input id="showchord" value="NOTE / CHORD" type="text" readonly class="showscalechord" /> 270 290 <?php endif; ?> 271 291 272 292 <div class="toggle-box"> 273 293 <div class="keys-checkbox"> 274 <span >Notes</span>294 <span class="ctl-label">Notes</span> 275 295 <label class="switch"> 276 296 <input type="checkbox" id="show-notes-toggle" checked> 277 297 <span class="slider round"></span> 278 298 </label> 279 <span >Keys</span>299 <span class="ctl-label">Keys</span> 280 300 <label class="switch"> 281 301 <input type="checkbox" id="show-keys-toggle" checked> … … 286 306 <div class="reverb-box"> 287 307 <div class="keys-checkbox"> 288 <span >Reverb</span>308 <span class="ctl-label">Reverb</span> 289 309 <label for="ptpian_reverb_enable" class="switch"> 290 310 <input type="checkbox" id="ptpian_reverb_enable" name="ptpian_reverb_enable" value="1" <?php checked(get_option('ptpian_reverb_enable'), 1); ?> /> 291 311 <span class="slider round"></span> 292 312 </label> 293 <label for="ptpian_reverb_ir" >IR:</label>313 <label for="ptpian_reverb_ir" class="ctl-label">IR:</label> 294 314 <select id="ptpian_reverb_ir" name="ptpian_reverb_ir"> 295 315 <option value="hall">Hall</option> -
ptpiano/tags/1.2.9/PT_Piano_Setting.php
r3361001 r3364816 3 3 exit; // Exit if accessed directly 4 4 } 5 ?> 6 <?php 5 7 6 if ( ! function_exists( 'get_plugin_data' ) ) { 8 7 require_once ABSPATH . 'wp-admin/includes/plugin.php'; … … 105 104 <input type="color" id="ptpian_bgcolor_control" name="ptpian_bgcolor_control" 106 105 value="<?php echo esc_attr(get_option('ptpian_bgcolor_control')); ?>" /> 107 <label> [ Choose BG color]</label>106 <label> [Background]</label> 108 107 </td> 109 108 <td> 110 <input type="color" id="ptpian_txtcolor_control" name="ptpian_txtcolor_control" 111 value="<?php echo esc_attr(get_option('ptpian_txtcolor_control')); ?>" /> 112 <label> [Choose Text color]</label> 109 <input type="color" id="ptpian_toggle_control" name="ptpian_toggle_control" 110 value="<?php echo esc_attr(get_option('ptpian_toggle_control')); ?>" /> 111 <label> [Toggle Button]</label> 112 </td> 113 <td colspan="2"> 114 <input type="color" id="ptpian_select_control" name="ptpian_select_control" 115 value="<?php echo esc_attr(get_option('ptpian_select_control')); ?>" /> 116 <label> [Select Option]</label> 113 117 </td> 114 118 </tr> … … 156 160 157 161 </table> 162 163 <h3 style="background-color:#252424;padding:10px;color:#eee;">User Options</h3> 164 <table class="form-table"> 165 <tr valign="top"> 166 <th scope="row">Max Recording Duration (seconds)</th> 167 <td> 168 <input type="number" name="ptpian_record_duration" value="<?php echo esc_attr(get_option('ptpian_record_duration', 30)); ?>" min="5" max="300" /> 169 <p class="description">Enter the max duration in seconds for recording (default is 30 seconds).</p> 170 </td> 171 </tr> 172 173 </table> 158 174 159 175 <div class="center-submit"> … … 179 195 </table> 180 196 </div> 181 182 183 184 -
ptpiano/tags/1.2.9/functions.php
r3361001 r3364816 67 67 } 68 68 69 70 69 /** 71 70 * Enqueue frontend scripts and styles … … 73 72 add_action('wp_enqueue_scripts', 'ptpian_enqueue_assets'); 74 73 75 function ptpian_enqueue_assets() { 74 function ptpian_enqueue_assets() { 75 76 if ( is_admin() || !is_singular() ) { 77 return; 78 } 79 80 global $post; 81 82 if ( !has_shortcode( $post->post_content, 'PT-Piano' ) && !has_shortcode( $post->post_content, '[PT-Piano]' ) && !has_shortcode( $post->post_content, 'pt-piano' ) && strpos( $post->post_content, '[PT-Piano' ) !== false) { 83 return; 84 } 85 86 76 87 // CSS 77 88 wp_enqueue_style( … … 93 104 // Set dynamic CSS variables 94 105 $css_vars = ':root {'; 95 $css_vars .= '--ptpian-control-txt-color: ' . esc_attr(get_option('ptpian_txtcolor_control')) . ';'; 106 $css_vars .= '--ptpian-control-bg-color: ' . esc_attr(get_option('ptpian_bgcolor_control')) . ';'; 107 $css_vars .= '--ptpian-control-toggle-color: ' . esc_attr(get_option('ptpian_toggle_control')) . ';'; 108 $css_vars .= '--ptpian-control-select-color: ' . esc_attr(get_option('ptpian_select_control')) . ';'; 96 109 $css_vars .= '--ptpian-txt-piano-color: ' . esc_attr(get_option('ptpian_txtcolor_piano')) . ';'; 97 110 $css_vars .= '--ptpian-mark-bg-color: ' . esc_attr(get_option('ptpian_markcolor_piano')) . ';'; … … 242 255 '1.2.5', 243 256 true 244 ); 257 ); 258 259 // Pass PHP setting to JavaScript for Record duration 260 $record_duration = get_option('ptpian_record_duration', 30); // Default: 30 seconds 261 262 wp_localize_script('ptpian-sound', 'ptPianSettings', array( 263 'recordDuration' => $record_duration 264 )); 245 265 246 266 } … … 262 282 // Color settings 263 283 register_setting('ptpian_settings_group', 'ptpian_bgcolor_control', 'sanitize_hex_color'); 264 register_setting('ptpian_settings_group', 'ptpian_txtcolor_control', 'sanitize_hex_color'); 284 register_setting('ptpian_settings_group', 'ptpian_toggle_control', 'sanitize_hex_color'); 285 register_setting('ptpian_settings_group', 'ptpian_select_control', 'sanitize_hex_color'); 265 286 register_setting('ptpian_settings_group', 'ptpian_txtcolor_piano', 'sanitize_hex_color'); 266 287 register_setting('ptpian_settings_group', 'ptpian_markcolor_piano', 'sanitize_hex_color'); … … 270 291 // NEW: Piano key lights toggle 271 292 register_setting('ptpian_settings_group', 'ptpian_keylights_color', 'sanitize_hex_color'); 293 294 // Recording duration (in seconds) 295 register_setting('ptpian_settings_group', 'ptpian_record_duration', 'absint'); // absint ensures it's a positive integer 296 272 297 } 273 298 -
ptpiano/tags/1.2.9/js/piano.augmented.mark.js
r3356455 r3364816 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMinorElement=document.getElementById('minorchord');const selectMajorElement=document.getElementById('majorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key span');const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function matchNote(span,noteLetter){return(span.textContent===noteLetter||span.textContent===solfegeMap[noteLetter]||span.textContent===indianMap[noteLetter])} 2 selectAugmentedElement.addEventListener('change',(event)=>{const selectedChord=event.target.value;selectMajorElement.selectedIndex=0;selectMinorElement.selectedIndex=0;selectDiminishedElement.selectedIndex=0;selectMajorScaleElement.selectedIndex=0;selectMinorScaleElement.selectedIndex=0;pianoKeys.forEach(span=>span.classList.remove('mark'));if(selectedChord==='Caug'){pianoKeys.forEach(span=>{if(matchNote(span,'C')||matchNote(span,'E')||matchNote(span,'G#')){span.classList.add('mark')}});showchord.value='C AUGMENTED'} 3 if(selectedChord==='C#aug'){pianoKeys.forEach(span=>{if(matchNote(span,'C#')||matchNote(span,'F')||matchNote(span,'A')){span.classList.add('mark')}});showchord.value='C# AUGMENTED'} 4 if(selectedChord==='Daug'){pianoKeys.forEach(span=>{if(matchNote(span,'D')||matchNote(span,'F#')||matchNote(span,'A#')){span.classList.add('mark')}});showchord.value='D AUGMENTED'} 5 if(selectedChord==='D#aug'){pianoKeys.forEach(span=>{if(matchNote(span,'D#')||matchNote(span,'G')||matchNote(span,'B')){span.classList.add('mark')}});showchord.value='D# AUGMENTED'} 6 if(selectedChord==='Eaug'){pianoKeys.forEach(span=>{if(matchNote(span,'E')||matchNote(span,'G#')||matchNote(span,'C')){span.classList.add('mark')}});showchord.value='E AUGMENTED'} 7 if(selectedChord==='Faug'){pianoKeys.forEach(span=>{if(matchNote(span,'F')||matchNote(span,'A')||matchNote(span,'C#')){span.classList.add('mark')}});showchord.value='F AUGMENTED'} 8 if(selectedChord==='F#aug'){pianoKeys.forEach(span=>{if(matchNote(span,'F#')||matchNote(span,'A#')||matchNote(span,'D')){span.classList.add('mark')}});showchord.value='F# AUGMENTED'} 9 if(selectedChord==='Gaug'){pianoKeys.forEach(span=>{if(matchNote(span,'G')||matchNote(span,'B')||matchNote(span,'D#')){span.classList.add('mark')}});showchord.value='G AUGMENTED'} 10 if(selectedChord==='G#aug'){pianoKeys.forEach(span=>{if(matchNote(span,'G#')||matchNote(span,'C')||matchNote(span,'E')){span.classList.add('mark')}});showchord.value='G# AUGMENTED'} 11 if(selectedChord==='Aaug'){pianoKeys.forEach(span=>{if(matchNote(span,'A')||matchNote(span,'C#')||matchNote(span,'F')){span.classList.add('mark')}});showchord.value='A AUGMENTED'} 12 if(selectedChord==='A#aug'){pianoKeys.forEach(span=>{if(matchNote(span,'A#')||matchNote(span,'D')||matchNote(span,'F#')){span.classList.add('mark')}});showchord.value='A# AUGMENTED'} 13 if(selectedChord==='Baug'){pianoKeys.forEach(span=>{if(matchNote(span,'B')||matchNote(span,'D#')||matchNote(span,'G')){span.classList.add('mark')}});showchord.value='B AUGMENTED'}})}) 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMinorElement=document.getElementById('minorchord');const selectMajorElement=document.getElementById('majorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key');const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function matchNote(keyElement,noteLetter){const keyNote=keyElement.dataset.note;if(keyNote===noteLetter){return!0} 2 const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])} 3 const chromaticNotes=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];function getAugmentedChord(rootNote){const rootIndex=chromaticNotes.indexOf(rootNote);if(rootIndex===-1)return[];const majorThird=chromaticNotes[(rootIndex+4)%12];const augmentedFifth=chromaticNotes[(rootIndex+8)%12];return[rootNote,majorThird,augmentedFifth]} 4 selectAugmentedElement.addEventListener('change',(event)=>{const selectedChordValue=event.target.value.toUpperCase();selectMajorElement.selectedIndex=0;selectMinorElement.selectedIndex=0;selectDiminishedElement.selectedIndex=0;selectMajorScaleElement.selectedIndex=0;selectMinorScaleElement.selectedIndex=0;const aguchordNotes=getAugmentedChord(selectedChordValue);pianoKeys.forEach(keyElement=>keyElement.classList.remove('mark'));pianoKeys.forEach(keyElement=>{if(aguchordNotes.some(note=>matchNote(keyElement,note))){keyElement.classList.add('mark')}});if(aguchordNotes.length){showchord.value=`${selectedChordValue} AGU`}else{showchord.value=''}})}) -
ptpiano/tags/1.2.9/js/piano.diminished.mark.js
r3356455 r3364816 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMajorElement=document.getElementById('majorchord');const selectMinorElement=document.getElementById('minorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key span');const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function matchNote(span,noteLetter){return(span.textContent===noteLetter||span.textContent===solfegeMap[noteLetter]||span.textContent===indianMap[noteLetter])} 2 selectDiminishedElement.addEventListener('change',(event)=>{const selectedChord=event.target.value;selectMajorElement.selectedIndex=0;selectMinorElement.selectedIndex=0;selectAugmentedElement.selectedIndex=0;selectMajorScaleElement.selectedIndex=0;selectMinorScaleElement.selectedIndex=0;pianoKeys.forEach(span=>span.classList.remove('mark'));if(selectedChord==='c'){pianoKeys.forEach(span=>{if(matchNote(span,'C')||matchNote(span,'D#')||matchNote(span,'F#')){span.classList.add('mark')}});showchord.value='C DIM'} 3 if(selectedChord==='d'){pianoKeys.forEach(span=>{if(matchNote(span,'D')||matchNote(span,'F')||matchNote(span,'G#')){span.classList.add('mark')}});showchord.value='D DIM'} 4 if(selectedChord==='e'){pianoKeys.forEach(span=>{if(matchNote(span,'E')||matchNote(span,'G')||matchNote(span,'A#')){span.classList.add('mark')}});showchord.value='E DIM'} 5 if(selectedChord==='f'){pianoKeys.forEach(span=>{if(matchNote(span,'F')||matchNote(span,'G#')||matchNote(span,'B')){span.classList.add('mark')}});showchord.value='F DIM'} 6 if(selectedChord==='g'){pianoKeys.forEach(span=>{if(matchNote(span,'G')||matchNote(span,'A#')||matchNote(span,'C#')){span.classList.add('mark')}});showchord.value='G DIM'} 7 if(selectedChord==='a'){pianoKeys.forEach(span=>{if(matchNote(span,'A')||matchNote(span,'C')||matchNote(span,'D#')){span.classList.add('mark')}});showchord.value='A DIM'}})}) 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMajorElement=document.getElementById('majorchord');const selectMinorElement=document.getElementById('minorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key');const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function matchNote(keyElement,noteLetter){const keyNote=keyElement.dataset.note;if(keyNote===noteLetter){return!0} 2 const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])} 3 const chromaticNotes=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"];function getDiminishedChord(rootNote){const rootIndex=chromaticNotes.indexOf(rootNote);if(rootIndex===-1)return[];const minorThird=chromaticNotes[(rootIndex+3)%12];const diminishedFifth=chromaticNotes[(rootIndex+6)%12];return[rootNote,minorThird,diminishedFifth]} 4 selectDiminishedElement.addEventListener('change',(event)=>{const selectedChordValue=event.target.value.toUpperCase();selectMajorElement.selectedIndex=0;selectMinorElement.selectedIndex=0;selectAugmentedElement.selectedIndex=0;selectMajorScaleElement.selectedIndex=0;selectMinorScaleElement.selectedIndex=0;const dimchordNotes=getDiminishedChord(selectedChordValue);pianoKeys.forEach(keyElement=>keyElement.classList.remove('mark'));pianoKeys.forEach(keyElement=>{if(dimchordNotes.some(note=>matchNote(keyElement,note))){keyElement.classList.add('mark')} 5 if(dimchordNotes.length){showchord.value=`${selectedChordValue} DIM`}else{showchord.value=''}})})}) -
ptpiano/tags/1.2.9/js/piano.major.mark.js
r3356455 r3364816 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMajorElement=document.getElementById('majorchord');const selectMinorElement=document.getElementById('minorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key span');const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function matchNote(span,noteLetter){return(span.textContent===noteLetter||span.textContent===solfegeMap[noteLetter]||span.textContent===indianMap[noteLetter])} 2 selectMajorElement.addEventListener('change',(event)=>{const selectedChord=event.target.value;selectMinorElement.selectedIndex=0;selectDiminishedElement.selectedIndex=0;selectAugmentedElement.selectedIndex=0;selectMajorScaleElement.selectedIndex=0;selectMinorScaleElement.selectedIndex=0;pianoKeys.forEach(span=>span.classList.remove('mark'));if(selectedChord==='C'){pianoKeys.forEach(span=>{if(matchNote(span,'C')||matchNote(span,'E')||matchNote(span,'G')){span.classList.add('mark')}});showchord.value='C MAJOR'} 3 if(selectedChord==='D'){pianoKeys.forEach(span=>{if(matchNote(span,'D')||matchNote(span,'F#')||matchNote(span,'A')){span.classList.add('mark')}});showchord.value='D MAJOR'} 4 if(selectedChord==='E'){pianoKeys.forEach(span=>{if(matchNote(span,'E')||matchNote(span,'G#')||matchNote(span,'B')){span.classList.add('mark')}});showchord.value='E MAJOR'} 5 if(selectedChord==='F'){pianoKeys.forEach(span=>{if(matchNote(span,'F')||matchNote(span,'A')||matchNote(span,'C')){span.classList.add('mark')}});showchord.value='F MAJOR'} 6 if(selectedChord==='G'){pianoKeys.forEach(span=>{if(matchNote(span,'G')||matchNote(span,'B')||matchNote(span,'D')){span.classList.add('mark')}});showchord.value='G MAJOR'} 7 if(selectedChord==='A'){pianoKeys.forEach(span=>{if(matchNote(span,'A')||matchNote(span,'C#')||matchNote(span,'E')){span.classList.add('mark')}});showchord.value='A MAJOR'}})}) 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMajorElement=document.getElementById('majorchord');const selectMinorElement=document.getElementById('minorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key');const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function matchNote(keyElement,noteLetter){const keyNote=keyElement.dataset.note;if(keyNote===noteLetter){return!0} 2 const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])} 3 const majorChords={'C':['C','E','G'],'C#':['C#','F','G#'],'D':['D','F#','A'],'D#':['D#','G','A#'],'E':['E','G#','B'],'F':['F','A','C'],'F#':['F#','A#','C#'],'G':['G','B','D'],'G#':['G#','C','D#'],'A':['A','C#','E'],'A#':['A#','D','F'],'B':['B','D#','F#']};selectMajorElement.addEventListener('change',(event)=>{const selectedChord=event.target.value;selectMinorElement.selectedIndex=0;selectDiminishedElement.selectedIndex=0;selectAugmentedElement.selectedIndex=0;selectMajorScaleElement.selectedIndex=0;selectMinorScaleElement.selectedIndex=0;pianoKeys.forEach(keyElement=>keyElement.classList.remove('mark'));if(majorChords[selectedChord]){const notes=majorChords[selectedChord];pianoKeys.forEach(keyElement=>{if(notes.some(note=>matchNote(keyElement,note))){keyElement.classList.add('mark')}});showchord.value=`${selectedChord} MAJOR`}})}) -
ptpiano/tags/1.2.9/js/piano.major.scale.js
r3356455 r3364816 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMinorElement=document.getElementById('minorchord');const selectMajorElement=document.getElementById('majorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key span');const majorScaleIntervals=[2,2,1,2,2,2,1];const allNotes=['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'];const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function getMajorScale(rootNote){let scale=[];let startIndex=allNotes.indexOf(rootNote);if(startIndex===-1)return scale;scale.push(allNotes[startIndex]);let currentIndex=startIndex;for(let i=0;i<majorScaleIntervals.length;i++){currentIndex=(currentIndex+majorScaleIntervals[i])%allNotes.length;scale.push(allNotes[currentIndex])} 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMinorElement=document.getElementById('minorchord');const selectMajorElement=document.getElementById('majorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key');const majorScaleIntervals=[2,2,1,2,2,2,1];const allNotes=['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'];const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function matchNote(keyElement,noteLetter){const keyNote=keyElement.dataset.note;if(keyNote===noteLetter){return!0} 2 const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])} 3 function getMajorScale(rootNote){let scale=[];let startIndex=allNotes.indexOf(rootNote);if(startIndex===-1)return scale;scale.push(allNotes[startIndex]);let currentIndex=startIndex;for(let i=0;i<majorScaleIntervals.length;i++){currentIndex=(currentIndex+majorScaleIntervals[i])%allNotes.length;scale.push(allNotes[currentIndex])} 2 4 return scale} 3 selectMajorScaleElement.addEventListener('change',(event)=>{const selectedScale=event.target.value;const scaleNotes=getMajorScale(selectedScale);selectMajorElement.selectedIndex=0;selectMinorElement.selectedIndex=0;selectDiminishedElement.selectedIndex=0;selectAugmentedElement.selectedIndex=0;selectMinorScaleElement.selectedIndex=0;pianoKeys.forEach(span=>span.classList.remove('mark'));if(scaleNotes.length>0){pianoKeys.forEach(span=>{for(let note of scaleNotes){if(span.textContent===note||span.textContent===solfegeMap[note]||span.textContent===indianMap[note]){span.classList.add('mark')}}});showchord.value=`${selectedScale} MAJOR SCALE`}else{showchord.value=''} 4 const firstKey=document.querySelector('.piano-keys .key');if(firstKey){firstKey.focus();firstKey.scrollIntoView({behavior:'smooth',block:'center'})}})}) 5 const commonMajorProgressions={'C':['C','G','Am','F'],'C#':['C#','G#','A#m','F#'],'D':['D','A','Bm','G'],'D#':['D#','A#','Cm','G#'],'E':['E','B','C#m','A'],'F':['F','C','Dm','Bb'],'F#':['F#','C#','D#m','B'],'G':['G','D','Em','C'],'G#':['G#','D#','Fm','C#'],'A':['A','E','F#m','D'],'A#':['A#','F','Gm','D#'],'B':['B','F#','G#m','E'],};selectMajorScaleElement.addEventListener('change',(event)=>{const selectedScale=event.target.value;const scaleNotes=getMajorScale(selectedScale);selectMajorElement.selectedIndex=0;selectMinorElement.selectedIndex=0;selectDiminishedElement.selectedIndex=0;selectAugmentedElement.selectedIndex=0;selectMinorScaleElement.selectedIndex=0;pianoKeys.forEach(keyElement=>keyElement.classList.remove('mark'));pianoKeys.forEach(keyElement=>{if(scaleNotes.some(note=>matchNote(keyElement,note))){keyElement.classList.add('mark')} 6 if(scaleNotes.length){showchord.value=`${selectedScale} MAJOR SCALE`}else{showchord.value=''}});const firstKey=document.querySelector('.piano-keys .key');if(firstKey){firstKey.focus();firstKey.scrollIntoView({behavior:'smooth',block:'center'})} 7 const progressionEl=document.getElementById('common-progression');if(commonMajorProgressions[selectedScale]){const progression=commonMajorProgressions[selectedScale].join(' → ');progressionEl.textContent=`Common Progression: ${progression}`}else{progressionEl.textContent=''}})}) -
ptpiano/tags/1.2.9/js/piano.minor.mark.js
r3356455 r3364816 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMinorElement=document.getElementById('minorchord');const selectMajorElement=document.getElementById('majorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key span');const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function matchNote(span,noteLetter){return(span.textContent===noteLetter||span.textContent===solfegeMap[noteLetter]||span.textContent===indianMap[noteLetter])} 2 selectMinorElement.addEventListener('change',(event)=>{const selectedChord=event.target.value;selectMajorElement.selectedIndex=0;selectDiminishedElement.selectedIndex=0;selectAugmentedElement.selectedIndex=0;selectMajorScaleElement.selectedIndex=0;selectMinorScaleElement.selectedIndex=0;pianoKeys.forEach(span=>span.classList.remove('mark'));if(selectedChord==='c'){pianoKeys.forEach(span=>{if(matchNote(span,'C')||matchNote(span,'D#')||matchNote(span,'G')){span.classList.add('mark')}});showchord.value='C MINOR'} 3 if(selectedChord==='d'){pianoKeys.forEach(span=>{if(matchNote(span,'D')||matchNote(span,'F')||matchNote(span,'A')){span.classList.add('mark')}});showchord.value='D MINOR'} 4 if(selectedChord==='e'){pianoKeys.forEach(span=>{if(matchNote(span,'E')||matchNote(span,'G')||matchNote(span,'B')){span.classList.add('mark')}});showchord.value='E MINOR'} 5 if(selectedChord==='f'){pianoKeys.forEach(span=>{if(matchNote(span,'F')||matchNote(span,'G#')||matchNote(span,'C')){span.classList.add('mark')}});showchord.value='F MINOR'} 6 if(selectedChord==='g'){pianoKeys.forEach(span=>{if(matchNote(span,'G')||matchNote(span,'A#')||matchNote(span,'D')){span.classList.add('mark')}});showchord.value='G MINOR'} 7 if(selectedChord==='a'){pianoKeys.forEach(span=>{if(matchNote(span,'A')||matchNote(span,'C')||matchNote(span,'E')){span.classList.add('mark')}});showchord.value='A MINOR'}})}) 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMinorElement=document.getElementById('minorchord');const selectMajorElement=document.getElementById('majorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key');const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function matchNote(keyElement,noteLetter){const keyNote=keyElement.dataset.note;if(keyNote===noteLetter){return!0} 2 const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])} 3 const minorChords={'C':['C','D#','G'],'C#':['C#','E','G#'],'D':['D','F','A'],'D#':['D#','F#','A#'],'E':['E','G','B'],'F':['F','G#','C'],'F#':['F#','A','C#'],'G':['G','A#','D'],'G#':['G#','B','D#'],'A':['A','C','E'],'A#':['A#','C#','F'],'B':['B','D','F#']};selectMinorElement.addEventListener('change',(event)=>{const selectedChord=event.target.value;selectMajorElement.selectedIndex=0;selectDiminishedElement.selectedIndex=0;selectAugmentedElement.selectedIndex=0;selectMajorScaleElement.selectedIndex=0;selectMinorScaleElement.selectedIndex=0;pianoKeys.forEach(keyElement=>keyElement.classList.remove('mark'));if(minorChords[selectedChord]){const notes=minorChords[selectedChord];pianoKeys.forEach(keyElement=>{if(notes.some(note=>matchNote(keyElement,note))){keyElement.classList.add('mark')}});showchord.value=`${selectedChord} MINOR`}})}) -
ptpiano/tags/1.2.9/js/piano.minor.scale.js
r3356455 r3364816 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMinorElement=document.getElementById('minorchord');const selectMajorElement=document.getElementById('majorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key span');const minorScaleIntervals=[2,1,2,2,1,2,2];const allNotes=['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'];const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function getMinorScale(rootNote){let scale=[];let startIndex=allNotes.indexOf(rootNote);if(startIndex===-1)return scale;scale.push(allNotes[startIndex]);let currentIndex=startIndex;for(let i=0;i<minorScaleIntervals.length;i++){currentIndex=(currentIndex+minorScaleIntervals[i])%allNotes.length;scale.push(allNotes[currentIndex])} 1 document.addEventListener('DOMContentLoaded',()=>{const selectMajorScaleElement=document.getElementById('majorscale');const selectMinorScaleElement=document.getElementById('minorscale');const selectMinorElement=document.getElementById('minorchord');const selectMajorElement=document.getElementById('majorchord');const selectDiminishedElement=document.getElementById('diminishedchord');const selectAugmentedElement=document.getElementById('augmentedchord');var showchord=document.getElementById('showchord');const pianoKeys=document.querySelectorAll('.piano-keys .key');const minorScaleIntervals=[2,1,2,2,1,2,2];const allNotes=['C','C#','D','D#','E','F','F#','G','G#','A','A#','B'];const solfegeMap={'C':'Do','C#':'Do#','D':'Re','D#':'Re#','E':'Mi','F':'Fa','F#':'Fa#','G':'So','G#':'So#','A':'La','A#':'La#','B':'Ti'};const indianMap={'C':'सा','C#':'रे♭','D':'रे','D#':'गा♭','E':'गा','F':'मा','F#':'मा#','G':'प','G#':'धा♭','A':'धा','A#':'नि♭','B':'नि'};function matchNote(keyElement,noteLetter){const keyNote=keyElement.dataset.note;if(keyNote===noteLetter){return!0} 2 const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])} 3 function getMinorScale(rootNote){let scale=[];let startIndex=allNotes.indexOf(rootNote);if(startIndex===-1)return scale;scale.push(allNotes[startIndex]);let currentIndex=startIndex;for(let i=0;i<minorScaleIntervals.length;i++){currentIndex=(currentIndex+minorScaleIntervals[i])%allNotes.length;scale.push(allNotes[currentIndex])} 2 4 return scale} 3 selectMinorScaleElement.addEventListener('change',(event)=>{const selectedScale=event.target.value;const scaleNotes=getMinorScale(selectedScale);selectMajorElement.selectedIndex=0;selectMinorElement.selectedIndex=0;selectDiminishedElement.selectedIndex=0;selectAugmentedElement.selectedIndex=0;selectMajorScaleElement.selectedIndex=0;pianoKeys.forEach(span=>span.classList.remove('mark'));if(scaleNotes.length>0){pianoKeys.forEach(span=>{for(let note of scaleNotes){if(span.textContent===note||span.textContent===solfegeMap[note]||span.textContent===indianMap[note]){span.classList.add('mark')}}});showchord.value=`${selectedScale} MINOR SCALE`}else{showchord.value=''} 4 const firstKey=document.querySelector('.piano-keys .key');if(firstKey){firstKey.focus();firstKey.scrollIntoView({behavior:'smooth',block:'center'})}})}) 5 const commonMinorProgressions={'A':['Am','F','C','G'],'A#':['A#m','G#','D#','A#'],'B':['Bm','G','D','A'],'C':['Cm','Ab','Eb','Bb'],'C#':['C#m','A','E','B'],'D':['Dm','Bb','F','C'],'D#':['D#m','B','F#','C#'],'E':['Em','C','G','D'],'F':['Fm','Db','Ab','Eb'],'F#':['F#m','D','A','E'],'G':['Gm','Eb','Bb','F'],'G#':['G#m','E','B','F#'],};selectMinorScaleElement.addEventListener('change',(event)=>{const selectedScale=event.target.value;const scaleNotes=getMinorScale(selectedScale);selectMajorElement.selectedIndex=0;selectMinorElement.selectedIndex=0;selectDiminishedElement.selectedIndex=0;selectAugmentedElement.selectedIndex=0;selectMajorScaleElement.selectedIndex=0;pianoKeys.forEach(keyElement=>keyElement.classList.remove('mark'));pianoKeys.forEach(keyElement=>{if(scaleNotes.some(note=>matchNote(keyElement,note))){keyElement.classList.add('mark')} 6 if(scaleNotes.length){showchord.value=`${selectedScale} MINOR SCALE`}else{showchord.value=''}});const firstKey=document.querySelector('.piano-keys .key');if(firstKey){firstKey.focus();firstKey.scrollIntoView({behavior:'smooth',block:'center'})} 7 const progressionEl=document.getElementById('common-progression');if(commonMinorProgressions[selectedScale]){const progression=commonMinorProgressions[selectedScale].join(' → ');progressionEl.textContent=`Common Progression: ${progression}`}else{progressionEl.textContent=''}})}) -
ptpiano/tags/1.2.9/js/piano.sound.js
r3361001 r3364816 1 document.addEventListener('DOMContentLoaded',()=>{const pianoKeys=document.querySelectorAll(".piano-keys .key"),volumeSlider=document.querySelector(".volume-slider input"),notesCheckbox=document.querySelector("#show-notes-toggle"),keysCheckbox=document.querySelector("#show-keys-toggle"),equalizerCanvas=document.getElementById("equalizer"),canvasCtx=equalizerCanvas.getContext("2d");const noteDisplay=document.getElementById("played-notes");const clearBtn=document.getElementById("clearBtn");const pianoRecorder=new PianoRecorder();const recordBtn=document.getElementById("recordBtn");const playBtn=document.getElementById("playBtn");const playIcon=playBtn.querySelector(".play-icon");const playLabel=playBtn.querySelector(".play-label");const audioContext=new(window.AudioContext||window.webkitAudioContext)();const analyser=audioContext.createAnalyser();analyser.fftSize=128;const bufferLength=20;const dataArray=new Uint8Array(64);let allKeys=[],audioCache={},audioSources={},isDrawing=!1;const pluginBaseUrl=ptpianData.pluginsUrl+'/ptpiano/tunes/';const enablePianoBtn=document.getElementById('enable-piano-btn');const enableMidiDownloadBtn=document.getElementById('mididownloadBtn');enablePianoBtn.classList.add('disabled');enablePianoBtn.textContent='Off';function startAudioContext(){const currentState=enablePianoBtn.textContent;if(currentState==='Off'){audioContext.resume().then(()=>{console.log("AudioContext resumed");enablePianoBtn.classList.remove('disabled');enablePianoBtn.classList.add('enabled');enablePianoBtn.textContent='On';connectMIDIInputs()}).catch(err=>{console.error("Failed to resume AudioContext:",err)})}else if(currentState==='On'){audioContext.suspend().then(()=>{console.log("AudioContext suspended");enablePianoBtn.classList.remove('enabled');enablePianoBtn.classList.add('disabled');enablePianoBtn.textContent='Off';disconnectMIDIInputs()}).catch(err=>{console.error("Failed to suspend AudioContext:",err)})}}1 document.addEventListener('DOMContentLoaded',()=>{const pianoKeys=document.querySelectorAll(".piano-keys .key"),volumeSlider=document.querySelector(".volume-slider input"),notesCheckbox=document.querySelector("#show-notes-toggle"),keysCheckbox=document.querySelector("#show-keys-toggle"),equalizerCanvas=document.getElementById("equalizer"),canvasCtx=equalizerCanvas.getContext("2d");const noteDisplay=document.getElementById("played-notes");const clearBtn=document.getElementById("clearBtn");const pianoRecorder=new PianoRecorder();const recordBtn=document.getElementById("recordBtn");const playBtn=document.getElementById("playBtn");const playIcon=playBtn.querySelector(".play-icon");const playLabel=playBtn.querySelector(".play-label");const popup=document.getElementById('recordLimitPopup');const closeBtn=document.getElementById("closePopupBtn");const audioContext=new(window.AudioContext||window.webkitAudioContext)();const analyser=audioContext.createAnalyser();analyser.fftSize=128;const bufferLength=20;const dataArray=new Uint8Array(64);let allKeys=[],audioCache={},audioSources={},isDrawing=!1;const pluginBaseUrl=ptpianData.pluginsUrl+'/ptpiano/tunes/';const enablePianoBtn=document.getElementById('enable-piano-btn');const enableMidiDownloadBtn=document.getElementById('mididownloadBtn');enablePianoBtn.classList.add('disabled');enablePianoBtn.textContent='Off';function startAudioContext(){const currentState=enablePianoBtn.textContent;if(currentState==='Off'){audioContext.resume().then(()=>{console.log("AudioContext resumed");enablePianoBtn.classList.remove('disabled');enablePianoBtn.classList.add('enabled');enablePianoBtn.textContent='On';connectMIDIInputs()}).catch(err=>{console.error("Failed to resume AudioContext:",err)})}else if(currentState==='On'){audioContext.suspend().then(()=>{console.log("AudioContext suspended");enablePianoBtn.classList.remove('enabled');enablePianoBtn.classList.add('disabled');enablePianoBtn.textContent='Off';disconnectMIDIInputs()}).catch(err=>{console.error("Failed to suspend AudioContext:",err)})}} 2 2 window.startAudioContext=startAudioContext;enablePianoBtn.addEventListener('click',()=>{startAudioContext()});if(window.ptpReverb){ptpReverb.initReverb(audioContext);ptpReverb.loadReverb(ptpianReverbData?.irs?.hall)} 3 3 pianoKeys.forEach(key=>{const keyData=key.dataset.key;const audio=new Audio(pluginBaseUrl+`${keyData}.wav`);audio.preload='auto';audioCache[keyData]=audio});const playTune=async(key)=>{try{await audioContext.resume();const audio=audioCache[key].cloneNode();const source=audioContext.createMediaElementSource(audio);if(window.ptpReverb){ptpReverb.applyReverb(source,analyser)}else{source.connect(analyser)} 4 analyser.connect(audioContext.destination);audio.volume=volumeSlider.value;audio.play();audioSources[key]=source;audio.onended=()=>{source.disconnect();delete audioSources[key]};const clickedKey=document.querySelector(`[data-key="${key}"]`);if(clickedKey){clickedKey.classList.add("active");setTimeout(()=>clickedKey.classList.remove("active"),150);const noteLabel=clickedKey.querySelector(".note-label")?.textContent||clickedKey.dataset.note;const noteSpan=document.createElement("span");noteSpan.textContent=noteLabel;noteSpan.classList.add("played-note");noteDisplay.appendChild(noteSpan);noteDisplay.scrollLeft=noteDisplay.scrollWidth;if(noteDisplay.childNodes.length>1 20){noteDisplay.removeChild(noteDisplay.firstChild)}4 analyser.connect(audioContext.destination);audio.volume=volumeSlider.value;audio.play();audioSources[key]=source;audio.onended=()=>{source.disconnect();delete audioSources[key]};const clickedKey=document.querySelector(`[data-key="${key}"]`);if(clickedKey){clickedKey.classList.add("active");setTimeout(()=>clickedKey.classList.remove("active"),150);const noteLabel=clickedKey.querySelector(".note-label")?.textContent||clickedKey.dataset.note;const noteSpan=document.createElement("span");noteSpan.textContent=noteLabel;noteSpan.classList.add("played-note");noteDisplay.appendChild(noteSpan);noteDisplay.scrollLeft=noteDisplay.scrollWidth;if(noteDisplay.childNodes.length>160){noteDisplay.removeChild(noteDisplay.firstChild)} 5 5 const note=clickedKey?.dataset.note||key;pianoRecorder.recordNote(key,note)} 6 6 if(!isDrawing)drawEqualizer();}catch(err){console.error("Error playing sound:",err)}};const drawEqualizer=()=>{isDrawing=!0;const renderFrame=()=>{analyser.getByteFrequencyData(dataArray);canvasCtx.clearRect(0,0,equalizerCanvas.width,equalizerCanvas.height);const canvasWidth=equalizerCanvas.width;const canvasHeight=equalizerCanvas.height;const barCount=bufferLength;const barGap=2;const totalGapWidth=(barCount-1)*barGap;const barWidth=(canvasWidth-totalGapWidth)/barCount;let x=0;for(let i=0;i<barCount;i++){const barHeight=dataArray[i]/2;canvasCtx.fillStyle=`rgb(${barHeight + 100}, 50, 200)`;canvasCtx.fillRect(x,canvasHeight-barHeight,barWidth,barHeight);x+=barWidth+barGap} 7 requestAnimationFrame(renderFrame)};renderFrame()};pianoKeys.forEach(key=>{allKeys.push(key.dataset.key);key.addEventListener("click",()=>{playTune(key.dataset.key);key.classList.add("glow");setTimeout(()=>{key.classList.remove("glow")},500)})});volumeSlider.addEventListener("input",()=>{});notesCheckbox.addEventListener("click",()=>{pianoKeys.forEach(key=>{const noteLabel=key.querySelector(".note-label");if(noteLabel)noteLabel.classList.toggle("hide");})});keysCheckbox.addEventListener("click",()=>{pianoKeys.forEach(key=>{const keyLabel=key.querySelector(".key-label");if(keyLabel)keyLabel.classList.toggle("hide");})});document.addEventListener("keydown",e=>{const pressedKey=e.key.toLowerCase();if(allKeys.includes(pressedKey)){playTune(pressedKey);const keyElement=document.querySelector(`.key[data-key="${pressedKey}"]`);if(keyElement){keyElement.classList.add("glow");setTimeout(()=>{keyElement.classList.remove("glow")},500)}}});recordBtn.addEventListener("click",()=>{if(!pianoRecorder.isRecording){noteDisplay.innerHTML="";pianoRecorder.startRecording();recordBtn.classList.add('active');playBtn.disabled=!0;clearBtn.disabled=!0}else{pianoRecorder.stopRecording();recordBtn.classList.remove('active');playBtn.disabled=!1;clearBtn.disabled=!1}});let isPlaying=!1;noteDisplay.innerHTML="";playBtn.addEventListener("click",()=>{if(!isPlaying){if(noteDisplay.innerHTML!==""){isPlaying=!0;playBtn.classList.add('active');recordBtn.disabled=!0;clearBtn.disabled=!0;noteDisplay.innerHTML="";pianoRecorder.playRecording(playTune,()=>{isPlaying=!1;playBtn.classList.remove('active');recordBtn.disabled=!1;clearBtn.disabled=!1})}else{noteDisplay.innerHTML="No notes to play";playBtn.classList.remove('active');playBtn.disabled=!0}}else{if(isPlaying){isPlaying=!1;playBtn.classList.remove('active');recordBtn.disabled=!1;clearBtn.disabled=!1;pianoRecorder.stopPlayback()}}});clearBtn.addEventListener("click",()=>{noteDisplay.innerHTML="";if(pianoRecorder.isRecording){pianoRecorder.stopRecording();recordBtn.classList.toggle('active');playBtn.disabled=!1} 8 if(isPlaying){isPlaying=!1;pianoRecorder.stopPlayback();playBtn.classList.remove('active');recordBtn.disabled=!1} 9 for(const key in audioSources){try{audioSources[key].disconnect();delete audioSources[key]}catch(e){console.warn(`Error disconnecting source for key ${key}:`,e)}}});document.getElementById("mididownloadBtn").addEventListener("click",()=>{pianoRecorder.downloadMidi()});window.playTune=playTune}) 7 requestAnimationFrame(renderFrame)};renderFrame()};pianoKeys.forEach(key=>{allKeys.push(key.dataset.key);key.addEventListener("click",()=>{playTune(key.dataset.key);key.classList.add("glow");setTimeout(()=>{key.classList.remove("glow")},500)})});volumeSlider.addEventListener("input",()=>{});notesCheckbox.addEventListener("click",()=>{pianoKeys.forEach(key=>{const noteLabel=key.querySelector(".note-label");if(noteLabel)noteLabel.classList.toggle("hide");})});keysCheckbox.addEventListener("click",()=>{pianoKeys.forEach(key=>{const keyLabel=key.querySelector(".key-label");if(keyLabel)keyLabel.classList.toggle("hide");})});document.addEventListener("keydown",e=>{const pressedKey=e.key.toLowerCase();if(allKeys.includes(pressedKey)){playTune(pressedKey);const keyElement=document.querySelector(`.key[data-key="${pressedKey}"]`);if(keyElement){keyElement.classList.add("glow");setTimeout(()=>{keyElement.classList.remove("glow")},500)}}});recordBtn.addEventListener("click",()=>{if(!pianoRecorder.isRecording){noteDisplay.innerHTML="";pianoRecorder.startRecording();recordBtn.classList.add('active');playBtn.disabled=!0;clearBtn.disabled=!0;const maxDuration=(typeof ptPianSettings!=='undefined'&&ptPianSettings.recordDuration)?parseInt(ptPianSettings.recordDuration,10)*1000:30000;setTimeout(()=>{if(pianoRecorder.isRecording){pianoRecorder.stopRecording();recordBtn.classList.remove('active');playBtn.disabled=!1;clearBtn.disabled=!1;popup.style.display='flex'}},maxDuration);if(closeBtn){closeBtn.addEventListener("click",()=>{popup.style.display="none";if(pianoRecorder.recordedNotes.length>0){isPlaying=!0;playBtn.classList.add('active');recordBtn.disabled=!0;clearBtn.disabled=!0;noteDisplay.innerHTML="";pianoRecorder.playRecording(playTune,()=>{isPlaying=!1;playBtn.classList.remove('active');recordBtn.disabled=!1;clearBtn.disabled=!1})}})}}else{pianoRecorder.stopRecording();recordBtn.classList.remove('active');playBtn.disabled=!1;clearBtn.disabled=!1}});let isPlaying=!1;noteDisplay.innerHTML="";playBtn.addEventListener("click",()=>{if(!isPlaying){if(pianoRecorder.recordedNotes.length>0){isPlaying=!0;playBtn.classList.add('active');recordBtn.disabled=!0;clearBtn.disabled=!0;noteDisplay.innerHTML="";pianoRecorder.playRecording(playTune,()=>{isPlaying=!1;playBtn.classList.remove('active');recordBtn.disabled=!1;clearBtn.disabled=!1})}else{noteDisplay.innerHTML="Record to play";playBtn.classList.remove('active');playBtn.disabled=!0}}else{if(isPlaying){isPlaying=!1;playBtn.classList.remove('active');recordBtn.disabled=!1;clearBtn.disabled=!1;pianoRecorder.stopPlayback()}}});clearBtn.addEventListener("click",()=>{if(!isPlaying||!pianoRecorder.isRecording){noteDisplay.innerHTML="";for(const key in audioSources){try{audioSources[key].disconnect();delete audioSources[key]}catch(e){console.warn(`Error disconnecting source for key ${key}:`,e)}}}});document.getElementById("mididownloadBtn").addEventListener("click",()=>{pianoRecorder.downloadMidi()});window.playTune=playTune}) -
ptpiano/tags/1.2.9/ptpiano.php
r3361001 r3364816 1 <?php2 if ( ! defined( 'ABSPATH' ) ) {3 exit; // Exit if accessed directly4 }5 ?>6 1 <?php 7 2 /** 8 3 * Plugin Name: PTPiano 9 4 * Description: An interactive, browser-based piano plugin for learning and exploring chords and notes. 10 * Version: 1.2. 85 * Version: 1.2.9 11 6 * Author: santechidea 12 7 * Author URI: https://wordpress.santechidea.net … … 15 10 * Text Domain: ptpiano 16 11 */ 12 13 if ( ! defined( 'ABSPATH' ) ) { 14 exit; // Exit if accessed directly 15 } 17 16 18 17 // Define constants with unique prefix -
ptpiano/tags/1.2.9/readme.txt
r3361001 r3364816 5 5 Tested up to: 6.8 6 6 Requires PHP: 8.0 7 Stable tag: 1.2. 87 Stable tag: 1.2.9 8 8 License: GPLv2 or later 9 9 License URI: https://www.gnu.org/licenses/gpl-2.0.html … … 50 50 51 51 == Changelog == 52 53 = 1.2.9 = 54 55 * Added complete note mappings for major, minor, diminished, and augmented chords. 56 57 * Introduced a new setting to allow users to control their recording duration from the Settings page. 58 59 * Enhanced the visual design of piano keys, including full key highlights when a chord or scale is selected. 60 61 * Optimized script loading so that it only runs on the plugin page, preventing unnecessary execution on other pages. 62 63 * Fixed various internal bugs to improve overall performance and stability. 52 64 53 65 = 1.2.8 = … … 163 175 First stable release of PT Piano. 164 176 * Initial release with full keyboard functionality 165 166 == Arbitrary section ==167 168 You can use this section to describe advanced usage, developer notes, or links to documentation.169 -
ptpiano/tags/1.2.9/styles/frontend-dynamic.css
r3361001 r3364816 1 :root{--ptpian-control-txt-color:#ffffff;--ptpian-txt-piano-color:#ffffff;--ptpian-mark-bg-color:#000000;--ptpian-mark-text-color:#ffffff;--ptpian-theme-bg:url(../theme/default-theme.png);--ptpian-keylight-color:#fff}.control span{color:var(--ptpian-control-txt-color)}.piano-keys .key .note-label{color:var(--ptpian-txt-piano-color)}.mark{background-color:var(--ptpian-mark-bg-color);color:var(--ptpian-mark-text-color)}.columnboxpiano{background-image:var(--ptpian-theme-bg);background-repeat:repeat}.hidden{display:none!important}.key.glow{box-shadow:0 5px 25px 8px var(--ptpian-keylight-color);border-radius:6px} 1 :root{--ptpian-control-toggle-color:#000;--ptpian-control-select-color:#000;--ptpian-txt-piano-color:#555555;--ptpian-mark-bg-color:#00FFFF;--ptpian-mark-text-color:#555555;--ptpian-theme-bg:url('../theme/default-theme.png');--ptpian-keylight-color:#00FFFF;--ptpian-mark-bg-color:#ffe082}.ptpiano-wrapper{background:linear-gradient(to bottom,rgba(0,0,0,0.8)42%,var(--ptpian-control-bg-color));background-blend-mode:overlay}.switch input:checked+.slider{background-color:var(--ptpian-control-toggle-color)}.chord-option select{color:var(--ptpian-control-select-color)}.reverb-box select{color:var(--ptpian-control-select-color)} 2 select option{color:var(--ptpian-control-select-color)}.piano-keys .key.note-label{color:var(--ptpian-txt-piano-color)}.piano-keys .key.white{position:relative;background:linear-gradient(to bottom,#fff,#eee);overflow:hidden}.piano-keys .key.white.mark::before{content:"";position:absolute;inset:0;background:linear-gradient(to bottom,var(--ptpian-mark-bg-color),#000);opacity:0.7;z-index:1;pointer-events:none}.piano-keys .key.black{position:relative;background:linear-gradient(to bottom,#333,#000);overflow:hidden;z-index:2}.piano-keys .key.black.mark::before{content:"";position:absolute;inset:0;background:linear-gradient(to bottom,var(--ptpian-mark-bg-color),#000);opacity:0.4;z-index:3;pointer-events:none}.columnboxpiano{background-image:var(--ptpian-theme-bg);background-repeat:repeat}.hidden{display:none!important}.key.glow{box-shadow:0 5px 25px 8px var(--ptpian-keylight-color);border-radius:6px} -
ptpiano/tags/1.2.9/styles/piano.css
r3361001 r3364816 1 *{margin:0;padding:0;box-sizing:border-box;font-family:sans-serif}. wrapper{padding:15px 35px 15px 35px;border-radius:20px}.wrapper header{display:flex;color:#B2B2B2;align-items:center;justify-content:space-between;padding:15px}.columnbox{display:grid;grid-template-columns:1fr 4fr 1fr;align-items:center;padding:15px 20px;background-color:#252424;border-radius:20px;width:100%}.col-left{display:flex;flex-direction:column}.piano-header{display:flex;align-items:center;gap:10px}.piano-title h2{margin:0;font-size:21px;font-weight:700;color:#555;font-style:italic;font-family:fantasy}.piano-title .version{font-size:18px;color:#555;margin-left:6px;font-family:cursive}.piano-speaker img{margin-top:5px;max-width:150px}.col-center{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:15px}.equalizer-notes-row{display:flex;flex-direction:row;gap:5px;align-items:center;justify-content:center;width:100%;max-width:100%}.note-display-wrapper{background:#1e1e1e;border-radius:12px;padding:10px 15px;min-height:100px;box-shadow:inset 0 0 6px rgb(0 0 0 / .6);border:1px solid #444;display:flex;align-items:center;justify-content:flex-start;flex-grow:1;width:90%;min-height:125px;max-width:100%;overflow-x:hidden}.equalizer-wrapper{background:#1e1e1e;border-radius:12px;padding:10px 15px;box-shadow:inset 0 0 6px rgb(0 0 0 / .6);border:1px solid #444;display:flex;align-items:center;justify-content:center;width:220px;min-height:100px}.note-display{width:100%;height:100px;overflow-x:hidden;overflow-y:auto;white-space:normal;padding:8px 12px;background:#121212;border-radius:8px;color:#eee;font-family:monospace,monospace;font-size:16px;user-select:text;box-sizing:border-box}#played-notes{display:flex;flex-wrap:wrap;align-items:flex-start;overflow-x:hidden;overflow-y:auto;background:#121212;border-radius:8px;padding:8px 12px;height:100px;color:#eee;font-family:monospace;font-size:16px;box-sizing:border-box;gap:6px 8px;line-height:1}#played-notes::-webkit-scrollbar{width:10px}#played-notes::-webkit-scrollbar-track{background:#1e1e1e;border-radius:10px}#played-notes::-webkit-scrollbar-thumb{background:linear-gradient(135deg,#ff6ec4,#7873f5);border-radius:10px;border:2px solid #1e1e1e}#played-notes::-webkit-scrollbar-thumb:hover{background:linear-gradient(135deg,#ff8ec4,#9893f5)}.played-note{display:inline-block;padding:2px 6px;background-color:#2a2a2a;border-radius:4px;white-space:nowrap;margin:0;line-height:1}#equalizer{width:220px}.col-right{display:flex;flex-direction:column;padding:0 0 0 15px}#enable-piano-btn{padding:10px 20px;font-size:16px;color:#fff;border:none;border-radius:4px;cursor:pointer;transition:background-color 0.3s ease,box-shadow 0.3s ease}#enable-piano-btn.enabled{background-color:green;color:#fff;box-shadow:0 0 10px 2px rgb(0 255 0 / .8)}#enable-piano-btn.disabled{background-color:red;color:#fff;box-shadow:none}.vol-notes-row{display:flex;flex-wrap:wrap;align-items:center;gap:15px;margin-top:10px;justify-content:center}.volume-slider{display:flex;align-items:center;background:#555;padding:10px 15px;border-radius:40px;width:320px;gap:12px;font-family:sans-serif;color:#00fdfd}.volume-icon{font-size:20px}#volumeControl{-webkit-appearance:none;appearance:none;width:100%;height:6px;background:#00fdfd;border-radius:3px;cursor:pointer}#volumeControl::-webkit-slider-thumb{-webkit-appearance:none;width:28px;height:28px;background:#000;border:4px solid #00fdfd;border-radius:50%;margin-top:-2px;transition:background 0.3s}#volumeControl::-moz-range-thumb{width:14px;height:14px;background:#000;border:4px solid #00fdfd;border-radius:50%}#volumeControl::-moz-range-track{height:6px;background:#00fdfd;border-radius:3px}#volumeRValue{font-weight:700;min-width:32px;text-align:right;color:gold}.button-box{display:flex;gap:10px;background:#555;padding:10px 20px;border-radius:40px;font-family:sans-serif}.dotted-btn{position:relative;width:100px;padding:10px 16px;height:auto;background-color:#2b2b2b;border:none;border-radius:8px;box-shadow:inset -4px 4px 8px #1a1a1a,inset 4px -4px 8px #3a3a3a;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform 0.2s}.dotted-btn:hover{transform:scale(.95);box-shadow:inset 3px 3px 6px rgb(0 0 0 / .6),inset -3px -3px 6px rgb(255 255 255 / .05);transition:transform 0.2s,box-shadow 0.2s}.dotted-btn::before{content:"";position:absolute;width:80%;height:80%;background-image:radial-gradient(#000 2px,transparent 0);background-size:8px 8px;top:50%;left:50%;transform:translate(-50%,-50%);opacity:.3;pointer-events:none;border-radius:6px}.button-content{display:flex;align-items:center;gap:8px;z-index:1;background-color:#252525}.indicator{width:12px;height:12px;background-color:#ff2e2e;border-radius:50%;transition:box-shadow 0.3s ease,opacity 0.3s ease;opacity:.5}.indicatorp{width:12px;height:12px;background-color:#00FDFD;border-radius:50%;transition:box-shadow 0.3s ease,opacity 0.3s ease;opacity:.5}.dotted-btn.active .indicator{box-shadow:0 0 12px 4px #ff2e2e;opacity:1}.dotted-btn.active .indicatorp{box-shadow:0 0 12px 4px #00FDFD;opacity:1}.btn-label{font-size:18px;color:#555;background-color:#fff0}#clearBtn{transition:background-color 0.2s ease,color 0.2s ease,opacity 0.2s ease}.chord-group{display:inline-block;text-align:center;position:relative;margin:0 20px}.chord-label{position:absolute;top:-18px;left:50%;transform:translateX(-50%);color:#252424;font-size:18px;font-weight:700;background:#070707;z-index:2;padding:5px 10px 0 10px;border-radius:10px 10px 0 0}.chord-option{display:inline-flex;gap:10px;padding:15px;border-radius:0 0 10px 10px;background:#070707;position:relative}.chord-option::before{content:"";position:absolute;top:-2px;left:0;width:100%;height:2px;background:#252424}.chord-option select{background-color:#252424;color:gold;border:2px solid cyan;border-radius:8px;padding:10px 16px;font-weight:700;font-family:Arial,Helvetica,sans-serif;font-size:14px;outline:none;transition:background-color 0.3s,color 0.3s;width:155px}select option{background-color:#252424;color:gold;font-weight:400}select:hover,select:focus{background-color:#252424;color:cyan;border-color:gold;cursor:pointer}.columnboxpiano{display:flex;flex-direction:row;flex-wrap:wrap;align-items:flex-start;padding:15px 0 0 0;background-color:#252424;border-radius:20px;width:100%;box-sizing:border-box;gap:10px}.left-column{width:72%}.right-column{width:26%}.left-column,.right-column{display:flex;flex-direction:column;gap:10px;color:#fff;box-sizing:border-box}.wrapper .control{display:flex;color:#252424;align-items:center;justify-content:space-between;padding:15px}.control .column{display:flex;align-items:center;gap:5px}.control span{font-weight:500;margin-right:15px;font-size:1.19rem}.control input{outline:none;border-radius:30px}.piano-keys{display:flex;list-style:none;margin-top:40px;padding:20px}ul.piano-keys{list-style-type:none!important}.piano-keys .key{cursor:pointer;user-select:none;position:relative;text-transform:uppercase}.piano-keys .black{z-index:2;width:44px;height:140px;margin:0 -22px 0 -22px;border-radius:0 0 5px 5px;background:linear-gradient(#333,#000)}.piano-keys .black.active{box-shadow:inset -5px -10px 10px rgb(255 255 255 / .1);background:linear-gradient(to bottom,#000,#434343)}.piano-keys .white{height:230px;width:70px;border-radius:8px;border:1px solid #000;background:linear-gradient(#fff 96%,#eee 4%)}.piano-keys .white.active{box-shadow:inset -5px 5px 20px rgb(0 0 0 / .2);background:linear-gradient(to bottom,#fff 0%,#eee 100%)}.piano-keys .key span{position:absolute;bottom:20px;width:80%;font-size:1.13rem;text-align:center}.piano-keys .black span{bottom:21px;color:#888}.mark{height:25px;width:20px;border-radius:50%}.piano-keys .key span.fullmark{background-color:rgb(255 255 0 / .3);border-radius:4px;padding:2px 4px;transition:background-color 0.3s ease}.hide{display:none!important}.piano-keys .key span.note-label{display:block;bottom:29px}.piano-keys .key span.key-label{display:block;font-size:12px;color:#888;bottom:9px}.toggle-box{background:#252424;padding:10px 15px 20px 15px;border-radius:40px;font-family:sans-serif;color:#00fdfd;margin:0 auto}.keys-checkbox{display:flex;align-items:center;gap:10px;margin:10px 0;font-family:sans-serif;width:100%}.keys-checkbox input{height:30px;width:60px;cursor:pointer;appearance:none;position:relative;background:#4B4B4B}.keys-checkbox input::before{content:"";position:absolute;top:50%;left:5px;width:20px;height:20px;border-radius:50%;background:#8c8c8c;transform:translateY(-50%);transition:all 0.3s ease}.keys-checkbox input:checked::before{left:35px;background:#fff}.switch input{opacity:0;width:0;height:0}.switch{position:relative;display:inline-block;width:65px;height:26px}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:0.4s;border-radius:26px;width:50px}.slider::before{content:"";position:absolute;height:20px;width:20px;left:3px;bottom:3px;background-color:#fff;transition:0.4s;border-radius:50%}.switch input:checked+.slider{background-color:cyan;width:50px}.switch input:checked+.slider::before{transform:translateX(24px)}.reverb-box{background:#252424;padding:10px 15px 20px 15px;border-radius:40px;font-family:sans-serif;color:#00fdfd;margin:0 auto}.reverb-box select{background-color:#252424;color:gold;border:2px solid cyan;border-radius:8px;padding:10px 16px;font-weight:700;font-family:Arial,Helvetica,sans-serif;font-size:14px;outline:none;transition:background-color 0.3s,color 0.3s;width:95px}.ptpiano-wrapper{position:relative;min-height:300px;background:#fff0}.ptpiano-loader{position:absolute;top:0;left:0;width:100%;height:100%;background:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:10}.ptpiano-loader p{margin-top:15px;font-size:14px;font-weight:700;color:#333}.spinner{width:40px;height:40px;border:4px solid #ddd;border-top:4px solid cyan;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{100%{transform:rotate(360deg)}}@media screen and (max-width:1280px){.wrapper{padding:5px}header{flex-direction:column}header :where(h2,.column){margin-bottom:13px}.piano-header{width:170px!important}.piano-speaker{display:none}.col-center{grid-column:1 / -1;width:100%;padding-left:0;align-items:center}#played-notes{width:120px!important}.wrapper .control{display:block!important}.chord-group{display:block!important;margin:0!important}.chord-option select{display:block;width:100%!important;margin-left:0}.chord-option::before{display:none}.chord-label{display:none}.left-column{width:99%!important}.columnboxpiano{flex-direction:column;align-items:center}.piano-keys .black{height:100px;width:44px;margin:0 -20px 0 -20px}.piano-keys .white{height:180px;width:70px}.piano-keys{display:flex;justify-content:space-between;flex-wrap:nowrap;margin:0!important;padding:0 5px}.piano-keys .white{width:9.5vw;height:140px}.piano-keys .black{width:5vw;height:100px;margin:0 -2.5vw}.right-column{width:98%!important;padding:10px 0}canvas#equalizer{width:95%!important;height:auto!important}.piano-keys .key span{font-size:10px}}1 *{margin:0;padding:0;box-sizing:border-box;font-family:sans-serif}.content-wrapper{padding:5px 10px 15px 10px;border-radius:20px}.content-wrapper header{display:flex;color:#B2B2B2;align-items:center;justify-content:space-between;padding:15px}.columnbox{display:grid;grid-template-columns:1fr 4fr 1fr;align-items:center;padding:15px 20px;background-color:#252424;border-radius:20px;width:100%}.col-left{display:flex;flex-direction:column}.piano-header{display:flex;align-items:center;gap:10px}.piano-title h2{margin:0;font-size:21px;font-weight:700;color:#555;font-style:italic;font-family:fantasy}.piano-title .version{font-size:18px;color:#555;margin-left:6px;font-family:cursive}.piano-speaker img{margin-top:5px;max-width:150px}.col-center{display:flex;flex-direction:column;align-items:center;justify-content:flex-start;gap:15px}.equalizer-notes-row{display:flex;flex-direction:row;gap:5px;align-items:center;justify-content:center;width:100%;max-width:100%}.note-display-wrapper{background:#1e1e1e;border-radius:12px;padding:10px 15px;min-height:100px;box-shadow:inset 0 0 6px rgb(0 0 0 / .6);border:1px solid #444;display:flex;align-items:center;justify-content:flex-start;flex-grow:1;width:90%;min-height:125px;max-width:100%;overflow-x:hidden}.equalizer-wrapper{background:#1e1e1e;border-radius:12px;padding:10px 15px;box-shadow:inset 0 0 6px rgb(0 0 0 / .6);border:1px solid #444;display:flex;align-items:center;justify-content:center;width:220px;min-height:100px}.note-display{width:100%;height:100px;overflow-x:hidden;overflow-y:auto;white-space:normal;padding:8px 12px;background:#121212;border-radius:8px;color:#eee;font-family:monospace,monospace;font-size:16px;user-select:text;box-sizing:border-box}#played-notes{display:flex;flex-wrap:wrap;align-items:flex-start;overflow-x:hidden;overflow-y:auto;background:#121212;border-radius:8px;padding:8px 12px;height:100px;color:#eee;font-family:monospace;font-size:16px;box-sizing:border-box;gap:6px 8px;line-height:1}#played-notes::-webkit-scrollbar{width:10px}#played-notes::-webkit-scrollbar-track{background:#1e1e1e;border-radius:10px}#played-notes::-webkit-scrollbar-thumb{background:linear-gradient(135deg,#ff6ec4,#7873f5);border-radius:10px;border:2px solid #1e1e1e}#played-notes::-webkit-scrollbar-thumb:hover{background:linear-gradient(135deg,#ff8ec4,#9893f5)}.played-note{display:inline-block;padding:2px 6px;background-color:#2a2a2a;border-radius:4px;white-space:nowrap;margin:0;line-height:1}#equalizer{width:220px}.col-right{display:flex;flex-direction:column;padding:5px 0 0 15px}#enable-piano-btn{padding:10px 20px;font-size:16px;color:#fff;border:none;border-radius:4px;cursor:pointer;transition:background-color 0.3s ease,box-shadow 0.3s ease}#enable-piano-btn.enabled{background-color:green;color:#fff;box-shadow:0 0 10px 2px rgb(0 255 0 / .8)}#enable-piano-btn.disabled{background-color:red;color:#fff;box-shadow:none}.vol-notes-row{display:flex;flex-wrap:wrap;align-items:center;gap:15px;margin-top:10px;justify-content:center}.volume-slider{display:flex;align-items:center;background:#555;padding:10px 15px;border-radius:40px;width:320px;gap:12px;font-family:sans-serif;color:#00fdfd}.volume-icon{font-size:20px}#volumeControl{-webkit-appearance:none;appearance:none;width:100%;height:8px;background:linear-gradient(to bottom,#555,#1E1E1E);border-radius:3px;cursor:pointer}#volumeControl::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:21px;height:30px;background:linear-gradient(to right,#555,#ccc),linear-gradient(to bottom,#444,#111);background-repeat:no-repeat;background-position:center;background-size:100% 6px,cover;border:2px solid #888;border-radius:3px;box-shadow:0 2px 6px rgb(0 0 0 / .4);margin-top:2px;z-index:3;position:relative}#volumeControl::-moz-range-thumb{width:21px;height:30px;background:linear-gradient(to right,#ccc,#ccc),linear-gradient(to bottom,#444,#111);background-repeat:no-repeat;background-position:center;background-size:100% 2px,cover;border:2px solid #888;border-radius:3px;box-shadow:0 2px 6px rgb(0 0 0 / .4)}#volumeRValue{font-weight:700;min-width:32px;text-align:right;color:orange}.button-box{display:flex;flex-wrap:wrap;gap:10px;background:#555;padding:10px 20px;border-radius:40px;font-family:sans-serif;justify-content:center}.dotted-btn{position:relative;width:100px;padding:10px 16px;height:auto;background-color:#2b2b2b;border:none;border-radius:8px;box-shadow:inset -4px 4px 8px #1a1a1a,inset 4px -4px 8px #3a3a3a;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:transform 0.2s}.dotted-btn:hover{transform:scale(.95);box-shadow:inset 3px 3px 6px rgb(0 0 0 / .6),inset -3px -3px 6px rgb(255 255 255 / .05);transition:transform 0.2s,box-shadow 0.2s}.dotted-btn::before{content:"";position:absolute;width:80%;height:80%;background-image:radial-gradient(#000 2px,transparent 0);background-size:8px 8px;top:50%;left:50%;transform:translate(-50%,-50%);opacity:.3;pointer-events:none;border-radius:6px}.button-content{display:flex;align-items:center;gap:8px;z-index:1;background-color:#252525}.indicator{width:12px;height:12px;background-color:#ff2e2e;border-radius:50%;transition:box-shadow 0.3s ease,opacity 0.3s ease;opacity:.5}.indicatorp{width:12px;height:12px;background-color:#00FDFD;border-radius:50%;transition:box-shadow 0.3s ease,opacity 0.3s ease;opacity:.5}.dotted-btn.active .indicator{box-shadow:0 0 12px 4px #ff2e2e;opacity:1}.dotted-btn.active .indicatorp{box-shadow:0 0 12px 4px #00FDFD;opacity:1}.btn-label{font-size:18px;color:#555;background-color:#fff0}#clearBtn{transition:background-color 0.2s ease,color 0.2s ease,opacity 0.2s ease}.chord-group{display:inline-block;text-align:center;position:relative;margin:0 20px}.chord-label{position:absolute;top:-18px;left:50%;transform:translateX(-50%);color:#252424;font-size:18px;font-weight:700;background:#070707;z-index:2;padding:5px 10px 0 10px;border-radius:10px 10px 0 0}.chord-option{display:inline-flex;gap:10px;padding:15px;border-radius:0 0 10px 10px;background:#070707;position:relative}.chord-option::before{content:"";position:absolute;top:-2px;left:0;width:100%;height:2px;background:#252424}.chord-option select{background-color:#252424;border:2px solid #555;border-radius:8px;padding:10px 16px;font-weight:700;font-family:Arial,Helvetica,sans-serif;font-size:14px;outline:none;transition:background-color 0.3s,color 0.3s;width:155px}select option{background-color:#252424;font-weight:400}.columnboxpiano{display:flex;flex-direction:row;flex-wrap:wrap;align-items:flex-start;padding:15px 0 0 0;background-color:#252424;border-radius:20px;width:100%;box-sizing:border-box;gap:10px}.left-column{width:72%}.left-column,.right-column{display:flex;flex-direction:column;gap:10px;color:#fff;box-sizing:border-box}.content-wrapper .control{display:flex;color:#252424;align-items:center;justify-content:space-between;padding:15px}.control .column{display:flex;align-items:center;gap:5px}.control span{font-weight:500;margin-right:15px;font-size:1.19rem}.control input{outline:none;border-radius:30px}.piano-keys{display:flex;list-style:none;margin-top:40px;padding:20px}ul.piano-keys{list-style-type:none!important}.piano-keys .key{cursor:pointer;user-select:none;position:relative;text-transform:uppercase}.piano-keys .white,.piano-keys .black{transition:transform 0.08s ease-in,box-shadow 0.1s ease,background 0.1s ease;will-change:transform}.piano-keys .black{z-index:3;width:44px;height:140px;margin:0 -22px 0 -22px;border-radius:0 0 5px 5px;background:linear-gradient(#333,#000);box-shadow:0 4px 8px rgb(0 0 0 / .6),inset 0 -2px 2px rgb(255 255 255 / .05);transition:transform 0.08s ease-in,box-shadow 0.1s ease,background 0.1s ease}.piano-keys .black.active{transform:scale(.96) translateY(1px);background:linear-gradient(to bottom,#000,#434343);box-shadow:inset -5px -10px 10px rgb(255 255 255 / .1),0 2px 10px rgb(0 0 0 / .5)}.piano-keys .white{height:230px;width:70px;border-radius:8px;border:1px solid #000;background:linear-gradient(#fff 96%,#eee 4%)}.piano-keys .white.active{transform:scale(.97);box-shadow:inset -5px 5px 20px rgb(0 0 0 / .2),0 2px 6px rgb(0 0 0 / .3);background:linear-gradient(to bottom,#fff 0%,#eee 100%)}.piano-keys .key span{position:absolute;bottom:20px;width:80%;font-size:1.13rem;text-align:center}.piano-keys .black span{bottom:21px;color:#888}.hide{display:none!important}.piano-keys .key span.note-label{display:block;bottom:29px}.piano-keys .key span.key-label{display:block;font-size:12px;color:#555;bottom:9px}.right-column{width:26%}.ctl-label{color:#555}.showscalechord{appearance:none;border:none;outline:none;background:#252424;border-radius:.2em .2em 0 0;text-align:center;padding:.6em;margin:0 auto;color:#fff}.toggle-box{background:#252424;padding:10px 15px 20px 15px;border-radius:40px;font-family:sans-serif;margin:0 auto}.keys-checkbox{display:flex;align-items:center;gap:10px;margin:10px 0;font-family:sans-serif;width:100%}.keys-checkbox input{height:30px;width:60px;cursor:pointer;appearance:none;position:relative;background:#4B4B4B}.keys-checkbox input::before{content:"";position:absolute;top:50%;left:5px;width:20px;height:20px;border-radius:50%;background:#8c8c8c;transform:translateY(-50%);transition:all 0.3s ease}.keys-checkbox input:checked::before{left:35px;background:#fff}.switch input{opacity:0;width:0;height:0}.switch{position:relative;display:inline-block;width:65px;height:26px}.slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background-color:#ccc;transition:0.4s;border-radius:26px;width:50px}.slider::before{content:"";position:absolute;height:20px;width:20px;left:3px;bottom:3px;background:linear-gradient(to bottom right,#555,#ccc);transition:0.4s;border-radius:50%}.switch input:checked+.slider{width:50px}.switch input:checked+.slider::before{transform:translateX(24px)}.reverb-box{background:#252424;padding:10px 15px 20px 15px;border-radius:40px;font-family:sans-serif;margin:0 auto}.reverb-box select{background-color:#252424;color:gold;border:2px solid #555;border-radius:8px;padding:10px 16px;font-weight:700;font-family:Arial,Helvetica,sans-serif;font-size:14px;outline:none;transition:background-color 0.3s,color 0.3s;width:95px}.ptpiano-wrapper{position:relative;min-height:300px;background:#fff0}.ptpiano-loader{position:absolute;top:0;left:0;width:100%;height:100%;background:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;z-index:10}.ptpiano-loader p{margin-top:15px;font-size:14px;font-weight:700;color:#333}.spinner{width:40px;height:40px;border:4px solid #ddd;border-top:4px solid cyan;border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{100%{transform:rotate(360deg)}}.popup-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background:rgb(0 0 0 / .75);display:none;justify-content:center;align-items:center;z-index:9999;pointer-events:all}.popup-content{background:#252424;padding:25px 30px;color:#fff;border-radius:12px;text-align:center;max-width:350px;box-shadow:0 10px 25px rgb(0 0 0 / .3);animation:fadeInScale 0.3s ease-in-out;font-family:'Segoe UI',sans-serif}.popup-content h3{margin-top:0;color:#555}.popup-content p{color:#555;margin:15px 0}.popup-content button{background-color:#3a7afe;color:#fff;border:none;padding:10px 18px;font-size:14px;border-radius:6px;cursor:pointer}.popup-content button:hover{background-color:#245fd3}@media screen and (max-width:1280px){.content-wrapper{padding:5px}header{flex-direction:column}header :where(h2,.column){margin-bottom:13px}.piano-header{width:170px!important}.piano-speaker{display:none}.col-center{grid-column:1 / -1;width:100%;padding-left:0;align-items:center}#played-notes{width:120px!important}.content-wrapper .control{display:block!important}.chord-group{display:block!important;margin:0!important}.chord-option select{display:block;width:100%!important;margin-left:0}.chord-option::before{display:none}.chord-label{display:none}.left-column{width:99%!important}.columnboxpiano{flex-direction:column;align-items:center}.piano-keys .black{height:100px;width:44px;margin:0 -20px 0 -20px}.piano-keys .white{height:180px;width:70px}.piano-keys{display:flex;justify-content:space-between;flex-wrap:nowrap;margin:0!important;padding:0 5px}.piano-keys .white{width:9.5vw;height:140px}.piano-keys .black{width:5vw;height:100px;margin:0 -2.5vw}.right-column{width:98%!important;padding:10px 0}canvas#equalizer{width:95%!important;height:auto!important}.piano-keys .key span{font-size:10px}}
Note: See TracChangeset
for help on using the changeset viewer.