Перейти к основному содержимому
clawam tools
Инструменты Документы Daoark EN Главная Главная / Быт и полезное › Главная manifest.json {frets: [E A D G B E 在每根弦上的品数, -1 表示不弹], fingers: [指法 1-4 0=不弹, 5=barre]} // 开放和弦 + 部分横按(常用 6 个品) var CHORD_LIB = { 'C': { frets: [0, 3, 2, 0, 1, 0], fingers: [0, 3, 2, 0, 1, 0] }, 'Cm': { frets: [-1, 3, 5, 5, 4, 3], fingers: [0, 1, 3, 4, 2, 1], barres: [{ fret: 3, from: 5, to: 1 }] }, 'C7': { frets: [0, 3, 2, 3, 1, 0], fingers: [0, 3, 2, 4, 1, 0] }, 'Cmaj7':{ frets: [0, 3, 2, 0, 0, 0], fingers: [0, 3, 2, 0, 0, 0] }, 'Cm7': { frets: [-1, 3, 5, 3, 4, 3], fingers: [0, 1, 3, 1, 2, 1], barres: [{ fret: 3, from: 5, to: 1 }] }, 'Cdim': { frets: [-1, 3, 4, 5, 4, -1], fingers: [0, 1, 2, 4, 3, 0] }, 'Caug': { frets: [-1, 3, 2, 0, 1, 4], fingers: [0, 2, 1, 0, 0, 4] }, 'Csus2':{ frets: [0, 3, 0, 0, 1, 3], fingers: [0, 2, 0, 0, 1, 3] }, 'Csus4':{ frets: [0, 3, 3, 0, 1, 1], fingers: [0, 3, 4, 0, 1, 2] }, 'Cadd9':{ frets: [0, 3, 0, 2, 1, 0], fingers: [0, 2, 0, 3, 1, 0] }, 'C6': { frets: [0, 3, 2, 2, 1, 0], fingers: [0, 3, 2, 2, 1, 0] } }; function getChordId(root, type) { return root + type; } // 简化:除 C 库外,其他根音用横移 5 品(大调)或 5/横移法(其他) — 实际此处仅支持 C 全 11 类 // 为支持所有 12 根音,使用变调夹(移调)方式:对所有根音应用 C 库的移位 = 根音索引差 function transposeChord(chord, semitones) { var f = chord.frets.slice(); var fi = chord.fingers ? chord.fingers.slice() : null; for (var i = 0; i < f.length; i++) if (f[i] > 0) f[i] = f[i] + semitones; return { frets: f, fingers: fi, barres: chord.barres }; } function getChord(root, type) { var id = getChordId('C', type); var c = CHORD_LIB[id]; if (!c) return null; var rootIdx = NOTE_NAMES.indexOf(root); return transposeChord(c, rootIdx); } function chordNotes(root, type) { var rootIdx = NOTE_NAMES.indexOf(root); var intervals = { '': [0, 4, 7], 'm': [0, 3, 7], '7': [0, 4, 7, 10], 'maj7': [0, 4, 7, 11], 'm7': [0, 3, 7, 10], 'dim': [0, 3, 6], 'aug': [0, 4, 8], 'sus2': [0, 2, 7], 'sus4': [0, 5, 7], 'add9': [0, 4, 7, 14], '6': [0, 4, 7, 9] }; var iv = intervals[type] || intervals['']; return iv.map(function(i) { return noteName(rootIdx + i) + '(' + i + ')'; }); } function renderChord(c, root, type) { var W = 280, H = 220, padL = 40, padR = 20, padT = 50, padB = 30; var fretW = (W - padL - padR) / 5; var stringSpacing = (H - padT - padB) / 5; var svg = ''; svg += '' + root + type + ' 和弦'; // 弦线(6 根) for (var s = 0; s < 6; s++) { var x = padL + fretW * 0; // 头 var y = padT + s * stringSpacing; svg += ''; } // 品线(5 个) for (var f = 0; f <= 5; f++) { var x = padL + f * fretW; svg += ''; } // 顶头标记 svg += 'E'; svg += 'A'; svg += 'D'; svg += 'G'; svg += 'B'; svg += 'E'; // 弦(从上到下 = E(低音) → E(高音)) for (var s = 0; s < 6; s++) { var fret = c.frets[s]; var y = padT + s * stringSpacing; if (fret === -1) { // × svg += '×'; } else if (fret === 0) { // 圆空 svg += ''; } else { // 黑点 var fx = padL + (fret - 0.5) * fretW; svg += ''; if (c.fingers && c.fingers[s] > 0) { svg += '' + c.fingers[s] + ''; } } } // 横按 if (c.barres) { for (var b = 0; b < c.barres.length; b++) { var bar = c.barres[b]; var y0 = padT + (5 - bar.from) * stringSpacing; var y1 = padT + (5 - bar.to) * stringSpacing; var bx = padL + (bar.fret - 0.5) * fretW; svg += ''; } } svg += ''; return svg; } function doProcess() { try { var root = getVal('root'); var type = getVal('type'); var capo = parseInt(getVal('capo'), 10); var c = getChord(root, type); if (!c) { showError('和弦库暂无此类型'); return; } var notes = chordNotes(root, type); var svg = renderChord(c, root, type); showResult(svg, root + type + ' = ' + notes.join(' + ') + (capo > 0 ? ' (Capo: ' + capo + ' 品)' : '')); } catch (e) { showError('生成失败: ' + (e.message || e)); } } $('btn-main').addEventListener('click', function(e) { e.preventDefault(); doProcess(); }); $('btn-clear').addEventListener('click', function() { var inputs = document.querySelectorAll('input,textarea,select'); for (var i = 0; i < inputs.length; i++) { if (inputs[i].tagName === 'SELECT') inputs[i].selectedIndex = 0; else inputs[i].value = inputs[i].defaultValue; } var ra = $('result-area'); ra.hidden = true; ra.style.display = 'none'; var em = $('error-msg'); em.hidden = true; em.style.display = 'none'; }); })();