simple-piano-keyboard
Version:
Can display simple piano keyboard. (Note: No include sound)
2 lines (1 loc) • 4.5 kB
JavaScript
;const t=require("vue");const Z=(l,s)=>{const a=l.__vccOpts||l;for(const[o,r]of s)a[o]=r;return a},A=12,ee=3,S={C:3,"C#":1.7,D:1.3,"D#":2.3,E:.7,F:3,"F#":1.35,G:1.65,"G#":1.9,A:1.1,"A#":2.45,B:.55},k={whiteKey:"#FFFFFF",blackKey:"#222222",selectedWhiteKey:"#B2EBF2",selectedBlackKey:"#B2EBF2",keyBorder:"#212121",frameBorder:"#e0e0e0",noteName:"#212121"},g={keyBorder:1,frameBorder:2},N={type:"none",target:"A"},te={name:"SimplePianoKeyboard",props:{modelValue:{default:[]},lowestNote:{default:"A0"},highestNote:{default:"C8"},keyHeightSize:{default:10},keyWidthSize:{default:10},padding:{default:8},width:{default:380},color:{default:k},thickness:{default:g},noteNameDisplay:{default:N},noteOutputType:{default:"intl"},isReadOnly:{default:!1}},emits:["update:modelValue"],setup(l,{emit:s}){const{modelValue:a,lowestNote:o,highestNote:r,keyHeightSize:m,keyWidthSize:i,padding:b,width:E,color:K,thickness:_,noteNameDisplay:x,noteOutputType:j,isReadOnly:D}=t.toRefs(l);t.watch(a,(e,c)=>{(e.length!==c.length||e.some((n,f)=>n!==c[f]))&&(p.value=h())});const u=t.computed(()=>o.value||o.value===0?isNaN(o.value)?B(o.value):o.value:33),T=t.computed(()=>{let e=108;return(r.value||r.value===0)&&(e=isNaN(r.value)?B(r.value):r.value),e<u.value&&(e=u.value),e}),d=t.computed(()=>({height:A*m.value,width:ee*i.value})),R=t.computed(()=>({height:d.value.height*.65,width:d.value.width*.7})),H=t.computed(()=>d.value.height*.76),y=t.computed(()=>typeof K.value=="object"?Object.assign(k,K.value):k),v=t.computed(()=>typeof _.value=="object"?Object.assign(g,_.value):g),P=t.computed(()=>typeof x.value=="object"?Object.assign(N,x.value):N),w=t.computed(()=>a.value&&a.value.length>0?a.value.map(e=>isNaN(e)?B(e):e):[]),h=()=>{const e=[];let c=0;e.push({left:c,isBlackKey:F(u.value),selected:!!w.value.includes(u.value),num:u.value,intl:z(u.value)});for(let n=u.value+1;n<T.value+1;n++)c+=i.value*S[W(n)],e.push({left:c,isBlackKey:F(n),selected:!!w.value.includes(n),num:n,intl:z(n),char:W(n)});return e},p=t.ref(h());t.watch(p,e=>{s("update:modelValue",e.filter(c=>c.selected).map(c=>j.value==="intl"?c.intl:c.num))},{deep:!0}),t.watch([o,r],()=>{p.value=h()});const I=t.computed(()=>p.value.filter(e=>!e.isBlackKey).length),V=e=>{const{type:c,target:n}=P.value;return c==="none"?"":e.char===n||n==="all"?c==="intl"?e.intl:e.num:""},G=e=>{D.value||(e.selected=!e.selected)},q=e=>{const{left:c,isBlackKey:n,selected:f}=e,{blackKey:M,whiteKey:Q,keyBorder:U}=y.value,$=n?R.value:d.value,X=n?M:Q,Y=n?y.value.selectedBlackKey:y.value.selectedWhiteKey,O=v.value.keyBorder;return`height: ${$.height}px; width: ${$.width}px; left: ${c}px; border: solid ${O}px ${U}; border-radius: ${O*3}px; background-color: ${f?Y:X}; z-index: ${n?2:1}`},L=t.computed(()=>{const e=v.value.keyBorder;return`height: ${d.value.height+e*2}px; width: ${d.value.width*I.value+e*2}px; border-radius: ${e*3}px; border: solid ${e}px ${y.value.keyBorder}`}),J=t.computed(()=>{const{frameBorder:e}=v.value;return`width: ${E.value-e}px; padding: ${b.value}px; border: solid ${e}px ${y.value.frameBorder}; font-size: ${m.value*1.4}px; color: ${y.value.noteName};`});return{spacerHeight:H,keys:p,getNoteName:V,changeSelectionOfKey:G,keyStyle:q,keysWrapperStyle:L,keyboardWrapperStyle:J}}};function z(l){const{char:s,num:a}=C(l);return s+a}function C(l){const s=Math.floor(l/12),a=l%12,o=a<9?s-1:s;return{char:Object.keys(S)[a],num:o}}function B(l){const s=l.includes("#")?l.slice(0,2):l.slice(0,1),a=l.includes("#")?Number(l.slice(2)):Number(l.slice(1)),o=Object.keys(S).indexOf(s);return(o<9?a+1:a)*12+o}function F(l){const s=l%12;return[1,3,6,8,10].some(o=>o===s)}function W(l){const{char:s}=C(l);return s}const le=["onClick"],oe={class:"note-name"};function ne(l,s,a,o,r,m){return t.openBlock(),t.createElementBlock("div",{class:"keyboard-wrapper",style:t.normalizeStyle(o.keyboardWrapperStyle)},[t.createElementVNode("div",{class:"keys-wrapper",style:t.normalizeStyle(o.keysWrapperStyle)},[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(o.keys,i=>(t.openBlock(),t.createElementBlock("div",{key:i.num,style:t.normalizeStyle(o.keyStyle(i)),onClick:b=>o.changeSelectionOfKey(i),class:"one-key"},[t.createElementVNode("div",{style:t.normalizeStyle(`height: ${o.spacerHeight}px`)},null,4),t.createElementVNode("div",oe,t.toDisplayString(o.getNoteName(i)),1)],12,le))),128))],4)],4)}const ae=Z(te,[["render",ne],["__scopeId","data-v-dc080436"]]),se={install:(l,s)=>{l.component("SimplePianoKeyboard",ae)}};module.exports=se;