@guitar-chords/svg
Advanced tools
Comparing version 0.0.5 to 0.0.6
/*! | ||
* @guitar-chords/svg version 0.0.5 | ||
* @guitar-chords/svg version 0.0.6 | ||
* Author: Capricorncd<capricorncd@qq.com> | ||
* Homepage: https://github.com/capricorncd/guitar-chords | ||
* Released on: 2024-10-27 21:15:06 (GMT+0900) | ||
* Released on: 2024-10-28 21:34:20 (GMT+0900) | ||
*/ | ||
var P = (o) => { | ||
throw TypeError(o); | ||
var E = (h) => { | ||
throw TypeError(h); | ||
}; | ||
var T = (o, t, e) => t.has(o) || P("Cannot " + e); | ||
var a = (o, t, e) => (T(o, t, "read from private field"), e ? e.call(o) : t.get(o)), k = (o, t, e) => t.has(o) ? P("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(o) : t.set(o, e), N = (o, t, e, i) => (T(o, t, "write to private field"), i ? i.call(o, e) : t.set(o, e), e), S = (o, t, e) => (T(o, t, "access private method"), e); | ||
var T = (h, t, e) => t.has(h) || E("Cannot " + e); | ||
var o = (h, t, e) => (T(h, t, "read from private field"), e ? e.call(h) : t.get(h)), k = (h, t, e) => t.has(h) ? E("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(h) : t.set(h, e), N = (h, t, e, i) => (T(h, t, "write to private field"), i ? i.call(h, e) : t.set(h, e), e), S = (h, t, e) => (T(h, t, "access private method"), e); | ||
const q = { | ||
@@ -18,5 +18,5 @@ autoRender: !0, | ||
name: "", | ||
nameFontSize: 50, | ||
nameFontSize: 60, | ||
// nameTextColor: '', | ||
spacing: 18, | ||
spacing: 20, | ||
// nutLineWidth: LINE_WIDTH, | ||
@@ -44,4 +44,4 @@ // nutColor: '', | ||
showNotesOutsideOfChords: !1 | ||
}, x = (o, t = {}, e) => { | ||
const i = document.createElementNS("http://www.w3.org/2000/svg", o); | ||
}, m = (h, t = {}, e) => { | ||
const i = document.createElementNS("http://www.w3.org/2000/svg", h); | ||
for (const [n, r] of Object.entries(t)) | ||
@@ -51,3 +51,3 @@ !r && r !== 0 || i.setAttribute(n, String(r)); | ||
}; | ||
var L, p, d, R, j, B, A, E, G, I, D; | ||
var L, p, z, d, A, I, P, v, j, B, G, D; | ||
class K { | ||
@@ -58,2 +58,3 @@ constructor(t = {}) { | ||
k(this, p); | ||
k(this, z, "0.0.6"); | ||
N(this, L, { | ||
@@ -63,7 +64,7 @@ ...q, | ||
}); | ||
const { autoRender: e } = a(this, L); | ||
N(this, p, x("svg")), e && S(this, d, R).call(this); | ||
const { autoRender: e } = o(this, L); | ||
N(this, p, m("svg")), e && S(this, d, A).call(this); | ||
} | ||
get element() { | ||
return a(this, p); | ||
return o(this, p); | ||
} | ||
@@ -75,3 +76,10 @@ get width() { | ||
get height() { | ||
const { nutLineWidth: t, fretsSpacing: e, fretsLineWidth: i, matrix: n, spacing: r, nameFontSize: s } = this.data; | ||
const { | ||
nutLineWidth: t, | ||
fretsSpacing: e, | ||
fretsLineWidth: i, | ||
matrix: n, | ||
spacing: r, | ||
nameFontSize: s | ||
} = this.data; | ||
return t + (e + i) * n.length + s + r; | ||
@@ -83,8 +91,18 @@ } | ||
get gridRect() { | ||
const { nutLineWidth: t, stringSpacing: e, stringLineWidth: i, stringCount: n, matrix: r, spacing: s, fretsSpacing: h, fretsLineWidth: c, nameFontSize: l } = this.data; | ||
const { | ||
nutLineWidth: t, | ||
stringSpacing: e, | ||
stringLineWidth: i, | ||
stringCount: n, | ||
matrix: r, | ||
spacing: s, | ||
fretsSpacing: l, | ||
fretsLineWidth: a, | ||
nameFontSize: g | ||
} = this.data; | ||
return { | ||
width: e * (n - 1) + i * n, | ||
height: t + (h + c) * r.length, | ||
height: t + (l + a) * r.length, | ||
left: e, | ||
top: l + s, | ||
top: g + s, | ||
right: this.width - e, | ||
@@ -94,37 +112,42 @@ bottom: this.height | ||
} | ||
get version() { | ||
return o(this, z); | ||
} | ||
get data() { | ||
const { defaultColor: t, defaultLineWidth: e } = a(this, L), { | ||
nameTextColor: i = t, | ||
nutLineWidth: n = e, | ||
nutColor: r = t, | ||
fretsColor: s = t, | ||
fretsLineWidth: h = e, | ||
stringColor: c = t, | ||
stringLineWidth: l = e, | ||
fingerCircleColor: g = t, | ||
startFretsTextColor: m = t, | ||
transposeTextColor: u = i, | ||
notesOutsideOfChords: C = {}, | ||
showNotesOutsideOfChords: y, | ||
crossLineWidth: O = Math.min(l, h), | ||
crossLineColor: W = t, | ||
nameLetterSpacing: f = 0 | ||
} = a(this, L); | ||
const { defaultColor: t, defaultLineWidth: e, fingerRadius: i } = o(this, L), { | ||
nameTextColor: n = t, | ||
nutLineWidth: r = e, | ||
nutColor: s = t, | ||
fretsColor: l = t, | ||
fretsLineWidth: a = e, | ||
stringColor: g = t, | ||
stringLineWidth: c = e, | ||
fingerCircleColor: $ = t, | ||
startFretsTextColor: u = t, | ||
transposeTextColor: w = n, | ||
notesOutsideOfChords: y = {}, | ||
showNotesOutsideOfChords: O, | ||
crossLineWidth: W = Math.min(c, a), | ||
crossLineColor: f = t, | ||
crossRadius: C = i * 0.75, | ||
nameLetterSpacing: x = 0 | ||
} = o(this, L); | ||
return { | ||
...a(this, L), | ||
nameTextColor: i, | ||
nutLineWidth: n, | ||
nutColor: r, | ||
fretsColor: s, | ||
fretsLineWidth: h, | ||
stringColor: c, | ||
stringLineWidth: l, | ||
fingerCircleColor: g, | ||
startFretsTextColor: m, | ||
transposeTextColor: u, | ||
notesOutsideOfChords: C, | ||
showNotesOutsideOfChords: y || Object.keys(C).length > 0, | ||
crossLineWidth: O, | ||
crossLineColor: W, | ||
nameLetterSpacing: f | ||
...o(this, L), | ||
nameTextColor: n, | ||
nutLineWidth: r, | ||
nutColor: s, | ||
fretsColor: l, | ||
fretsLineWidth: a, | ||
stringColor: g, | ||
stringLineWidth: c, | ||
fingerCircleColor: $, | ||
startFretsTextColor: u, | ||
transposeTextColor: w, | ||
notesOutsideOfChords: y, | ||
showNotesOutsideOfChords: O || Object.keys(y).length > 0, | ||
crossLineWidth: W, | ||
crossLineColor: f, | ||
crossRadius: C, | ||
nameLetterSpacing: x | ||
}; | ||
@@ -139,16 +162,23 @@ } | ||
return t && N(this, L, { | ||
...a(this, L), | ||
...o(this, L), | ||
...t | ||
}), a(this, p).innerHTML = "", S(this, d, R).call(this), this; | ||
}), o(this, p).innerHTML = "", S(this, d, A).call(this), this; | ||
} | ||
} | ||
L = new WeakMap(), p = new WeakMap(), d = new WeakSet(), R = function() { | ||
L = new WeakMap(), p = new WeakMap(), z = new WeakMap(), d = new WeakSet(), A = function() { | ||
const t = this.data, { width: e, height: i } = this; | ||
a(this, p).setAttribute("width", `${e}`), a(this, p).setAttribute("height", `${i}`), a(this, p).setAttribute("viewBox", `0 0 ${e} ${i}`), S(this, d, G).call(this, t), S(this, d, E).call(this, t), S(this, d, B).call(this, t), S(this, d, j).call(this, t), t.showNotesOutsideOfChords && S(this, d, I).call(this, t); | ||
}, j = function(t) { | ||
const { name: e, nameTextColor: i, nameFontSize: n, transposeTextColor: r, transpose: s, nameLetterSpacing: h } = t, c = !!s, l = n / 2, g = x("text", { | ||
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); | ||
}, I = function(t) { | ||
const { | ||
name: e, | ||
nameTextColor: i, | ||
nameFontSize: n, | ||
transposeTextColor: r, | ||
transpose: s, | ||
nameLetterSpacing: l | ||
} = t, a = !!s, g = n / 2, c = m("text", { | ||
// 变调时,x向左偏移1/4文字大小(1/2变调符号字体大小) | ||
x: this.width / 2 - (c ? l / 2 : 0), | ||
x: this.width / 2 - (a ? g / 2 : 0), | ||
// y偏移字体大小的20%,使变调符号可以全部显示 | ||
y: n / 2 + l * 0.2, | ||
y: n / 2 + g * 0.2, | ||
fill: i, | ||
@@ -159,8 +189,8 @@ "font-size": n, | ||
}); | ||
a(this, p).appendChild(g), c && g.append( | ||
x( | ||
o(this, p).appendChild(c), a && c.append( | ||
m( | ||
"tspan", | ||
{ | ||
fill: r, | ||
style: `font-size: ${l}px;`, | ||
style: `font-size: ${g}px;`, | ||
"alignment-baseline": "middle", | ||
@@ -172,26 +202,44 @@ "baseline-shift": "super" | ||
); | ||
const m = x("tspan", { | ||
style: `letter-spacing:${h}px;`, | ||
"alignment-baseline": "middle" | ||
}, e); | ||
g.append(m), setTimeout(() => { | ||
const u = this.gridRect.width, { width: C } = m.getBBox(); | ||
C > u && (m.setAttribute("textLength", String(u)), m.setAttribute("lengthAdjust", "spacingAndGlyphs")); | ||
const $ = m( | ||
"tspan", | ||
{ | ||
style: `letter-spacing:${l}px;`, | ||
"alignment-baseline": "middle" | ||
}, | ||
e | ||
); | ||
c.append($), setTimeout(() => { | ||
const u = this.gridRect.width, { width: w } = $.getBBox(); | ||
w > u && ($.setAttribute("textLength", String(u)), $.setAttribute("lengthAdjust", "spacingAndGlyphs")); | ||
}, 0); | ||
}, B = function(t) { | ||
const { stringSpacing: e, fingerCircleColor: i, stringLineWidth: n, fingerRadius: r, spacing: s, matrix: h, fretsSpacing: c, fretsLineWidth: l, nameFontSize: g, nutLineWidth: m, fingerNumberTextColor: u, showFingerNumber: C, mergeFingerCircle: y } = t, O = r * 1.5, W = /* @__PURE__ */ new Map(); | ||
for (let f = 0; f < h.length; f++) | ||
for (let $ = 0; $ < h[f].length; $++) { | ||
const w = h[f][$]; | ||
if (w > 0) { | ||
const b = $ * (e + n) + n / 2 + e, F = (f + 0.5) * (c + l) + l / 2 + g + s + m - l; | ||
}, P = function(t) { | ||
const { | ||
stringSpacing: e, | ||
fingerCircleColor: i, | ||
stringLineWidth: n, | ||
fingerRadius: r, | ||
spacing: s, | ||
matrix: l, | ||
fretsSpacing: a, | ||
fretsLineWidth: g, | ||
nameFontSize: c, | ||
nutLineWidth: $, | ||
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(w) || W.set(w, []); | ||
const z = W.get(w); | ||
if (z.push({ x: b, y: F }), z.length > 1 && $ === h[f].lastIndexOf(w)) { | ||
const v = z[0], M = { x: b, y: F }, _ = x("line", { | ||
x1: `${v.x}`, | ||
y1: `${v.y}`, | ||
x2: `${M.x}`, | ||
y2: `${M.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", { | ||
x1: `${M.x}`, | ||
y1: `${M.y}`, | ||
x2: `${_.x}`, | ||
y2: `${_.y}`, | ||
stroke: i, | ||
@@ -201,7 +249,7 @@ "stroke-width": `${r * 2}`, | ||
}); | ||
a(this, p).appendChild(_), C && S(this, d, A).call(this, b, F, w, u, O); | ||
o(this, p).appendChild(V), w && S(this, d, v).call(this, b, F, x, u, O); | ||
continue; | ||
} | ||
} | ||
const H = x("circle", { | ||
const H = m("circle", { | ||
cx: `${b}`, | ||
@@ -212,35 +260,61 @@ cy: `${F}`, | ||
}); | ||
a(this, p).appendChild(H), C && (!y || $ === h[f].lastIndexOf(w)) && S(this, d, A).call(this, b, F, w, u, O); | ||
o(this, p).appendChild(H), w && (!y || C === l[f].lastIndexOf(x)) && S(this, d, v).call(this, b, F, x, u, O); | ||
} | ||
} | ||
}, // 新增一个辅助方法来绘制指法编号 | ||
A = function(t, e, i, n, r) { | ||
const s = x("text", { | ||
x: `${t}`, | ||
y: `${e}`, | ||
fill: n, | ||
"font-size": `${r}`, | ||
"text-anchor": "middle", | ||
"dominant-baseline": "central" | ||
}, i); | ||
a(this, p).appendChild(s); | ||
}, E = function(t) { | ||
const { startFretsTextColor: e, startFrets: i, nameFontSize: n, nutLineWidth: r, fretsLineWidth: s, fretsSpacing: h } = t; | ||
v = function(t, e, i, n, r) { | ||
const s = m( | ||
"text", | ||
{ | ||
x: `${t}`, | ||
y: `${e}`, | ||
fill: n, | ||
"font-size": `${r}`, | ||
"text-anchor": "middle", | ||
"dominant-baseline": "central" | ||
}, | ||
i | ||
); | ||
o(this, p).appendChild(s); | ||
}, j = function(t) { | ||
const { | ||
startFretsTextColor: e, | ||
startFrets: i, | ||
nameFontSize: n, | ||
nutLineWidth: r, | ||
fretsLineWidth: s, | ||
fretsSpacing: l | ||
} = t; | ||
if (i <= 1) return; | ||
const c = n / 2, l = x("text", { | ||
x: "0", | ||
y: `${this.gridRect.top + r + h / 2 + s * 2}`, | ||
fill: e, | ||
"font-size": `${c}`, | ||
"font-style": "italic" | ||
}, i); | ||
a(this, p).appendChild(l); | ||
}, G = function(t) { | ||
const { matrix: e, stringLineWidth: i, stringSpacing: n, stringColor: r, stringCount: s, fretsSpacing: h, fretsLineWidth: c, fretsColor: l, nutLineWidth: g, nutColor: m } = t, u = e.length, { top: C, bottom: y, right: O, left: W } = this.gridRect; | ||
const a = n / 2, g = m( | ||
"text", | ||
{ | ||
x: "0", | ||
y: `${this.gridRect.top + r + l / 2 + s * 2}`, | ||
fill: e, | ||
"font-size": `${a}`, | ||
"font-style": "italic" | ||
}, | ||
i | ||
); | ||
o(this, p).appendChild(g); | ||
}, B = function(t) { | ||
const { | ||
matrix: e, | ||
stringLineWidth: i, | ||
stringSpacing: n, | ||
stringColor: r, | ||
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; | ||
for (let f = 0; f < s; f++) { | ||
const $ = f * (n + i) + i / 2 + n, w = x("line", { | ||
x1: `${$}`, | ||
const C = f * (n + i) + i / 2 + n, x = m("line", { | ||
x1: `${C}`, | ||
// 从琴枕横线下方 1/2 琴枕宽度开始 | ||
y1: `${C + g}`, | ||
x2: `${$}`, | ||
y1: `${w + c}`, | ||
x2: `${C}`, | ||
y2: `${y}`, | ||
@@ -250,53 +324,61 @@ stroke: r, | ||
}); | ||
a(this, p).appendChild(w); | ||
o(this, p).appendChild(x); | ||
} | ||
for (let f = 0; f <= u; f++) { | ||
const $ = f === 0, w = $ ? C + g / 2 : f * (h + c) + C + g - c / 2, b = x("line", { | ||
const C = f === 0, x = C ? w + c / 2 : f * (l + a) + w + c - a / 2, b = m("line", { | ||
x1: `${W}`, | ||
y1: `${w}`, | ||
y1: `${x}`, | ||
x2: `${O}`, | ||
y2: `${w}`, | ||
stroke: $ ? m : l, | ||
"stroke-width": `${$ ? g : c}` | ||
y2: `${x}`, | ||
stroke: C ? $ : g, | ||
"stroke-width": `${C ? c : a}` | ||
}); | ||
a(this, p).appendChild(b); | ||
o(this, p).appendChild(b); | ||
} | ||
}, I = function(t) { | ||
const { stringLineWidth: e, stringSpacing: i, stringCount: n, notesOutsideOfChords: r, fingerRadius: s, crossLineColor: h, crossLineWidth: c } = t, l = this.gridRect.top; | ||
for (let g = 0; g < n; g++) { | ||
if (!S(this, d, D).call(this, g, t)) continue; | ||
const m = g * (i + e) + e / 2 + i; | ||
if (r[n - g]) { | ||
const u = x("g", { | ||
transform: `translate(${m - s / 2}, ${l - s * 1.2})` | ||
}), C = x("line", { | ||
x1: "0", | ||
y1: "0", | ||
x2: `${s}`, | ||
y2: `${s}`, | ||
stroke: h, | ||
"stroke-width": `${c}`, | ||
}, G = function(t) { | ||
const { | ||
stringLineWidth: e, | ||
stringSpacing: i, | ||
stringCount: n, | ||
notesOutsideOfChords: r, | ||
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", { | ||
x1: 0, | ||
y1: s, | ||
x2: s * 2, | ||
y2: s, | ||
stroke: l, | ||
"stroke-width": `${a}`, | ||
"stroke-linecap": "round" | ||
}); | ||
u.appendChild(C); | ||
const y = x("line", { | ||
x1: "0", | ||
y1: `${s}`, | ||
x2: `${s}`, | ||
y2: "0", | ||
stroke: h, | ||
"stroke-width": `${c}`, | ||
u.appendChild(w); | ||
const y = m("line", { | ||
x1: s, | ||
y1: 0, | ||
x2: s, | ||
y2: s * 2, | ||
stroke: l, | ||
"stroke-width": `${a}`, | ||
"stroke-linecap": "round" | ||
}); | ||
u.appendChild(y), a(this, p).appendChild(u); | ||
u.appendChild(y), o(this, p).appendChild(u); | ||
} else { | ||
const u = s * 0.75, C = x("circle", { | ||
cx: `${m}`, | ||
cy: `${l - u * 1.1}`, | ||
r: `${u}`, | ||
const u = m("circle", { | ||
cx: `${$}`, | ||
cy: `${g - s - a / 2}`, | ||
r: `${s}`, | ||
fill: "transparent", | ||
stroke: h, | ||
"stroke-width": `${c}` | ||
stroke: l, | ||
"stroke-width": `${a}` | ||
}); | ||
a(this, p).appendChild(C); | ||
o(this, p).appendChild(u); | ||
} | ||
@@ -303,0 +385,0 @@ } |
/*! | ||
* @guitar-chords/svg version 0.0.5 | ||
* @guitar-chords/svg version 0.0.6 | ||
* Author: Capricorncd<capricorncd@qq.com> | ||
* Homepage: https://github.com/capricorncd/guitar-chords | ||
* Released on: 2024-10-27 21:15:06 (GMT+0900) | ||
* Released on: 2024-10-28 21:34:20 (GMT+0900) | ||
*/ | ||
(function(r,d){typeof exports=="object"&&typeof module<"u"?d(exports):typeof define=="function"&&define.amd?define(["exports"],d):(r=typeof globalThis<"u"?globalThis:r||self,d(r.GuitarChords={}))})(this,function(r){"use strict";var B=r=>{throw TypeError(r)};var A=(r,d,s)=>d.has(r)||B("Cannot "+s);var c=(r,d,s)=>(A(r,d,"read from private field"),s?s.call(r):d.get(r)),T=(r,d,s)=>d.has(r)?B("Cannot add the same private member more than once"):d instanceof WeakSet?d.add(r):d.set(r,s),z=(r,d,s,N)=>(A(r,d,"write to private field"),N?N.call(r,s):d.set(r,s),s),y=(r,d,s)=>(A(r,d,"access private method"),s);var L,f,a,v,E,I,M,D,H,_,q;const d={autoRender:!0,defaultColor:"#000",defaultLineWidth:4,transpose:0,name:"",nameFontSize:50,spacing:18,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},s=(j,t={},e)=>{const i=document.createElementNS("http://www.w3.org/2000/svg",j);for(const[n,h]of Object.entries(t))!h&&h!==0||i.setAttribute(n,String(h));return e&&(i.textContent=String(e)),i};class N{constructor(t={}){T(this,a);T(this,L);T(this,f);z(this,L,{...d,...t});const{autoRender:e}=c(this,L);z(this,f,s("svg")),e&&y(this,a,v).call(this)}get element(){return c(this,f)}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:o}=this.data;return t+(e+i)*n.length+o+h}get gridRect(){const{nutLineWidth:t,stringSpacing:e,stringLineWidth:i,stringCount:n,matrix:h,spacing:o,fretsSpacing:l,fretsLineWidth:u,nameFontSize:g}=this.data;return{width:e*(n-1)+i*n,height:t+(l+u)*h.length,left:e,top:g+o,right:this.width-e,bottom:this.height}}get data(){const{defaultColor:t,defaultLineWidth:e}=c(this,L),{nameTextColor:i=t,nutLineWidth:n=e,nutColor:h=t,fretsColor:o=t,fretsLineWidth:l=e,stringColor:u=t,stringLineWidth:g=e,fingerCircleColor:p=t,startFretsTextColor:$=t,transposeTextColor:x=i,notesOutsideOfChords:m={},showNotesOutsideOfChords:b,crossLineWidth:F=Math.min(g,l),crossLineColor:W=t,nameLetterSpacing:C=0}=c(this,L);return{...c(this,L),nameTextColor:i,nutLineWidth:n,nutColor:h,fretsColor:o,fretsLineWidth:l,stringColor:u,stringLineWidth:g,fingerCircleColor:p,startFretsTextColor:$,transposeTextColor:x,notesOutsideOfChords:m,showNotesOutsideOfChords:b||Object.keys(m).length>0,crossLineWidth:F,crossLineColor:W,nameLetterSpacing:C}}render(t){return t&&z(this,L,{...c(this,L),...t}),c(this,f).innerHTML="",y(this,a,v).call(this),this}}L=new WeakMap,f=new WeakMap,a=new WeakSet,v=function(){const t=this.data,{width:e,height:i}=this;c(this,f).setAttribute("width",`${e}`),c(this,f).setAttribute("height",`${i}`),c(this,f).setAttribute("viewBox",`0 0 ${e} ${i}`),y(this,a,H).call(this,t),y(this,a,D).call(this,t),y(this,a,I).call(this,t),y(this,a,E).call(this,t),t.showNotesOutsideOfChords&&y(this,a,_).call(this,t)},E=function(t){const{name:e,nameTextColor:i,nameFontSize:n,transposeTextColor:h,transpose:o,nameLetterSpacing:l}=t,u=!!o,g=n/2,p=s("text",{x:this.width/2-(u?g/2:0),y:n/2+g*.2,fill:i,"font-size":n,"text-anchor":"middle","dominant-baseline":"middle"});c(this,f).appendChild(p),u&&p.append(s("tspan",{fill:h,style:`font-size: ${g}px;`,"alignment-baseline":"middle","baseline-shift":"super"},o===1?"♯":"♭"));const $=s("tspan",{style:`letter-spacing:${l}px;`,"alignment-baseline":"middle"},e);p.append($),setTimeout(()=>{const x=this.gridRect.width,{width:m}=$.getBBox();m>x&&($.setAttribute("textLength",String(x)),$.setAttribute("lengthAdjust","spacingAndGlyphs"))},0)},I=function(t){const{stringSpacing:e,fingerCircleColor:i,stringLineWidth:n,fingerRadius:h,spacing:o,matrix:l,fretsSpacing:u,fretsLineWidth:g,nameFontSize:p,nutLineWidth:$,fingerNumberTextColor:x,showFingerNumber:m,mergeFingerCircle:b}=t,F=h*1.5,W=new Map;for(let C=0;C<l.length;C++)for(let w=0;w<l[C].length;w++){const S=l[C][w];if(S>0){const O=w*(e+n)+n/2+e,k=(C+.5)*(u+g)+g/2+p+o+$-g;if(b){W.has(S)||W.set(S,[]);const R=W.get(S);if(R.push({x:O,y:k}),R.length>1&&w===l[C].lastIndexOf(S)){const G=R[0],P={x:O,y:k},K=s("line",{x1:`${G.x}`,y1:`${G.y}`,x2:`${P.x}`,y2:`${P.y}`,stroke:i,"stroke-width":`${h*2}`,"stroke-linecap":"round"});c(this,f).appendChild(K),m&&y(this,a,M).call(this,O,k,S,x,F);continue}}const J=s("circle",{cx:`${O}`,cy:`${k}`,r:`${h}`,fill:i});c(this,f).appendChild(J),m&&(!b||w===l[C].lastIndexOf(S))&&y(this,a,M).call(this,O,k,S,x,F)}}},M=function(t,e,i,n,h){const o=s("text",{x:`${t}`,y:`${e}`,fill:n,"font-size":`${h}`,"text-anchor":"middle","dominant-baseline":"central"},i);c(this,f).appendChild(o)},D=function(t){const{startFretsTextColor:e,startFrets:i,nameFontSize:n,nutLineWidth:h,fretsLineWidth:o,fretsSpacing:l}=t;if(i<=1)return;const u=n/2,g=s("text",{x:"0",y:`${this.gridRect.top+h+l/2+o*2}`,fill:e,"font-size":`${u}`,"font-style":"italic"},i);c(this,f).appendChild(g)},H=function(t){const{matrix:e,stringLineWidth:i,stringSpacing:n,stringColor:h,stringCount:o,fretsSpacing:l,fretsLineWidth:u,fretsColor:g,nutLineWidth:p,nutColor:$}=t,x=e.length,{top:m,bottom:b,right:F,left:W}=this.gridRect;for(let C=0;C<o;C++){const w=C*(n+i)+i/2+n,S=s("line",{x1:`${w}`,y1:`${m+p}`,x2:`${w}`,y2:`${b}`,stroke:h,"stroke-width":`${i}`});c(this,f).appendChild(S)}for(let C=0;C<=x;C++){const w=C===0,S=w?m+p/2:C*(l+u)+m+p-u/2,O=s("line",{x1:`${W}`,y1:`${S}`,x2:`${F}`,y2:`${S}`,stroke:w?$:g,"stroke-width":`${w?p:u}`});c(this,f).appendChild(O)}},_=function(t){const{stringLineWidth:e,stringSpacing:i,stringCount:n,notesOutsideOfChords:h,fingerRadius:o,crossLineColor:l,crossLineWidth:u}=t,g=this.gridRect.top;for(let p=0;p<n;p++){if(!y(this,a,q).call(this,p,t))continue;const $=p*(i+e)+e/2+i;if(h[n-p]){const x=s("g",{transform:`translate(${$-o/2}, ${g-o*1.2})`}),m=s("line",{x1:"0",y1:"0",x2:`${o}`,y2:`${o}`,stroke:l,"stroke-width":`${u}`,"stroke-linecap":"round"});x.appendChild(m);const b=s("line",{x1:"0",y1:`${o}`,x2:`${o}`,y2:"0",stroke:l,"stroke-width":`${u}`,"stroke-linecap":"round"});x.appendChild(b),c(this,f).appendChild(x)}else{const x=o*.75,m=s("circle",{cx:`${$}`,cy:`${g-x*1.1}`,r:`${x}`,fill:"transparent",stroke:l,"stroke-width":`${u}`});c(this,f).appendChild(m)}}},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},r.GuitarChords=N,Object.defineProperty(r,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,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"})}); |
@@ -5,3 +5,3 @@ { | ||
"authors": "Capricorncd", | ||
"version": "0.0.5", | ||
"version": "0.0.6", | ||
"type": "module", | ||
@@ -19,3 +19,3 @@ "main": "./dist/guitar-chords.umd.js", | ||
"scripts": { | ||
"build": "vite build && node ../../node_modules/@zx-libs/header --dir=dist", | ||
"build": "vite build && node ../../scripts/after-build.mjs --dir=dist", | ||
"pl": "npm run build && npm publish", | ||
@@ -22,0 +22,0 @@ "pl:first": "npm publish --access public" |
@@ -5,3 +5,3 @@ /** | ||
*/ | ||
import type { DefaultOptions } from "./types"; | ||
import type { DefaultOptions } from './types' | ||
@@ -14,5 +14,5 @@ export const DEF_OPTIONS: DefaultOptions = { | ||
name: '', | ||
nameFontSize: 50, | ||
nameFontSize: 60, | ||
// nameTextColor: '', | ||
spacing: 18, | ||
spacing: 20, | ||
// nutLineWidth: LINE_WIDTH, | ||
@@ -19,0 +19,0 @@ // nutColor: '', |
@@ -5,5 +5,9 @@ /** | ||
*/ | ||
import type { GuitarChordsOptions, GuitarChordsData, DefaultOptions } from "./types"; | ||
import { DEF_OPTIONS } from "./const"; | ||
import { DEF_OPTIONS } from './const' | ||
import { createSvgElement } from './helpers' | ||
import type { | ||
GuitarChordsOptions, | ||
GuitarChordsData, | ||
DefaultOptions, | ||
} from './types' | ||
@@ -16,2 +20,3 @@ /** | ||
#element: SVGElement | ||
#version: string = '__VERSION__' | ||
@@ -21,7 +26,7 @@ constructor(options: Partial<GuitarChordsOptions> = {}) { | ||
...DEF_OPTIONS, | ||
...options | ||
...options, | ||
} | ||
const { autoRender } = this.#options | ||
this.#element = createSvgElement("svg") | ||
this.#element = createSvgElement('svg') | ||
if (autoRender) this.#draw() | ||
@@ -36,8 +41,20 @@ } | ||
const { stringCount, stringSpacing, stringLineWidth } = this.data | ||
return (stringSpacing * (stringCount + 1) + stringLineWidth * stringCount) | ||
return stringSpacing * (stringCount + 1) + stringLineWidth * stringCount | ||
} | ||
get height() { | ||
const { nutLineWidth, fretsSpacing, fretsLineWidth, matrix, spacing, nameFontSize } = this.data | ||
return nutLineWidth + (fretsSpacing + fretsLineWidth) * matrix.length + nameFontSize + spacing | ||
const { | ||
nutLineWidth, | ||
fretsSpacing, | ||
fretsLineWidth, | ||
matrix, | ||
spacing, | ||
nameFontSize, | ||
} = this.data | ||
return ( | ||
nutLineWidth + | ||
(fretsSpacing + fretsLineWidth) * matrix.length + | ||
nameFontSize + | ||
spacing | ||
) | ||
} | ||
@@ -49,9 +66,19 @@ | ||
get gridRect() { | ||
const { nutLineWidth, stringSpacing, stringLineWidth, stringCount, matrix, spacing, fretsSpacing, fretsLineWidth, nameFontSize } = this.data | ||
const { | ||
nutLineWidth, | ||
stringSpacing, | ||
stringLineWidth, | ||
stringCount, | ||
matrix, | ||
spacing, | ||
fretsSpacing, | ||
fretsLineWidth, | ||
nameFontSize, | ||
} = this.data | ||
return { | ||
width: (stringSpacing * (stringCount - 1) + stringLineWidth * stringCount), | ||
width: stringSpacing * (stringCount - 1) + stringLineWidth * stringCount, | ||
height: nutLineWidth + (fretsSpacing + fretsLineWidth) * matrix.length, | ||
left: stringSpacing, | ||
top: (nameFontSize + spacing), | ||
right: (this.width - stringSpacing), | ||
top: nameFontSize + spacing, | ||
right: this.width - stringSpacing, | ||
bottom: this.height, | ||
@@ -61,4 +88,8 @@ } | ||
get version() { | ||
return this.#version | ||
} | ||
get data(): GuitarChordsData { | ||
const { defaultColor, defaultLineWidth} = this.#options | ||
const { defaultColor, defaultLineWidth, fingerRadius } = this.#options | ||
const { | ||
@@ -79,2 +110,3 @@ nameTextColor = defaultColor, | ||
crossLineColor = defaultColor, | ||
crossRadius = fingerRadius * 0.75, | ||
nameLetterSpacing = 0, | ||
@@ -95,5 +127,8 @@ } = this.#options | ||
notesOutsideOfChords, | ||
showNotesOutsideOfChords: showNotesOutsideOfChords || Object.keys(notesOutsideOfChords).length > 0, | ||
showNotesOutsideOfChords: | ||
showNotesOutsideOfChords || | ||
Object.keys(notesOutsideOfChords).length > 0, | ||
crossLineWidth, | ||
crossLineColor, | ||
crossRadius, | ||
nameLetterSpacing, | ||
@@ -112,3 +147,3 @@ } | ||
...this.#options, | ||
...options | ||
...options, | ||
} | ||
@@ -139,3 +174,10 @@ } | ||
#drawChordName(data: GuitarChordsData) { | ||
const { name, nameTextColor, nameFontSize, transposeTextColor, transpose, nameLetterSpacing } = data | ||
const { | ||
name, | ||
nameTextColor, | ||
nameFontSize, | ||
transposeTextColor, | ||
transpose, | ||
nameLetterSpacing, | ||
} = data | ||
// 是否变调 | ||
@@ -146,8 +188,8 @@ const hasTranspose = !!transpose | ||
const text = createSvgElement("text", { | ||
const text = createSvgElement('text', { | ||
// 变调时,x向左偏移1/4文字大小(1/2变调符号字体大小) | ||
'x': this.width / 2 - (hasTranspose ? transposeFontSize / 2 : 0), | ||
x: this.width / 2 - (hasTranspose ? transposeFontSize / 2 : 0), | ||
// y偏移字体大小的20%,使变调符号可以全部显示 | ||
'y': nameFontSize / 2 + transposeFontSize * 0.2, | ||
'fill': nameTextColor, | ||
y: nameFontSize / 2 + transposeFontSize * 0.2, | ||
fill: nameTextColor, | ||
'font-size': nameFontSize, | ||
@@ -161,9 +203,13 @@ 'text-anchor': 'middle', | ||
if (hasTranspose) { | ||
text.append(createSvgElement("tspan", { | ||
fill: transposeTextColor, | ||
style: `font-size: ${transposeFontSize}px;`, | ||
'alignment-baseline': "middle", | ||
'baseline-shift': 'super', | ||
}, | ||
transpose === 1 ? '♯' : '♭'), | ||
text.append( | ||
createSvgElement( | ||
'tspan', | ||
{ | ||
fill: transposeTextColor, | ||
style: `font-size: ${transposeFontSize}px;`, | ||
'alignment-baseline': 'middle', | ||
'baseline-shift': 'super', | ||
}, | ||
transpose === 1 ? '♯' : '♭' | ||
) | ||
) | ||
@@ -173,6 +219,10 @@ } | ||
// 和弦名称 | ||
const nameTspan = createSvgElement<SVGTextElement>("tspan", { | ||
style: `letter-spacing:${nameLetterSpacing}px;`, | ||
'alignment-baseline': "middle", | ||
}, name) | ||
const nameTspan = createSvgElement<SVGTextElement>( | ||
'tspan', | ||
{ | ||
style: `letter-spacing:${nameLetterSpacing}px;`, | ||
'alignment-baseline': 'middle', | ||
}, | ||
name | ||
) | ||
text.append(nameTspan) | ||
@@ -193,6 +243,20 @@ | ||
#drawFingerPositions(data: GuitarChordsData) { | ||
const { stringSpacing, fingerCircleColor, stringLineWidth, fingerRadius, spacing, matrix, fretsSpacing, fretsLineWidth, nameFontSize, nutLineWidth, fingerNumberTextColor, showFingerNumber, mergeFingerCircle } = data | ||
const { | ||
stringSpacing, | ||
fingerCircleColor, | ||
stringLineWidth, | ||
fingerRadius, | ||
spacing, | ||
matrix, | ||
fretsSpacing, | ||
fretsLineWidth, | ||
nameFontSize, | ||
nutLineWidth, | ||
fingerNumberTextColor, | ||
showFingerNumber, | ||
mergeFingerCircle, | ||
} = data | ||
const fontSize = fingerRadius * 1.5 | ||
const fingerCircleMap = new Map<number, { x: number, y: number }[]>() | ||
const fingerCircleMap = new Map<number, { x: number; y: number }[]>() | ||
@@ -203,4 +267,13 @@ for (let fret = 0; fret < matrix.length; fret++) { | ||
if (fingerNumber > 0) { | ||
const x = string * (stringSpacing + stringLineWidth) + stringLineWidth / 2 + stringSpacing | ||
const y = (fret + 0.5) * (fretsSpacing + fretsLineWidth) + fretsLineWidth / 2 + nameFontSize + spacing + nutLineWidth - fretsLineWidth | ||
const x = | ||
string * (stringSpacing + stringLineWidth) + | ||
stringLineWidth / 2 + | ||
stringSpacing | ||
const y = | ||
(fret + 0.5) * (fretsSpacing + fretsLineWidth) + | ||
fretsLineWidth / 2 + | ||
nameFontSize + | ||
spacing + | ||
nutLineWidth - | ||
fretsLineWidth | ||
@@ -216,11 +289,14 @@ // 大横按/小横按时,合并指法圆点 | ||
// 相同手指编号的最后一个指法圆点绘制 | ||
if (fingerCircleList.length > 1 && string === matrix[fret].lastIndexOf(fingerNumber)) { | ||
if ( | ||
fingerCircleList.length > 1 && | ||
string === matrix[fret].lastIndexOf(fingerNumber) | ||
) { | ||
const startPoint = fingerCircleList[0] | ||
const endPoint = { x, y } | ||
const line = createSvgElement("line", { | ||
'x1': `${startPoint.x}`, | ||
'y1': `${startPoint.y}`, | ||
'x2': `${endPoint.x}`, | ||
'y2': `${endPoint.y}`, | ||
'stroke': fingerCircleColor, | ||
const line = createSvgElement('line', { | ||
x1: `${startPoint.x}`, | ||
y1: `${startPoint.y}`, | ||
x2: `${endPoint.x}`, | ||
y2: `${endPoint.y}`, | ||
stroke: fingerCircleColor, | ||
'stroke-width': `${fingerRadius * 2}`, | ||
@@ -233,3 +309,9 @@ 'stroke-linecap': 'round', | ||
if (showFingerNumber) { | ||
this.#drawFingerNumber(x, y, fingerNumber, fingerNumberTextColor, fontSize) | ||
this.#drawFingerNumber( | ||
x, | ||
y, | ||
fingerNumber, | ||
fingerNumberTextColor, | ||
fontSize | ||
) | ||
} | ||
@@ -240,12 +322,22 @@ continue | ||
const circle = createSvgElement("circle", { | ||
'cx': `${x}`, | ||
'cy': `${y}`, | ||
'r': `${fingerRadius}`, | ||
'fill': fingerCircleColor, | ||
const circle = createSvgElement('circle', { | ||
cx: `${x}`, | ||
cy: `${y}`, | ||
r: `${fingerRadius}`, | ||
fill: fingerCircleColor, | ||
}) | ||
this.#element.appendChild(circle) | ||
if (showFingerNumber && (!mergeFingerCircle || string === matrix[fret].lastIndexOf(fingerNumber))) { | ||
this.#drawFingerNumber(x, y, fingerNumber, fingerNumberTextColor, fontSize) | ||
if ( | ||
showFingerNumber && | ||
(!mergeFingerCircle || | ||
string === matrix[fret].lastIndexOf(fingerNumber)) | ||
) { | ||
this.#drawFingerNumber( | ||
x, | ||
y, | ||
fingerNumber, | ||
fingerNumberTextColor, | ||
fontSize | ||
) | ||
} | ||
@@ -258,11 +350,21 @@ } | ||
// 新增一个辅助方法来绘制指法编号 | ||
#drawFingerNumber(x: number, y: number, fingerNumber: number, color: string, fontSize: number) { | ||
const text = createSvgElement("text", { | ||
'x': `${x}`, | ||
'y': `${y}`, | ||
'fill': color, | ||
'font-size': `${fontSize}`, | ||
'text-anchor': 'middle', | ||
'dominant-baseline': 'central', | ||
}, fingerNumber) | ||
#drawFingerNumber( | ||
x: number, | ||
y: number, | ||
fingerNumber: number, | ||
color: string, | ||
fontSize: number | ||
) { | ||
const text = createSvgElement( | ||
'text', | ||
{ | ||
x: `${x}`, | ||
y: `${y}`, | ||
fill: color, | ||
'font-size': `${fontSize}`, | ||
'text-anchor': 'middle', | ||
'dominant-baseline': 'central', | ||
}, | ||
fingerNumber | ||
) | ||
this.#element.appendChild(text) | ||
@@ -272,13 +374,24 @@ } | ||
#drawFretNumbers(data: GuitarChordsData) { | ||
const { startFretsTextColor, startFrets, nameFontSize, nutLineWidth, fretsLineWidth, fretsSpacing } = data | ||
const { | ||
startFretsTextColor, | ||
startFrets, | ||
nameFontSize, | ||
nutLineWidth, | ||
fretsLineWidth, | ||
fretsSpacing, | ||
} = data | ||
if (startFrets <= 1) return | ||
const fontSize = nameFontSize / 2 | ||
const text = createSvgElement("text", { | ||
'x': '0', | ||
'y': `${this.gridRect.top + nutLineWidth + fretsSpacing / 2 + fretsLineWidth * 2}`, | ||
'fill': startFretsTextColor, | ||
'font-size': `${fontSize}`, | ||
'font-style': 'italic', | ||
}, startFrets) | ||
const text = createSvgElement( | ||
'text', | ||
{ | ||
x: '0', | ||
y: `${this.gridRect.top + nutLineWidth + fretsSpacing / 2 + fretsLineWidth * 2}`, | ||
fill: startFretsTextColor, | ||
'font-size': `${fontSize}`, | ||
'font-style': 'italic', | ||
}, | ||
startFrets | ||
) | ||
this.#element.appendChild(text) | ||
@@ -288,3 +401,14 @@ } | ||
#drawGrid(data: GuitarChordsData) { | ||
const { matrix, stringLineWidth, stringSpacing, stringColor, stringCount, fretsSpacing, fretsLineWidth, fretsColor, nutLineWidth, nutColor } = data | ||
const { | ||
matrix, | ||
stringLineWidth, | ||
stringSpacing, | ||
stringColor, | ||
stringCount, | ||
fretsSpacing, | ||
fretsLineWidth, | ||
fretsColor, | ||
nutLineWidth, | ||
nutColor, | ||
} = data | ||
const fretCount = matrix.length | ||
@@ -296,10 +420,13 @@ | ||
for (let i = 0; i < stringCount; i++) { | ||
const x = i * (stringSpacing + stringLineWidth) + stringLineWidth / 2 + stringSpacing | ||
const line = createSvgElement("line", { | ||
'x1': `${x}`, | ||
const x = | ||
i * (stringSpacing + stringLineWidth) + | ||
stringLineWidth / 2 + | ||
stringSpacing | ||
const line = createSvgElement('line', { | ||
x1: `${x}`, | ||
// 从琴枕横线下方 1/2 琴枕宽度开始 | ||
'y1': `${top + nutLineWidth}`, | ||
'x2': `${x}`, | ||
'y2': `${bottom}`, | ||
'stroke': stringColor, | ||
y1: `${top + nutLineWidth}`, | ||
x2: `${x}`, | ||
y2: `${bottom}`, | ||
stroke: stringColor, | ||
'stroke-width': `${stringLineWidth}`, | ||
@@ -313,9 +440,14 @@ }) | ||
const isNut = i === 0 | ||
const y = isNut ? top + nutLineWidth / 2 : i * (fretsSpacing + fretsLineWidth) + top + nutLineWidth - fretsLineWidth / 2 | ||
const line = createSvgElement("line", { | ||
'x1': `${left}`, | ||
'y1': `${y}`, | ||
'x2': `${right}`, | ||
'y2': `${y}`, | ||
'stroke': isNut ? nutColor : fretsColor, | ||
const y = isNut | ||
? top + nutLineWidth / 2 | ||
: i * (fretsSpacing + fretsLineWidth) + | ||
top + | ||
nutLineWidth - | ||
fretsLineWidth / 2 | ||
const line = createSvgElement('line', { | ||
x1: `${left}`, | ||
y1: `${y}`, | ||
x2: `${right}`, | ||
y2: `${y}`, | ||
stroke: isNut ? nutColor : fretsColor, | ||
'stroke-width': `${isNut ? nutLineWidth : fretsLineWidth}`, | ||
@@ -328,3 +460,11 @@ }) | ||
#drawNotesOutsideOfChords(data: GuitarChordsData) { | ||
const { stringLineWidth, stringSpacing, stringCount, notesOutsideOfChords, fingerRadius, crossLineColor, crossLineWidth } = data | ||
const { | ||
stringLineWidth, | ||
stringSpacing, | ||
stringCount, | ||
notesOutsideOfChords, | ||
crossRadius, | ||
crossLineColor, | ||
crossLineWidth, | ||
} = data | ||
@@ -335,15 +475,18 @@ // 绘制垂直交叉线段,长度为指法圆点直径 | ||
if (!this.#isOpenString(i, data)) continue | ||
const x = i * (stringSpacing + stringLineWidth) + stringLineWidth / 2 + stringSpacing | ||
const x = | ||
i * (stringSpacing + stringLineWidth) + | ||
stringLineWidth / 2 + | ||
stringSpacing | ||
if (notesOutsideOfChords[stringCount - i]) { | ||
const group = createSvgElement("g", { | ||
'transform': `translate(${x - fingerRadius / 2}, ${y - fingerRadius * 1.2})`, | ||
const group = createSvgElement('g', { | ||
transform: `translate(${x - crossRadius}, ${y - crossRadius * 2}) rotate(45 ${crossRadius} ${crossRadius})`, | ||
}) | ||
// 绘制交叉线 | ||
const line1 = createSvgElement("line", { | ||
'x1': '0', | ||
'y1': '0', | ||
'x2': `${fingerRadius}`, | ||
'y2': `${fingerRadius}`, | ||
'stroke': crossLineColor, | ||
const line1 = createSvgElement('line', { | ||
x1: 0, | ||
y1: crossRadius, | ||
x2: crossRadius * 2, | ||
y2: crossRadius, | ||
stroke: crossLineColor, | ||
'stroke-width': `${crossLineWidth}`, | ||
@@ -354,8 +497,8 @@ 'stroke-linecap': 'round', | ||
const line2 = createSvgElement("line", { | ||
'x1': '0', | ||
'y1': `${fingerRadius}`, | ||
'x2': `${fingerRadius}`, | ||
'y2': '0', | ||
'stroke': crossLineColor, | ||
const line2 = createSvgElement('line', { | ||
x1: crossRadius, | ||
y1: 0, | ||
x2: crossRadius, | ||
y2: crossRadius * 2, | ||
stroke: crossLineColor, | ||
'stroke-width': `${crossLineWidth}`, | ||
@@ -368,9 +511,8 @@ 'stroke-linecap': 'round', | ||
} else { | ||
const radius = fingerRadius * 0.75 | ||
const circle = createSvgElement("circle", { | ||
'cx': `${x}`, | ||
'cy': `${y - radius * 1.1}`, | ||
'r': `${radius}`, | ||
'fill': 'transparent', | ||
'stroke': crossLineColor, | ||
const circle = createSvgElement('circle', { | ||
cx: `${x}`, | ||
cy: `${y - crossRadius - crossLineWidth / 2}`, | ||
r: `${crossRadius}`, | ||
fill: 'transparent', | ||
stroke: crossLineColor, | ||
'stroke-width': `${crossLineWidth}`, | ||
@@ -377,0 +519,0 @@ }) |
@@ -11,4 +11,8 @@ export type SvgElementAttrs = Record<string, string | number> | ||
*/ | ||
export const createSvgElement = <T extends SVGElement>(type: string, attrs: SvgElementAttrs = {}, content?: string | number): T => { | ||
const el = document.createElementNS("http://www.w3.org/2000/svg", type) as T | ||
export const createSvgElement = <T extends SVGElement>( | ||
type: string, | ||
attrs: SvgElementAttrs = {}, | ||
content?: string | number | ||
): T => { | ||
const el = document.createElementNS('http://www.w3.org/2000/svg', type) as T | ||
for (const [key, val] of Object.entries(attrs)) { | ||
@@ -15,0 +19,0 @@ if (!val && val !== 0) continue |
@@ -22,5 +22,5 @@ /** | ||
// 和弦名称 | ||
name: string, | ||
name: string | ||
// 和弦名称字体大小 | ||
nameFontSize: number, | ||
nameFontSize: number | ||
// 和弦名称颜色 | ||
@@ -70,6 +70,8 @@ nameTextColor: string | ||
notesOutsideOfChords: Record<number, boolean> | ||
// 和弦外音`x`的线条粗细,默认为琴弦线条宽度。其长度为指法圆点直径 | ||
// 和弦外音`x/o`的线条粗细,默认为琴弦线条宽度。其长度为指法圆点直径 | ||
crossLineWidth: number | ||
// 和弦外音`x`的线条颜色 | ||
// 和弦外音`x/o`的线条颜色 | ||
crossLineColor: string | ||
// 和弦外音`x/o`的半径,默认为`fingerRadius * 0.75` | ||
crossRadius: number | ||
} | ||
@@ -91,3 +93,6 @@ | ||
*/ | ||
export type GuitarChordsOptions = OmitOptional<GuitarChordsData, 'name' | 'matrix'> | ||
export type GuitarChordsOptions = OmitOptional< | ||
GuitarChordsData, | ||
'name' | 'matrix' | ||
> | ||
@@ -97,3 +102,19 @@ /** | ||
*/ | ||
export type DefaultOptions = PickOptional<GuitarChordsData, 'nameTextColor' | 'transposeTextColor' | 'nutLineWidth' | 'nutColor' | 'fretsColor' | 'fretsLineWidth' | 'stringColor' | 'stringLineWidth' | 'fingerCircleColor' | 'startFretsTextColor' | 'notesOutsideOfChords' | 'crossLineWidth' | 'crossLineColor' | 'nameLetterSpacing'> | ||
export type DefaultOptions = PickOptional< | ||
GuitarChordsData, | ||
| 'nameTextColor' | ||
| 'transposeTextColor' | ||
| 'nutLineWidth' | ||
| 'nutColor' | ||
| 'fretsColor' | ||
| 'fretsLineWidth' | ||
| 'stringColor' | ||
| 'stringLineWidth' | ||
| 'fingerCircleColor' | ||
| 'startFretsTextColor' | ||
| 'notesOutsideOfChords' | ||
| 'crossLineWidth' | ||
| 'crossLineColor' | ||
| 'nameLetterSpacing' | ||
| 'crossRadius' | ||
> |
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
36929
1059