UNPKG

chordproject-diagrammer

Version:

A TypeScript library for generating SVG chord diagrams.

1 lines 6.58 kB
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ChordProjectDiagrammer=e():t.ChordProjectDiagrammer=e()}(self,(function(){return(()=>{"use strict";var t={d:(e,s)=>{for(var i in s)t.o(s,i)&&!t.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:s[i]})},o:(t,e)=>Object.prototype.hasOwnProperty.call(t,e),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},e={};t.r(e),t.d(e,{ChordDiagram:()=>g,Instrument:()=>c,SvgBuilder:()=>o});class s{static createSVGElement(t,e,s=!1){const i=document.createElementNS("http://www.w3.org/2000/svg",t);for(let t in e)s?i.setAttributeNS(null,t.replace(/[A-Z]/g,(function(t,e,s,i){return"-"+t.toLowerCase()})),e[t].toString()):i.setAttributeNS(null,t,e[t].toString());return i}static appendTextNode(t,e){const s=document.createTextNode(e);return t.appendChild(s),t}}class i{constructor(t){this._settings=t}build(t,e,i,n){var r=s.createSVGElement("g",{class:"neck"}),a=s.createSVGElement("rect",{class:"neck-background",x:0,y:0,width:this._settings.stringSpace*(e-1),height:this._settings.fretSpace*i});r.appendChild(a);var o=s.createSVGElement("path",{class:"neck-grid",strokeWidth:this._settings.neck.lineWidth,strokeLinecap:"square",d:this.getNeckPath(e,i)},!0);let g;if(r.appendChild(o),1===n)g=s.createSVGElement("path",{class:"neck-nut",strokeWidth:this._settings.neck.nutWidth,strokeLinecap:"round",strokeLinejoin:"round",d:`M 0 ${-this._settings.neck.nutWidth/2} H ${(e-1)*this._settings.stringSpace}`},!0);else{var c=s.createSVGElement("text",{class:"neck-basefret",dominantBaseline:"middle",textAnchor:"end",x:-(this._settings.neck.baseFretMargin+this._settings.dot.radius+this._settings.dot.borderWidth),y:this._settings.fretSpace/2+.2},!0);const t=this.getBaseFretText(n);g=s.appendTextNode(c,t)}if(r.appendChild(g),this._settings.neck.stringNameVisible){var d=s.createSVGElement("g");t.forEach(((t,e)=>{var n=s.createSVGElement("text",{class:"neck-stringnames",key:e,textAnchor:"middle",dominantBaseline:"hanging",x:e*this._settings.stringSpace,y:i*this._settings.fretSpace+this._settings.neck.stringNameMargin},!0);d.appendChild(s.appendTextNode(n,t))})),r.appendChild(d)}return r}getBaseFretText(t){return this._settings.neck.useRoman?["I","II","III","IV","V","VI","VII","VIII","IX","X","XI","XII","XIII","XIV","XV"][t-1]:t+"fr"}getNeckHorizonalLine(t,e){return`M 0 ${t*this._settings.fretSpace} H ${(e-1)*this._settings.stringSpace}`}getNeckVerticalLine(t,e){return`M ${t*this._settings.stringSpace} 0 V ${e*this._settings.fretSpace}`}getNeckPath(t,e){return Array.apply(null,Array(e+1)).map(((e,s)=>this.getNeckHorizonalLine(s,t))).join(" ").concat(Array.apply(null,Array(t)).map(((t,s)=>this.getNeckVerticalLine(s,e))).join(" "))}}class n{constructor(t){this._settings=t}build(t,e,i){const n=10*(i-e);var r=s.createSVGElement("g");const a=e*this._settings.stringSpace,o=t*this._settings.fretSpace-this._settings.fretSpace/2-this._settings.dot.radius;var g=s.createSVGElement("rect",{class:"dot-circle dot-barre",strokeWidth:this._settings.dot.borderWidth,x:a,y:o,width:n,height:2*this._settings.dot.radius},!0);return r.appendChild(g),r}}class r{constructor(t){this._settings=t}build(t,e,i,n){const r=t*this._settings.stringSpace,a=e*this._settings.fretSpace-this._settings.fretSpace/2;if(-1===e){var o=s.createSVGElement("text",{class:"dot-stringinfo dot-mutedstring",textAnchor:"middle",dominantBaseline:"auto",x:r,y:n?-this._settings.neck.nutWidth-this._settings.dot.stringInfoMargin:-this._settings.dot.stringInfoMargin},!0);return s.appendTextNode(o,"x")}{let t=a,o=this._settings.dot.radius,h="dot-circle";0===e&&(t=n?-this._settings.neck.nutWidth-this._settings.dot.stringInfoMargin-this._settings.dot.openStringRadius:-this._settings.dot.stringInfoMargin-this._settings.dot.openStringRadius,o=this._settings.dot.openStringRadius,h="dot-stringinfo dot-openstring");var g=s.createSVGElement("g"),c=s.createSVGElement("circle",{class:h,strokeWidth:this._settings.dot.borderWidth,cx:r,cy:t,r:o},!0);if(g.appendChild(c),i>0){var d=s.createSVGElement("text",{class:"dot-finger",textAnchor:"middle",dominantBaseline:"middle",x:r,y:a+.2},!0);g.appendChild(s.appendTextNode(d,i.toString()))}return g}}}class a{constructor(){this.stringSpace=10,this.fretSpace=14,this.dot={radius:4,borderWidth:.25,openStringRadius:2,stringInfoMargin:2},this.neck={lineWidth:.3,baseFretMargin:1,useRoman:!0,nutWidth:2,stringNameVisible:!0,stringNameMargin:2}}}class o{constructor(){this._settings=new a}set settings(t){this._settings=t}build(t,e){var a=e.tuning,o=e.stringsCount,g=e.fretsOnDiagram,c=t.baseFret>0?t.baseFret:1;const d=(o-1)*this._settings.stringSpace+2*(this._settings.dot.radius+this._settings.dot.borderWidth),h=c<=1?0:9+this._settings.neck.baseFretMargin,l=d+h,p=g*this._settings.fretSpace,u=this._settings.neck.stringNameVisible?10+this._settings.neck.stringNameMargin:0,f=c>1?0:this._settings.neck.nutWidth,_=4+this._settings.dot.openStringRadius+this._settings.dot.stringInfoMargin+this._settings.dot.borderWidth,m=p+u+f+_;var S=s.createSVGElement("svg",{class:"chordproject-diagram",width:"100%",preserveAspectRatio:"xMinYMin meet",viewBox:`0 0 ${l} ${m}`});const b=h+this._settings.dot.radius,k=f+_;var x=s.createSVGElement("g",{transform:`translate(${b}, ${k})`});const y=new i(this._settings);return x.appendChild(y.build(a,o,g,c)),t.barres.length>0&&t.barres.forEach((t=>{const e=new n(this._settings);x.appendChild(e.build(t.fret,t.startString,t.endString))})),this.onlyDots(t).forEach((e=>{const s=new r(this._settings),i=t.fingers?t.fingers[e.fret]:0;x.appendChild(s.build(e.fret,e.value,i,1===t.baseFret))})),S.appendChild(x),S}onlyDots(t){return t.frets.map(((t,e)=>({fret:e,value:t})))}}class g{constructor(t){this.frets=[],this.fingers=[],this.baseFret=1,Object.assign(this,t)}get barres(){let t=[];if(0==this.fingers.filter((t=>t>0)).length)return[];let e=[];for(let t=0;t<this.frets.length;t++)e.push([this.frets[t],this.fingers[t]]);return this.frets.filter(((t,e,s)=>t>0&&s.indexOf(t)===e)).sort(((t,e)=>t-e)).forEach((s=>{for(let i=0;i<e.length;i++){const n=e[i];if(n[0]!==s)continue;const r=i,a=n[1];let o=1;for(;++i<e.length&&(e[i][0]>=s||-1===e[i][0]);)if(e[i][0]===s){if(e[i][1]!==a)continue;o++}o>1&&t.push({fret:s,startString:r,endString:i-1})}})),t}}class c{constructor(t,e,s,i){this.name=t,this.stringsCount=e,this.fretsOnDiagram=s,this.tuning=i}}return e})()}));