Plugin Directory

Changeset 3364816


Ignore:
Timestamp:
09/20/2025 05:12:06 AM (6 months ago)
Author:
santechidea
Message:

Version 1.2.9

Location:
ptpiano/tags/1.2.9
Files:
1 edited
43 copied

Legend:

Unmodified
Added
Removed
  • ptpiano/tags/1.2.9/PT_Piano_Player.php

    r3361001 r3364816  
    33    exit; // Exit if accessed directly
    44}
    5 ?>
    6 <?php
     5
    76if ( ! function_exists( 'get_plugin_data' ) ) {
    87    require_once ABSPATH . 'wp-admin/includes/plugin.php';
     
    1110$plugin_data = get_plugin_data( plugin_dir_path(__FILE__) . 'ptpiano.php' );
    1211$plugin_version = $plugin_data['Version'];
     12
     13$record_duration = get_option('ptpian_record_duration', 30); // fallback to 30
    1314?>
    1415<div class="ptpiano-wrapper">   
     
    1819      <p>Please wait, PTPiano loading...</p>
    1920    </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
    2030    <div class="ptpiano-content" style="display:none;">
    2131        <!-- your existing plugin content -->
    22         <div class="wrapper">
     32        <div class="content-wrapper">
    2333            <header>               
    2434                <div class="columnbox">
     
    138148                        <option value="">Major</option>
    139149                        <option value="C">C Chords</option>
     150                        <option value="C#">C♯ Chords</option>
    140151                        <option value="D">D Chords</option>
     152                        <option value="D#">D♯ Chords</option>
    141153                        <option value="E">E Chords</option>
    142154                        <option value="F">F Chords</option>
     155                        <option value="F#">F♯ Chords</option>
    143156                        <option value="G">G Chords</option>
     157                        <option value="G#">G♯ Chords</option>
    144158                        <option value="A">A Chords</option>
     159                        <option value="A#">A♯ Chords</option>
     160                        <option value="B">B Chords</option>
    145161                    </select>
    146162
    147163                    <select id="minorchord" name="minorchord" class="<?php echo esc_attr($minor_hidden_class); ?>">
    148164                        <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>
    155177                    </select>
    156178
    157179                    <select id="diminishedchord" name="diminishedchord" class="<?php echo esc_attr($dim_hidden_class); ?>">
    158180                        <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
    165195                    </select>
    166196                    <select id="augmentedchord" name="augmentedchord" class="<?php echo esc_attr($agu_hidden_class); ?>">
    167197                        <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>
    182213                </div>
    183214            </div>
     
    254285                </div>
    255286               
    256                 <div class="right-column"> 
    257 
     287                <div class="right-column">
    258288                    <?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" />
    270290                    <?php endif; ?>
    271291               
    272292                    <div class="toggle-box">                   
    273293                        <div class="keys-checkbox">
    274                             <span>Notes</span>
     294                            <span class="ctl-label">Notes</span>
    275295                            <label class="switch">
    276296                                <input type="checkbox" id="show-notes-toggle" checked>
    277297                                <span class="slider round"></span>
    278298                            </label>
    279                             <span>Keys</span>
     299                            <span class="ctl-label">Keys</span>
    280300                            <label class="switch">
    281301                                <input type="checkbox" id="show-keys-toggle" checked>
     
    286306                    <div class="reverb-box">   
    287307                        <div class="keys-checkbox">
    288                             <span>Reverb</span>
     308                            <span class="ctl-label">Reverb</span>
    289309                            <label for="ptpian_reverb_enable" class="switch">
    290310                                <input type="checkbox" id="ptpian_reverb_enable" name="ptpian_reverb_enable" value="1" <?php checked(get_option('ptpian_reverb_enable'), 1); ?> />
    291311                                <span class="slider round"></span>
    292312                            </label>                                               
    293                             <label for="ptpian_reverb_ir">IR:</label>
     313                            <label for="ptpian_reverb_ir" class="ctl-label">IR:</label>
    294314                            <select id="ptpian_reverb_ir" name="ptpian_reverb_ir">
    295315                                <option value="hall">Hall</option>
  • ptpiano/tags/1.2.9/PT_Piano_Setting.php

    r3361001 r3364816  
    33    exit; // Exit if accessed directly
    44}
    5 ?>
    6 <?php
     5
    76if ( ! function_exists( 'get_plugin_data' ) ) {
    87    require_once ABSPATH . 'wp-admin/includes/plugin.php';
     
    105104                                <input type="color" id="ptpian_bgcolor_control" name="ptpian_bgcolor_control"
    106105                                       value="<?php echo esc_attr(get_option('ptpian_bgcolor_control')); ?>" />
    107                                 <label>&nbsp;[Choose BG color]</label>
     106                                <label>&nbsp;[Background]</label>
    108107                            </td>
    109108                            <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>&nbsp;[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>&nbsp;[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>&nbsp;[Select Option]</label>
    113117                            </td>
    114118                        </tr>
     
    156160
    157161                    </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>
    158174
    159175                    <div class="center-submit">
     
    179195    </table>
    180196</div>
    181 
    182 
    183 
    184 
  • ptpiano/tags/1.2.9/functions.php

    r3361001 r3364816  
    6767}
    6868
    69 
    7069/**
    7170 * Enqueue frontend scripts and styles
     
    7372add_action('wp_enqueue_scripts', 'ptpian_enqueue_assets');
    7473
    75 function ptpian_enqueue_assets() {
     74function 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   
    7687    // CSS
    7788    wp_enqueue_style(
     
    93104    // Set dynamic CSS variables
    94105    $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')) . ';';
    96109    $css_vars .= '--ptpian-txt-piano-color: ' . esc_attr(get_option('ptpian_txtcolor_piano')) . ';';
    97110    $css_vars .= '--ptpian-mark-bg-color: ' . esc_attr(get_option('ptpian_markcolor_piano')) . ';';
     
    242255        '1.2.5',
    243256        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    ));
    245265
    246266}
     
    262282    // Color settings
    263283    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');
    265286    register_setting('ptpian_settings_group', 'ptpian_txtcolor_piano', 'sanitize_hex_color');
    266287    register_setting('ptpian_settings_group', 'ptpian_markcolor_piano', 'sanitize_hex_color');
     
    270291    // NEW: Piano key lights toggle
    271292    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
    272297}
    273298
  • 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'}})})
     1document.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}
     2const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])}
     3const 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]}
     4selectAugmentedElement.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'}})})
     1document.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}
     2const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])}
     3const 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]}
     4selectDiminishedElement.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')}
     5if(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'}})})
     1document.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}
     2const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])}
     3const 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])}
     1document.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}
     2const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])}
     3function 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])}
    24return 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'})}})})
     5const 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')}
     6if(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'})}
     7const 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'}})})
     1document.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}
     2const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])}
     3const 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])}
     1document.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}
     2const noteLabelSpan=keyElement.querySelector('.note-label');if(!noteLabelSpan)return!1;const label=noteLabelSpan.textContent;return(label===solfegeMap[noteLetter]||label===indianMap[noteLetter])}
     3function 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])}
    24return 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'})}})})
     5const 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')}
     6if(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'})}
     7const 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)})}}
     1document.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)})}}
    22window.startAudioContext=startAudioContext;enablePianoBtn.addEventListener('click',()=>{startAudioContext()});if(window.ptpReverb){ptpReverb.initReverb(audioContext);ptpReverb.loadReverb(ptpianReverbData?.irs?.hall)}
    33pianoKeys.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>120){noteDisplay.removeChild(noteDisplay.firstChild)}
     4analyser.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)}
    55const note=clickedKey?.dataset.note||key;pianoRecorder.recordNote(key,note)}
    66if(!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})
     7requestAnimationFrame(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 <?php
    2 if ( ! defined( 'ABSPATH' ) ) {
    3     exit; // Exit if accessed directly
    4 }
    5 ?>
    61<?php
    72/**
    83 * Plugin Name: PTPiano
    94 * Description: An interactive, browser-based piano plugin for learning and exploring chords and notes.
    10  * Version: 1.2.8
     5 * Version: 1.2.9
    116 * Author: santechidea
    127 * Author URI:  https://wordpress.santechidea.net
     
    1510 * Text Domain: ptpiano
    1611 */
     12 
     13 if ( ! defined( 'ABSPATH' ) ) {
     14    exit; // Exit if accessed directly
     15}
    1716
    1817// Define constants with unique prefix
  • ptpiano/tags/1.2.9/readme.txt

    r3361001 r3364816  
    55Tested up to: 6.8
    66Requires PHP: 8.0
    7 Stable tag: 1.2.8
     7Stable tag: 1.2.9
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
     
    5050
    5151== 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.
    5264
    5365= 1.2.8 =
     
    163175First stable release of PT Piano.
    164176* 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)}
     2select 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.