@guitar-chords/svg
Advanced tools
Comparing version 0.0.6 to 0.0.7
/*! | ||
* @guitar-chords/svg version 0.0.6 | ||
* @guitar-chords/svg version 0.0.7 | ||
* Author: Capricorncd<capricorncd@qq.com> | ||
* Homepage: https://github.com/capricorncd/guitar-chords | ||
* Released on: 2024-10-28 21:34:20 (GMT+0900) | ||
* Released on: 2024-11-07 21:37:30 (GMT+0900) | ||
*/ | ||
@@ -29,3 +29,2 @@ var E = (h) => { | ||
// stringLineWidth: LINE_WIDTH, | ||
stringCount: 6, | ||
fingerRadius: 15, | ||
@@ -44,3 +43,3 @@ // fingerCircleColor: '', | ||
showNotesOutsideOfChords: !1 | ||
}, m = (h, t = {}, e) => { | ||
}, $ = (h, t = {}, e) => { | ||
const i = document.createElementNS("http://www.w3.org/2000/svg", h); | ||
@@ -51,9 +50,9 @@ for (const [n, r] of Object.entries(t)) | ||
}; | ||
var L, p, z, d, A, I, P, v, j, B, G, D; | ||
var L, p, z, a, A, I, P, v, j, B, G, D; | ||
class K { | ||
constructor(t = {}) { | ||
k(this, d); | ||
k(this, a); | ||
k(this, L); | ||
k(this, p); | ||
k(this, z, "0.0.6"); | ||
k(this, z, "0.0.7"); | ||
N(this, L, { | ||
@@ -64,7 +63,17 @@ ...q, | ||
const { autoRender: e } = o(this, L); | ||
N(this, p, m("svg")), e && S(this, d, A).call(this); | ||
N(this, p, $("svg")), e && S(this, a, A).call(this); | ||
} | ||
/** | ||
* @property element | ||
* 获取Canvas元素 | ||
* @returns `SVGElement` | ||
*/ | ||
get element() { | ||
return o(this, p); | ||
} | ||
/** | ||
* @property width | ||
* 获取和弦的宽度 | ||
* @returns `number` | ||
*/ | ||
get width() { | ||
@@ -74,2 +83,7 @@ const { stringCount: t, stringSpacing: e, stringLineWidth: i } = this.data; | ||
} | ||
/** | ||
* @property height | ||
* 获取和弦的高度 | ||
* @returns `number` | ||
*/ | ||
get height() { | ||
@@ -87,3 +101,5 @@ const { | ||
/** | ||
* 网格尺寸 | ||
* @property gridRect | ||
* 获取网格的尺寸及位置信息。 | ||
* @returns `GridRect` 见[GridRect](#gridrect-1) | ||
*/ | ||
@@ -98,11 +114,11 @@ get gridRect() { | ||
spacing: s, | ||
fretsSpacing: l, | ||
fretsLineWidth: a, | ||
nameFontSize: g | ||
fretsSpacing: d, | ||
fretsLineWidth: l, | ||
nameFontSize: c | ||
} = this.data; | ||
return { | ||
width: e * (n - 1) + i * n, | ||
height: t + (l + a) * r.length, | ||
height: t + (d + l) * r.length, | ||
left: e, | ||
top: g + s, | ||
top: c + s, | ||
right: this.width - e, | ||
@@ -112,48 +128,60 @@ bottom: this.height | ||
} | ||
/** | ||
* @property version | ||
* 获取当前版本 | ||
* @returns `string` 版本号,比如`1.0.0` | ||
*/ | ||
get version() { | ||
return o(this, z); | ||
} | ||
/** | ||
* @property data | ||
* 获取和弦的数据 | ||
* @returns `GuitarChordsData` 见[GuitarChordsData](#GuitarChordsData) | ||
*/ | ||
get data() { | ||
const { defaultColor: t, defaultLineWidth: e, fingerRadius: i } = o(this, L), { | ||
nameTextColor: n = t, | ||
nutLineWidth: r = e, | ||
nutColor: s = t, | ||
const { defaultColor: t, defaultLineWidth: e, fingerRadius: i, matrix: n } = o(this, L), { | ||
nameTextColor: r = t, | ||
nutLineWidth: s = e, | ||
nutColor: d = t, | ||
fretsColor: l = t, | ||
fretsLineWidth: a = e, | ||
fretsLineWidth: c = e, | ||
stringColor: g = t, | ||
stringLineWidth: c = e, | ||
fingerCircleColor: $ = t, | ||
startFretsTextColor: u = t, | ||
transposeTextColor: w = n, | ||
notesOutsideOfChords: y = {}, | ||
stringLineWidth: m = e, | ||
fingerCircleColor: u = t, | ||
startFretsTextColor: w = t, | ||
transposeTextColor: W = r, | ||
notesOutsideOfChords: b = {}, | ||
showNotesOutsideOfChords: O, | ||
crossLineWidth: W = Math.min(c, a), | ||
crossLineColor: f = t, | ||
crossLineWidth: f = Math.min(m, c), | ||
crossLineColor: x = t, | ||
crossRadius: C = i * 0.75, | ||
nameLetterSpacing: x = 0 | ||
nameLetterSpacing: y = 0 | ||
} = o(this, L); | ||
return { | ||
...o(this, L), | ||
nameTextColor: n, | ||
nutLineWidth: r, | ||
nutColor: s, | ||
nameTextColor: r, | ||
nutLineWidth: s, | ||
nutColor: d, | ||
fretsColor: l, | ||
fretsLineWidth: a, | ||
fretsLineWidth: c, | ||
stringColor: g, | ||
stringLineWidth: c, | ||
fingerCircleColor: $, | ||
startFretsTextColor: u, | ||
transposeTextColor: w, | ||
notesOutsideOfChords: y, | ||
showNotesOutsideOfChords: O || Object.keys(y).length > 0, | ||
crossLineWidth: W, | ||
crossLineColor: f, | ||
stringLineWidth: m, | ||
fingerCircleColor: u, | ||
startFretsTextColor: w, | ||
transposeTextColor: W, | ||
notesOutsideOfChords: b, | ||
showNotesOutsideOfChords: O || Object.keys(b).length > 0, | ||
crossLineWidth: f, | ||
crossLineColor: x, | ||
crossRadius: C, | ||
nameLetterSpacing: x | ||
nameLetterSpacing: y, | ||
stringCount: n[0].length ?? 6 | ||
}; | ||
} | ||
/** | ||
* 重新绘制 | ||
* @param options 和弦配置选项 | ||
* @returns | ||
* @method render(options) | ||
* 重新渲染和弦图 | ||
* @param options? `Partial<GuitarChordsOptions>` 和弦实例化选项,见[GuitarChordsOptions](#GuitarChordsOptions) | ||
* @returns `GuitarChords` | ||
*/ | ||
@@ -164,8 +192,8 @@ render(t) { | ||
...t | ||
}), o(this, p).innerHTML = "", S(this, d, A).call(this), this; | ||
}), o(this, p).innerHTML = "", S(this, a, A).call(this), this; | ||
} | ||
} | ||
L = new WeakMap(), p = new WeakMap(), z = new WeakMap(), d = new WeakSet(), A = function() { | ||
L = new WeakMap(), p = new WeakMap(), z = new WeakMap(), a = new WeakSet(), A = function() { | ||
const t = this.data, { width: e, height: i } = this; | ||
o(this, p).setAttribute("width", `${e}`), o(this, p).setAttribute("height", `${i}`), o(this, p).setAttribute("viewBox", `0 0 ${e} ${i}`), S(this, d, B).call(this, t), S(this, d, j).call(this, t), S(this, d, P).call(this, t), S(this, d, I).call(this, t), t.showNotesOutsideOfChords && S(this, d, G).call(this, t); | ||
o(this, p).setAttribute("width", `${e}`), o(this, p).setAttribute("height", `${i}`), o(this, p).setAttribute("viewBox", `0 0 ${e} ${i}`), S(this, a, B).call(this, t), S(this, a, j).call(this, t), S(this, a, P).call(this, t), S(this, a, I).call(this, t), t.showNotesOutsideOfChords && S(this, a, G).call(this, t); | ||
}, I = function(t) { | ||
@@ -178,8 +206,8 @@ const { | ||
transpose: s, | ||
nameLetterSpacing: l | ||
} = t, a = !!s, g = n / 2, c = m("text", { | ||
nameLetterSpacing: d | ||
} = t, l = !!s, c = n / 2, g = $("text", { | ||
// 变调时,x向左偏移1/4文字大小(1/2变调符号字体大小) | ||
x: this.width / 2 - (a ? g / 2 : 0), | ||
x: this.width / 2 - (l ? c / 2 : 0), | ||
// y偏移字体大小的20%,使变调符号可以全部显示 | ||
y: n / 2 + g * 0.2, | ||
y: n / 2 + c * 0.2, | ||
fill: i, | ||
@@ -190,8 +218,8 @@ "font-size": n, | ||
}); | ||
o(this, p).appendChild(c), a && c.append( | ||
m( | ||
o(this, p).appendChild(g), l && g.append( | ||
$( | ||
"tspan", | ||
{ | ||
fill: r, | ||
style: `font-size: ${g}px;`, | ||
style: `font-size: ${c}px;`, | ||
"alignment-baseline": "middle", | ||
@@ -203,6 +231,6 @@ "baseline-shift": "super" | ||
); | ||
const $ = m( | ||
const m = $( | ||
"tspan", | ||
{ | ||
style: `letter-spacing:${l}px;`, | ||
style: `letter-spacing:${d}px;`, | ||
"alignment-baseline": "middle" | ||
@@ -212,5 +240,5 @@ }, | ||
); | ||
c.append($), setTimeout(() => { | ||
const u = this.gridRect.width, { width: w } = $.getBBox(); | ||
w > u && ($.setAttribute("textLength", String(u)), $.setAttribute("lengthAdjust", "spacingAndGlyphs")); | ||
g.append(m), setTimeout(() => { | ||
const u = this.gridRect.width, { width: w } = m.getBBox(); | ||
w > u && (m.setAttribute("textLength", String(u)), m.setAttribute("lengthAdjust", "spacingAndGlyphs")); | ||
}, 0); | ||
@@ -224,21 +252,21 @@ }, P = function(t) { | ||
spacing: s, | ||
matrix: l, | ||
fretsSpacing: a, | ||
fretsLineWidth: g, | ||
nameFontSize: c, | ||
nutLineWidth: $, | ||
matrix: d, | ||
fretsSpacing: l, | ||
fretsLineWidth: c, | ||
nameFontSize: g, | ||
nutLineWidth: m, | ||
fingerNumberTextColor: u, | ||
showFingerNumber: w, | ||
mergeFingerCircle: y | ||
} = t, O = r * 1.5, W = /* @__PURE__ */ new Map(); | ||
for (let f = 0; f < l.length; f++) | ||
for (let C = 0; C < l[f].length; C++) { | ||
const x = l[f][C]; | ||
if (x > 0) { | ||
const b = C * (e + n) + n / 2 + e, F = (f + 0.5) * (a + g) + g / 2 + c + s + $ - g; | ||
if (y) { | ||
W.has(x) || W.set(x, []); | ||
const R = W.get(x); | ||
if (R.push({ x: b, y: F }), R.length > 1 && C === l[f].lastIndexOf(x)) { | ||
const M = R[0], _ = { x: b, y: F }, V = m("line", { | ||
mergeFingerCircle: W | ||
} = t, b = r * 1.5, O = /* @__PURE__ */ new Map(); | ||
for (let f = 0; f < d.length; f++) | ||
for (let x = 0; x < d[f].length; x++) { | ||
const C = d[f][x]; | ||
if (C > 0) { | ||
const y = x * (e + n) + n / 2 + e, F = (f + 0.5) * (l + c) + c / 2 + g + s + m - c; | ||
if (W) { | ||
O.has(C) || O.set(C, []); | ||
const R = O.get(C); | ||
if (R.push({ x: y, y: F }), R.length > 1 && x === d[f].lastIndexOf(C)) { | ||
const M = R[0], _ = { x: y, y: F }, V = $("line", { | ||
x1: `${M.x}`, | ||
@@ -252,8 +280,8 @@ y1: `${M.y}`, | ||
}); | ||
o(this, p).appendChild(V), w && S(this, d, v).call(this, b, F, x, u, O); | ||
o(this, p).appendChild(V), w && S(this, a, v).call(this, y, F, C, u, b); | ||
continue; | ||
} | ||
} | ||
const H = m("circle", { | ||
cx: `${b}`, | ||
const H = $("circle", { | ||
cx: `${y}`, | ||
cy: `${F}`, | ||
@@ -263,3 +291,3 @@ r: `${r}`, | ||
}); | ||
o(this, p).appendChild(H), w && (!y || C === l[f].lastIndexOf(x)) && S(this, d, v).call(this, b, F, x, u, O); | ||
o(this, p).appendChild(H), w && (!W || x === d[f].lastIndexOf(C)) && S(this, a, v).call(this, y, F, C, u, b); | ||
} | ||
@@ -269,3 +297,3 @@ } | ||
v = function(t, e, i, n, r) { | ||
const s = m( | ||
const s = $( | ||
"text", | ||
@@ -290,12 +318,12 @@ { | ||
fretsLineWidth: s, | ||
fretsSpacing: l | ||
fretsSpacing: d | ||
} = t; | ||
if (i <= 1) return; | ||
const a = n / 2, g = m( | ||
const l = n / 2, c = $( | ||
"text", | ||
{ | ||
x: "0", | ||
y: `${this.gridRect.top + r + l / 2 + s * 2}`, | ||
y: `${this.gridRect.top + r + d / 2 + s * 2}`, | ||
fill: e, | ||
"font-size": `${a}`, | ||
"font-size": `${l}`, | ||
"font-style": "italic" | ||
@@ -305,3 +333,3 @@ }, | ||
); | ||
o(this, p).appendChild(g); | ||
o(this, p).appendChild(c); | ||
}, B = function(t) { | ||
@@ -314,30 +342,30 @@ const { | ||
stringCount: s, | ||
fretsSpacing: l, | ||
fretsLineWidth: a, | ||
fretsColor: g, | ||
nutLineWidth: c, | ||
nutColor: $ | ||
} = t, u = e.length, { top: w, bottom: y, right: O, left: W } = this.gridRect; | ||
fretsSpacing: d, | ||
fretsLineWidth: l, | ||
fretsColor: c, | ||
nutLineWidth: g, | ||
nutColor: m | ||
} = t, u = e.length, { top: w, bottom: W, right: b, left: O } = this.gridRect; | ||
for (let f = 0; f < s; f++) { | ||
const C = f * (n + i) + i / 2 + n, x = m("line", { | ||
x1: `${C}`, | ||
const x = f * (n + i) + i / 2 + n, C = $("line", { | ||
x1: `${x}`, | ||
// 从琴枕横线下方 1/2 琴枕宽度开始 | ||
y1: `${w + c}`, | ||
x2: `${C}`, | ||
y2: `${y}`, | ||
y1: `${w + g}`, | ||
x2: `${x}`, | ||
y2: `${W}`, | ||
stroke: r, | ||
"stroke-width": `${i}` | ||
}); | ||
o(this, p).appendChild(x); | ||
o(this, p).appendChild(C); | ||
} | ||
for (let f = 0; f <= u; f++) { | ||
const C = f === 0, x = C ? w + c / 2 : f * (l + a) + w + c - a / 2, b = m("line", { | ||
x1: `${W}`, | ||
y1: `${x}`, | ||
x2: `${O}`, | ||
y2: `${x}`, | ||
stroke: C ? $ : g, | ||
"stroke-width": `${C ? c : a}` | ||
const x = f === 0, C = x ? w + g / 2 : f * (d + l) + w + g - l / 2, y = $("line", { | ||
x1: `${O}`, | ||
y1: `${C}`, | ||
x2: `${b}`, | ||
y2: `${C}`, | ||
stroke: x ? m : c, | ||
"stroke-width": `${x ? g : l}` | ||
}); | ||
o(this, p).appendChild(b); | ||
o(this, p).appendChild(y); | ||
} | ||
@@ -351,12 +379,12 @@ }, G = function(t) { | ||
crossRadius: s, | ||
crossLineColor: l, | ||
crossLineWidth: a | ||
} = t, g = this.gridRect.top; | ||
for (let c = 0; c < n; c++) { | ||
if (!S(this, d, D).call(this, c, t)) continue; | ||
const $ = c * (i + e) + e / 2 + i; | ||
if (r[n - c]) { | ||
const u = m("g", { | ||
transform: `translate(${$ - s}, ${g - s * 2}) rotate(45 ${s} ${s})` | ||
}), w = m("line", { | ||
crossLineColor: d, | ||
crossLineWidth: l | ||
} = t, c = this.gridRect.top; | ||
for (let g = 0; g < n; g++) { | ||
if (!S(this, a, D).call(this, g, t)) continue; | ||
const m = g * (i + e) + e / 2 + i; | ||
if (r[n - g]) { | ||
const u = $("g", { | ||
transform: `translate(${m - s}, ${c - s * 2}) rotate(45 ${s} ${s})` | ||
}), w = $("line", { | ||
x1: 0, | ||
@@ -366,8 +394,8 @@ y1: s, | ||
y2: s, | ||
stroke: l, | ||
"stroke-width": `${a}`, | ||
stroke: d, | ||
"stroke-width": `${l}`, | ||
"stroke-linecap": "round" | ||
}); | ||
u.appendChild(w); | ||
const y = m("line", { | ||
const W = $("line", { | ||
x1: s, | ||
@@ -377,15 +405,15 @@ y1: 0, | ||
y2: s * 2, | ||
stroke: l, | ||
"stroke-width": `${a}`, | ||
stroke: d, | ||
"stroke-width": `${l}`, | ||
"stroke-linecap": "round" | ||
}); | ||
u.appendChild(y), o(this, p).appendChild(u); | ||
u.appendChild(W), o(this, p).appendChild(u); | ||
} else { | ||
const u = m("circle", { | ||
cx: `${$}`, | ||
cy: `${g - s - a / 2}`, | ||
const u = $("circle", { | ||
cx: `${m}`, | ||
cy: `${c - s - l / 2}`, | ||
r: `${s}`, | ||
fill: "transparent", | ||
stroke: l, | ||
"stroke-width": `${a}` | ||
stroke: d, | ||
"stroke-width": `${l}` | ||
}); | ||
@@ -392,0 +420,0 @@ o(this, p).appendChild(u); |
/*! | ||
* @guitar-chords/svg version 0.0.6 | ||
* @guitar-chords/svg version 0.0.7 | ||
* Author: Capricorncd<capricorncd@qq.com> | ||
* Homepage: https://github.com/capricorncd/guitar-chords | ||
* Released on: 2024-10-28 21:34:20 (GMT+0900) | ||
* Released on: 2024-11-07 21:37:30 (GMT+0900) | ||
*/ | ||
(function(o,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(o=typeof globalThis<"u"?globalThis:o||self,a(o.GuitarChords={}))})(this,function(o){"use strict";var E=o=>{throw TypeError(o)};var A=(o,a,r)=>a.has(o)||E("Cannot "+r);var d=(o,a,r)=>(A(o,a,"read from private field"),r?r.call(o):a.get(o)),N=(o,a,r)=>a.has(o)?E("Cannot add the same private member more than once"):a instanceof WeakSet?a.add(o):a.set(o,r),R=(o,a,r,T)=>(A(o,a,"write to private field"),T?T.call(o,r):a.set(o,r),r),y=(o,a,r)=>(A(o,a,"access private method"),r);var L,u,z,l,M,I,B,j,D,H,V,q;const a={autoRender:!0,defaultColor:"#000",defaultLineWidth:4,transpose:0,name:"",nameFontSize:60,spacing:20,fretsSpacing:50,stringSpacing:30,stringCount:6,fingerRadius:15,fingerNumberTextColor:"#fff",showFingerNumber:!0,startFrets:0,matrix:[[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]],mergeFingerCircle:!1,showNotesOutsideOfChords:!1},r=(G,t={},e)=>{const i=document.createElementNS("http://www.w3.org/2000/svg",G);for(const[n,h]of Object.entries(t))!h&&h!==0||i.setAttribute(n,String(h));return e&&(i.textContent=String(e)),i};class T{constructor(t={}){N(this,l);N(this,L);N(this,u);N(this,z,"0.0.6");R(this,L,{...a,...t});const{autoRender:e}=d(this,L);R(this,u,r("svg")),e&&y(this,l,M).call(this)}get element(){return d(this,u)}get width(){const{stringCount:t,stringSpacing:e,stringLineWidth:i}=this.data;return e*(t+1)+i*t}get height(){const{nutLineWidth:t,fretsSpacing:e,fretsLineWidth:i,matrix:n,spacing:h,nameFontSize:s}=this.data;return t+(e+i)*n.length+s+h}get gridRect(){const{nutLineWidth:t,stringSpacing:e,stringLineWidth:i,stringCount:n,matrix:h,spacing:s,fretsSpacing:g,fretsLineWidth:c,nameFontSize:p}=this.data;return{width:e*(n-1)+i*n,height:t+(g+c)*h.length,left:e,top:p+s,right:this.width-e,bottom:this.height}}get version(){return d(this,z)}get data(){const{defaultColor:t,defaultLineWidth:e,fingerRadius:i}=d(this,L),{nameTextColor:n=t,nutLineWidth:h=e,nutColor:s=t,fretsColor:g=t,fretsLineWidth:c=e,stringColor:p=t,stringLineWidth:f=e,fingerCircleColor:w=t,startFretsTextColor:x=t,transposeTextColor:S=n,notesOutsideOfChords:b={},showNotesOutsideOfChords:F,crossLineWidth:O=Math.min(f,c),crossLineColor:C=t,crossRadius:m=i*.75,nameLetterSpacing:$=0}=d(this,L);return{...d(this,L),nameTextColor:n,nutLineWidth:h,nutColor:s,fretsColor:g,fretsLineWidth:c,stringColor:p,stringLineWidth:f,fingerCircleColor:w,startFretsTextColor:x,transposeTextColor:S,notesOutsideOfChords:b,showNotesOutsideOfChords:F||Object.keys(b).length>0,crossLineWidth:O,crossLineColor:C,crossRadius:m,nameLetterSpacing:$}}render(t){return t&&R(this,L,{...d(this,L),...t}),d(this,u).innerHTML="",y(this,l,M).call(this),this}}L=new WeakMap,u=new WeakMap,z=new WeakMap,l=new WeakSet,M=function(){const t=this.data,{width:e,height:i}=this;d(this,u).setAttribute("width",`${e}`),d(this,u).setAttribute("height",`${i}`),d(this,u).setAttribute("viewBox",`0 0 ${e} ${i}`),y(this,l,H).call(this,t),y(this,l,D).call(this,t),y(this,l,B).call(this,t),y(this,l,I).call(this,t),t.showNotesOutsideOfChords&&y(this,l,V).call(this,t)},I=function(t){const{name:e,nameTextColor:i,nameFontSize:n,transposeTextColor:h,transpose:s,nameLetterSpacing:g}=t,c=!!s,p=n/2,f=r("text",{x:this.width/2-(c?p/2:0),y:n/2+p*.2,fill:i,"font-size":n,"text-anchor":"middle","dominant-baseline":"middle"});d(this,u).appendChild(f),c&&f.append(r("tspan",{fill:h,style:`font-size: ${p}px;`,"alignment-baseline":"middle","baseline-shift":"super"},s===1?"♯":"♭"));const w=r("tspan",{style:`letter-spacing:${g}px;`,"alignment-baseline":"middle"},e);f.append(w),setTimeout(()=>{const x=this.gridRect.width,{width:S}=w.getBBox();S>x&&(w.setAttribute("textLength",String(x)),w.setAttribute("lengthAdjust","spacingAndGlyphs"))},0)},B=function(t){const{stringSpacing:e,fingerCircleColor:i,stringLineWidth:n,fingerRadius:h,spacing:s,matrix:g,fretsSpacing:c,fretsLineWidth:p,nameFontSize:f,nutLineWidth:w,fingerNumberTextColor:x,showFingerNumber:S,mergeFingerCircle:b}=t,F=h*1.5,O=new Map;for(let C=0;C<g.length;C++)for(let m=0;m<g[C].length;m++){const $=g[C][m];if($>0){const W=m*(e+n)+n/2+e,k=(C+.5)*(c+p)+p/2+f+s+w-p;if(b){O.has($)||O.set($,[]);const v=O.get($);if(v.push({x:W,y:k}),v.length>1&&m===g[C].lastIndexOf($)){const P=v[0],_={x:W,y:k},K=r("line",{x1:`${P.x}`,y1:`${P.y}`,x2:`${_.x}`,y2:`${_.y}`,stroke:i,"stroke-width":`${h*2}`,"stroke-linecap":"round"});d(this,u).appendChild(K),S&&y(this,l,j).call(this,W,k,$,x,F);continue}}const J=r("circle",{cx:`${W}`,cy:`${k}`,r:`${h}`,fill:i});d(this,u).appendChild(J),S&&(!b||m===g[C].lastIndexOf($))&&y(this,l,j).call(this,W,k,$,x,F)}}},j=function(t,e,i,n,h){const s=r("text",{x:`${t}`,y:`${e}`,fill:n,"font-size":`${h}`,"text-anchor":"middle","dominant-baseline":"central"},i);d(this,u).appendChild(s)},D=function(t){const{startFretsTextColor:e,startFrets:i,nameFontSize:n,nutLineWidth:h,fretsLineWidth:s,fretsSpacing:g}=t;if(i<=1)return;const c=n/2,p=r("text",{x:"0",y:`${this.gridRect.top+h+g/2+s*2}`,fill:e,"font-size":`${c}`,"font-style":"italic"},i);d(this,u).appendChild(p)},H=function(t){const{matrix:e,stringLineWidth:i,stringSpacing:n,stringColor:h,stringCount:s,fretsSpacing:g,fretsLineWidth:c,fretsColor:p,nutLineWidth:f,nutColor:w}=t,x=e.length,{top:S,bottom:b,right:F,left:O}=this.gridRect;for(let C=0;C<s;C++){const m=C*(n+i)+i/2+n,$=r("line",{x1:`${m}`,y1:`${S+f}`,x2:`${m}`,y2:`${b}`,stroke:h,"stroke-width":`${i}`});d(this,u).appendChild($)}for(let C=0;C<=x;C++){const m=C===0,$=m?S+f/2:C*(g+c)+S+f-c/2,W=r("line",{x1:`${O}`,y1:`${$}`,x2:`${F}`,y2:`${$}`,stroke:m?w:p,"stroke-width":`${m?f:c}`});d(this,u).appendChild(W)}},V=function(t){const{stringLineWidth:e,stringSpacing:i,stringCount:n,notesOutsideOfChords:h,crossRadius:s,crossLineColor:g,crossLineWidth:c}=t,p=this.gridRect.top;for(let f=0;f<n;f++){if(!y(this,l,q).call(this,f,t))continue;const w=f*(i+e)+e/2+i;if(h[n-f]){const x=r("g",{transform:`translate(${w-s}, ${p-s*2}) rotate(45 ${s} ${s})`}),S=r("line",{x1:0,y1:s,x2:s*2,y2:s,stroke:g,"stroke-width":`${c}`,"stroke-linecap":"round"});x.appendChild(S);const b=r("line",{x1:s,y1:0,x2:s,y2:s*2,stroke:g,"stroke-width":`${c}`,"stroke-linecap":"round"});x.appendChild(b),d(this,u).appendChild(x)}else{const x=r("circle",{cx:`${w}`,cy:`${p-s-c/2}`,r:`${s}`,fill:"transparent",stroke:g,"stroke-width":`${c}`});d(this,u).appendChild(x)}}},q=function(t,e){const{matrix:i}=e;for(let n=0;n<i.length;n++)if(i[n][t]>0)return!1;return!0},o.GuitarChords=T,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})}); | ||
(function(o,a){typeof exports=="object"&&typeof module<"u"?a(exports):typeof define=="function"&&define.amd?define(["exports"],a):(o=typeof globalThis<"u"?globalThis:o||self,a(o.GuitarChords={}))})(this,function(o){"use strict";var E=o=>{throw TypeError(o)};var A=(o,a,r)=>a.has(o)||E("Cannot "+r);var d=(o,a,r)=>(A(o,a,"read from private field"),r?r.call(o):a.get(o)),N=(o,a,r)=>a.has(o)?E("Cannot add the same private member more than once"):a instanceof WeakSet?a.add(o):a.set(o,r),R=(o,a,r,T)=>(A(o,a,"write to private field"),T?T.call(o,r):a.set(o,r),r),y=(o,a,r)=>(A(o,a,"access private method"),r);var L,u,z,l,M,I,B,j,D,H,V,q;const a={autoRender:!0,defaultColor:"#000",defaultLineWidth:4,transpose:0,name:"",nameFontSize:60,spacing:20,fretsSpacing:50,stringSpacing:30,fingerRadius:15,fingerNumberTextColor:"#fff",showFingerNumber:!0,startFrets:0,matrix:[[0,0,0,0,0,0],[0,0,0,0,0,0],[0,0,0,0,0,0]],mergeFingerCircle:!1,showNotesOutsideOfChords:!1},r=(G,t={},e)=>{const i=document.createElementNS("http://www.w3.org/2000/svg",G);for(const[n,h]of Object.entries(t))!h&&h!==0||i.setAttribute(n,String(h));return e&&(i.textContent=String(e)),i};class T{constructor(t={}){N(this,l);N(this,L);N(this,u);N(this,z,"0.0.7");R(this,L,{...a,...t});const{autoRender:e}=d(this,L);R(this,u,r("svg")),e&&y(this,l,M).call(this)}get element(){return d(this,u)}get width(){const{stringCount:t,stringSpacing:e,stringLineWidth:i}=this.data;return e*(t+1)+i*t}get height(){const{nutLineWidth:t,fretsSpacing:e,fretsLineWidth:i,matrix:n,spacing:h,nameFontSize:s}=this.data;return t+(e+i)*n.length+s+h}get gridRect(){const{nutLineWidth:t,stringSpacing:e,stringLineWidth:i,stringCount:n,matrix:h,spacing:s,fretsSpacing:c,fretsLineWidth:g,nameFontSize:f}=this.data;return{width:e*(n-1)+i*n,height:t+(c+g)*h.length,left:e,top:f+s,right:this.width-e,bottom:this.height}}get version(){return d(this,z)}get data(){const{defaultColor:t,defaultLineWidth:e,fingerRadius:i,matrix:n}=d(this,L),{nameTextColor:h=t,nutLineWidth:s=e,nutColor:c=t,fretsColor:g=t,fretsLineWidth:f=e,stringColor:p=t,stringLineWidth:w=e,fingerCircleColor:x=t,startFretsTextColor:S=t,transposeTextColor:O=h,notesOutsideOfChords:W={},showNotesOutsideOfChords:F,crossLineWidth:C=Math.min(w,f),crossLineColor:m=t,crossRadius:$=i*.75,nameLetterSpacing:b=0}=d(this,L);return{...d(this,L),nameTextColor:h,nutLineWidth:s,nutColor:c,fretsColor:g,fretsLineWidth:f,stringColor:p,stringLineWidth:w,fingerCircleColor:x,startFretsTextColor:S,transposeTextColor:O,notesOutsideOfChords:W,showNotesOutsideOfChords:F||Object.keys(W).length>0,crossLineWidth:C,crossLineColor:m,crossRadius:$,nameLetterSpacing:b,stringCount:n[0].length??6}}render(t){return t&&R(this,L,{...d(this,L),...t}),d(this,u).innerHTML="",y(this,l,M).call(this),this}}L=new WeakMap,u=new WeakMap,z=new WeakMap,l=new WeakSet,M=function(){const t=this.data,{width:e,height:i}=this;d(this,u).setAttribute("width",`${e}`),d(this,u).setAttribute("height",`${i}`),d(this,u).setAttribute("viewBox",`0 0 ${e} ${i}`),y(this,l,H).call(this,t),y(this,l,D).call(this,t),y(this,l,B).call(this,t),y(this,l,I).call(this,t),t.showNotesOutsideOfChords&&y(this,l,V).call(this,t)},I=function(t){const{name:e,nameTextColor:i,nameFontSize:n,transposeTextColor:h,transpose:s,nameLetterSpacing:c}=t,g=!!s,f=n/2,p=r("text",{x:this.width/2-(g?f/2:0),y:n/2+f*.2,fill:i,"font-size":n,"text-anchor":"middle","dominant-baseline":"middle"});d(this,u).appendChild(p),g&&p.append(r("tspan",{fill:h,style:`font-size: ${f}px;`,"alignment-baseline":"middle","baseline-shift":"super"},s===1?"♯":"♭"));const w=r("tspan",{style:`letter-spacing:${c}px;`,"alignment-baseline":"middle"},e);p.append(w),setTimeout(()=>{const x=this.gridRect.width,{width:S}=w.getBBox();S>x&&(w.setAttribute("textLength",String(x)),w.setAttribute("lengthAdjust","spacingAndGlyphs"))},0)},B=function(t){const{stringSpacing:e,fingerCircleColor:i,stringLineWidth:n,fingerRadius:h,spacing:s,matrix:c,fretsSpacing:g,fretsLineWidth:f,nameFontSize:p,nutLineWidth:w,fingerNumberTextColor:x,showFingerNumber:S,mergeFingerCircle:O}=t,W=h*1.5,F=new Map;for(let C=0;C<c.length;C++)for(let m=0;m<c[C].length;m++){const $=c[C][m];if($>0){const b=m*(e+n)+n/2+e,k=(C+.5)*(g+f)+f/2+p+s+w-f;if(O){F.has($)||F.set($,[]);const v=F.get($);if(v.push({x:b,y:k}),v.length>1&&m===c[C].lastIndexOf($)){const P=v[0],_={x:b,y:k},K=r("line",{x1:`${P.x}`,y1:`${P.y}`,x2:`${_.x}`,y2:`${_.y}`,stroke:i,"stroke-width":`${h*2}`,"stroke-linecap":"round"});d(this,u).appendChild(K),S&&y(this,l,j).call(this,b,k,$,x,W);continue}}const J=r("circle",{cx:`${b}`,cy:`${k}`,r:`${h}`,fill:i});d(this,u).appendChild(J),S&&(!O||m===c[C].lastIndexOf($))&&y(this,l,j).call(this,b,k,$,x,W)}}},j=function(t,e,i,n,h){const s=r("text",{x:`${t}`,y:`${e}`,fill:n,"font-size":`${h}`,"text-anchor":"middle","dominant-baseline":"central"},i);d(this,u).appendChild(s)},D=function(t){const{startFretsTextColor:e,startFrets:i,nameFontSize:n,nutLineWidth:h,fretsLineWidth:s,fretsSpacing:c}=t;if(i<=1)return;const g=n/2,f=r("text",{x:"0",y:`${this.gridRect.top+h+c/2+s*2}`,fill:e,"font-size":`${g}`,"font-style":"italic"},i);d(this,u).appendChild(f)},H=function(t){const{matrix:e,stringLineWidth:i,stringSpacing:n,stringColor:h,stringCount:s,fretsSpacing:c,fretsLineWidth:g,fretsColor:f,nutLineWidth:p,nutColor:w}=t,x=e.length,{top:S,bottom:O,right:W,left:F}=this.gridRect;for(let C=0;C<s;C++){const m=C*(n+i)+i/2+n,$=r("line",{x1:`${m}`,y1:`${S+p}`,x2:`${m}`,y2:`${O}`,stroke:h,"stroke-width":`${i}`});d(this,u).appendChild($)}for(let C=0;C<=x;C++){const m=C===0,$=m?S+p/2:C*(c+g)+S+p-g/2,b=r("line",{x1:`${F}`,y1:`${$}`,x2:`${W}`,y2:`${$}`,stroke:m?w:f,"stroke-width":`${m?p:g}`});d(this,u).appendChild(b)}},V=function(t){const{stringLineWidth:e,stringSpacing:i,stringCount:n,notesOutsideOfChords:h,crossRadius:s,crossLineColor:c,crossLineWidth:g}=t,f=this.gridRect.top;for(let p=0;p<n;p++){if(!y(this,l,q).call(this,p,t))continue;const w=p*(i+e)+e/2+i;if(h[n-p]){const x=r("g",{transform:`translate(${w-s}, ${f-s*2}) rotate(45 ${s} ${s})`}),S=r("line",{x1:0,y1:s,x2:s*2,y2:s,stroke:c,"stroke-width":`${g}`,"stroke-linecap":"round"});x.appendChild(S);const O=r("line",{x1:s,y1:0,x2:s,y2:s*2,stroke:c,"stroke-width":`${g}`,"stroke-linecap":"round"});x.appendChild(O),d(this,u).appendChild(x)}else{const x=r("circle",{cx:`${w}`,cy:`${f-s-g/2}`,r:`${s}`,fill:"transparent",stroke:c,"stroke-width":`${g}`});d(this,u).appendChild(x)}}},q=function(t,e){const{matrix:i}=e;for(let n=0;n<i.length;n++)if(i[n][t]>0)return!1;return!0},o.GuitarChords=T,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})}); |
@@ -5,3 +5,3 @@ { | ||
"authors": "Capricorncd", | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"type": "module", | ||
@@ -8,0 +8,0 @@ "main": "./dist/guitar-chords.umd.js", |
157
README.md
@@ -7,2 +7,3 @@ # @guitar-chords/svg | ||
<a href="https://www.npmjs.com/package/@guitar-chords/svg"><img src="https://img.shields.io/npm/l/@guitar-chords/svg.svg?sanitize=true" alt="License"></a> | ||
<img src="https://img.shields.io/badge/styled_with-prettier-ff69b4.svg" /> | ||
</p> | ||
@@ -20,3 +21,5 @@ | ||
```ts | ||
`options` GuitarChords Instantiation Options, See [GuitarChordsOptions](#GuitarChordsOptions). | ||
```js | ||
import { GuitarChords } from '@guitar-chords/svg' | ||
@@ -30,16 +33,154 @@ | ||
[3, 4, 0, 0, 0, 0], | ||
] | ||
], | ||
}) | ||
// get canvas element and append to body | ||
document.querySelect('body').append(guitarChords.element) | ||
// get data | ||
console.log(guitarChords.data) | ||
``` | ||
document.body.appendChild(guitarChords.element) | ||
## Property | ||
### data | ||
Get the chord data. | ||
- @returns `GuitarChordsData` See [GuitarChordsData](#GuitarChordsData) | ||
### element | ||
Get the Svg element of the GuitarChords | ||
- @returns `SvgElement` | ||
### gridRect | ||
Get the size and position information of the chord grid. | ||
- @returns `GridRect` See [GridRect](#gridrect-1) | ||
### height | ||
Get the height of the chord | ||
- @returns `number` | ||
### version | ||
Get the version of the chord | ||
- @returns `string` version `1.0.0` | ||
### width | ||
Get the width of the chord | ||
- @returns `number` | ||
## Methods | ||
### render(options) | ||
Re-render the chord. | ||
Param|Types|Required|Description | ||
:--|:--|:--|:-- | ||
options|`Partial<GuitarChordsOptions>`|no|Chord instantiation options, see [GuitarChordsOptions](#GuitarChordsOptions) | ||
- @returns `GuitarChords` | ||
## Types | ||
### GridRect | ||
Grid size and position information. | ||
Prop|Types|Required|Description | ||
:--|:--|:--|:-- | ||
width|`number`|yes|Grid Width | ||
height|`number`|yes|Grid Height | ||
top|`number`|yes|The position of the top of the grid in the entire chord diagram | ||
right|`number`|yes|The position of the right of the grid in the entire chord diagram | ||
bottom|`number`|yes|The position of the bottom of the grid in the entire chord diagram | ||
left|`number`|yes|The position of the left of the grid in the entire chord diagram | ||
### GuitarChordsData | ||
Guitar Chords All Options (Configuration Data). | ||
Prop|Types|Required|Description | ||
:--|:--|:--|:-- | ||
autoRender|`boolean`|yes|Whether to automatically render when instantiated, the default is `true` | ||
defaultColor|`string`|yes|Default colors (except for the color of the finger number text) | ||
defaultLineWidth|`number`|yes|Default line width | ||
transpose|`number`|yes|Chord transposition value, `1` is a sharp semitone, `-1` is a flat semitone, default is `0` | ||
transposeTextColor|`string`|yes|The font color of the chord transposition symbol is the same as the chord name font color by default | ||
name|`string`|yes|Chord Name | ||
nameFontSize|`number`|yes|Chord name font size | ||
nameTextColor|`string`|yes|Chord Name Color | ||
nameLetterSpacing|`number`|yes|The spacing between chord name letters, default is `0` | ||
spacing|`number`|yes|Spacing between chord names and the chord grid | ||
nutLineWidth|`number`|yes|The width of the nut line (default is the value of lineWidth) | ||
nutColor|`string`|yes|Nut Line Color | ||
fretsSpacing|`number`|yes|Fret Line Spacing | ||
fretsColor|`string`|yes|Fret Line Color | ||
fretsLineWidth|`number`|yes|Fret Line Width | ||
stringSpacing|`number`|yes|String line spacing | ||
stringColor|`string`|yes|String line color | ||
stringLineWidth|`number`|yes|String line width | ||
fingerRadius|`number`|yes|Radius of the fingering dot | ||
fingerCircleColor|`string`|yes|Fingering dot color | ||
showFingerNumber|`boolean`|yes|Whether to display the finger number, the default is `true` | ||
fingerNumberTextColor|`string`|yes|Finger number font color, default `#fff` | ||
startFrets|`number`|yes|The starting fret of the chord, default is `0` | ||
startFretsTextColor|`string`|yes|Starting grade font color | ||
matrix|`number[][]`|yes|Matrix of chord fingerings and number of frets (2D array with rows representing chords and columns representing frets) | ||
mergeFingerCircle|`boolean`|yes|Whether to merge fingering dots when playing barre/barre, default is `false` | ||
showNotesOutsideOfChords|`boolean`|yes|Used to configure whether to display a small cross `x/o` at the head of the empty string column, the default is `false` | ||
notesOutsideOfChords|`Record<number, boolean>`|yes|Whether to display open strings as notes outside of chords option `{chord number (strings 1-6 for guitar): true or false}` | ||
crossLineWidth|`number`|yes|The line thickness of the notes `x/o` outside the chord is the default string line width. Its length is the diameter of the fingering dot | ||
crossLineColor|`string`|yes|Line color for the non-chord tones `x/o` | ||
crossRadius|`number`|yes|The radius of the chord outside the tone `x/o`, the default is `fingerRadius * 0.75` | ||
### GuitarChordsOptions | ||
Required configuration options for chord strength, see [GuitarChordsData](#GuitarChordsData) | ||
```ts | ||
interface GuitarChordsOptions { | ||
name: string; | ||
matrix: GuitarChordsData['matrix']; | ||
} | ||
``` | ||
## Options | ||
## Constants | ||
See [types.d.ts](./src/types.d.ts). | ||
Chord Default Options | ||
## API | ||
```ts | ||
{ | ||
autoRender: true, | ||
defaultColor: '#000', | ||
defaultLineWidth: 4, | ||
transpose: 0, | ||
nameFontSize: 60, | ||
spacing: 20, | ||
fretsSpacing: 50, | ||
stringSpacing: 30, | ||
fingerRadius: 15, | ||
showFingerNumber: true, | ||
fingerNumberTextColor: '#fff', | ||
startFrets: 0, | ||
matrix: [ | ||
[0, 0, 0, 0, 0, 0], | ||
[0, 0, 0, 0, 0, 0], | ||
[0, 0, 0, 0, 0, 0], | ||
], | ||
mergeFingerCircle: false, | ||
showNotesOutsideOfChords: false, | ||
} | ||
``` | ||
### `render(options?: Partial<GuitarChordsOptions>)` | ||
## Contributors | ||
Re-render the guitar chord. | ||
90% of the code for `version<=0.0.4` is completed by `Cursor` (The AI Code Editor) |
@@ -7,2 +7,7 @@ /** | ||
/** | ||
* @constant DEF_OPTIONS | ||
* @private | ||
* 和弦默认选项 | ||
*/ | ||
export const DEF_OPTIONS: DefaultOptions = { | ||
@@ -25,3 +30,2 @@ autoRender: true, | ||
// stringLineWidth: LINE_WIDTH, | ||
stringCount: 6, | ||
fingerRadius: 15, | ||
@@ -28,0 +32,0 @@ // fingerCircleColor: '', |
@@ -11,6 +11,28 @@ /** | ||
DefaultOptions, | ||
GridRect, | ||
} from './types' | ||
/** | ||
* @document 吉他和弦 | ||
* @document GuitarChords | ||
* | ||
* 用于创建一个Svg吉他和弦实例。 | ||
* | ||
* `options`和弦实例化选项,见[GuitarChordsOptions](#GuitarChordsOptions) | ||
* | ||
* ```js | ||
* import { GuitarChords } from '@guitar-chords/svg' | ||
* | ||
* const guitarChords = new GuitarChords({ | ||
* name: 'C', | ||
* matrix: [ | ||
* [0, 0, 0, 0, 1, 0], | ||
* [0, 0, 2, 0, 0, 0], | ||
* [3, 4, 0, 0, 0, 0], | ||
* ], | ||
* }) | ||
* // get canvas element and append to body | ||
* document.querySelect('body').append(guitarChords.element) | ||
* // get data | ||
* console.log(guitarChords.data) | ||
* ``` | ||
*/ | ||
@@ -33,2 +55,7 @@ export class GuitarChords { | ||
/** | ||
* @property element | ||
* 获取Canvas元素 | ||
* @returns `SVGElement` | ||
*/ | ||
get element() { | ||
@@ -38,2 +65,7 @@ return this.#element | ||
/** | ||
* @property width | ||
* 获取和弦的宽度 | ||
* @returns `number` | ||
*/ | ||
get width() { | ||
@@ -44,2 +76,7 @@ const { stringCount, stringSpacing, stringLineWidth } = this.data | ||
/** | ||
* @property height | ||
* 获取和弦的高度 | ||
* @returns `number` | ||
*/ | ||
get height() { | ||
@@ -63,5 +100,7 @@ const { | ||
/** | ||
* 网格尺寸 | ||
* @property gridRect | ||
* 获取网格的尺寸及位置信息。 | ||
* @returns `GridRect` 见[GridRect](#gridrect-1) | ||
*/ | ||
get gridRect() { | ||
get gridRect(): GridRect { | ||
const { | ||
@@ -88,2 +127,7 @@ nutLineWidth, | ||
/** | ||
* @property version | ||
* 获取当前版本 | ||
* @returns `string` 版本号,比如`1.0.0` | ||
*/ | ||
get version() { | ||
@@ -93,4 +137,10 @@ return this.#version | ||
/** | ||
* @property data | ||
* 获取和弦的数据 | ||
* @returns `GuitarChordsData` 见[GuitarChordsData](#GuitarChordsData) | ||
*/ | ||
get data(): GuitarChordsData { | ||
const { defaultColor, defaultLineWidth, fingerRadius } = this.#options | ||
const { defaultColor, defaultLineWidth, fingerRadius, matrix } = | ||
this.#options | ||
const { | ||
@@ -134,2 +184,3 @@ nameTextColor = defaultColor, | ||
nameLetterSpacing, | ||
stringCount: matrix[0].length ?? 6, | ||
} | ||
@@ -139,5 +190,6 @@ } | ||
/** | ||
* 重新绘制 | ||
* @param options 和弦配置选项 | ||
* @returns | ||
* @method render(options) | ||
* 重新渲染和弦图 | ||
* @param options? `Partial<GuitarChordsOptions>` 和弦实例化选项,见[GuitarChordsOptions](#GuitarChordsOptions) | ||
* @returns `GuitarChords` | ||
*/ | ||
@@ -144,0 +196,0 @@ render(options?: Partial<GuitarChordsOptions>) { |
@@ -8,3 +8,3 @@ /** | ||
* @type GuitarChordsData | ||
* 吉他和弦配置数据 | ||
* 吉他和弦配置数据。 | ||
*/ | ||
@@ -90,6 +90,6 @@ export interface GuitarChordsData { | ||
* @type GuitarChordsOptions | ||
* 和弦配置选项 | ||
* 和弦实力化时必须的配置选项,见[GuitarChordsData](#GuitarChordsData) | ||
*/ | ||
export type GuitarChordsOptions = OmitOptional< | ||
GuitarChordsData, | ||
Omit<GuitarChordsData, 'stringCount'>, | ||
'name' | 'matrix' | ||
@@ -102,3 +102,3 @@ > | ||
export type DefaultOptions = PickOptional< | ||
GuitarChordsData, | ||
Omit<GuitarChordsData, 'stringCount'>, | ||
| 'nameTextColor' | ||
@@ -120,1 +120,20 @@ | 'transposeTextColor' | ||
> | ||
/** | ||
* @type GridRect | ||
* 网格尺寸及位置信息。 | ||
*/ | ||
export interface GridRect { | ||
// 网格宽度 | ||
width: number | ||
// 网格高度 | ||
height: number | ||
// 网格顶部在整个和弦图中的位置 | ||
top: number | ||
// 网格右侧在整个和弦图中的位置 | ||
right: number | ||
// 网格底部在整个和弦图中的位置 | ||
bottom: number | ||
// 网格左侧在整个和弦图中的位置 | ||
left: number | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
44424
1161
184