[译]指板
By robot-v1.0
本文链接 https://www.kyfws.com/applications/fretboardjs-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 17 分钟阅读 - 8059 个词 阅读量 0[译]指板
原文地址:https://www.codeproject.com/Articles/802003/FretboardJs
原文作者:CognitiveFeedback
译文由本站 robot-v1.0 翻译
前言
An SVG Guitar Fretboard Library SVG吉他指板库
介绍(Introduction)
目标是为JavaScript创建吉他指板框架. FretboardJs在SVG元素中呈现.(The goal is to create a guitar fretboard framework for JavaScript. FretboardJs is rendered in an SVG element.) 消费者在指板中添加注释,并使用全面的和弦和音阶库来创建复杂的指板应用程序,而忽略有关指板逻辑的详细信息.(The consumer adds notes to the fretboard and uses the comprehensive chord and scale libraries to create sophisticated fretboard applications whilst ignoring details concerning fretboard logic.) 可以找到使用FretboardJs的示例应用程序(An example app using FretboardJs can be found)在示例代码中.这个程序利用和弦库来渲染和弦家族.(in the sample code. This app makes use of the chord library to render chord families.)吉他手输入和弦名称,然后该应用会显示和弦家族,展示各种位置和指法.(A guitarist enters chord names and the app presents the chord family, demonstrating various positions and fingerings.) 单击此处查看正在运行的" Chord Explorer"演示应用程序.(Click here to view the ‘Chord Explorer’ demo app in action.)
使用图书馆(Using the Library)
让我们看看如何利用FretboardJs库.(Let’s see how to makes use of the FretboardJs library.) 首先:包括指向指板的链接.(Firstly: include a link to the fretboard.)版(version).js文件和(.js file and)使用以下结构定义SVG:(define an SVG with the following structure:)
<svg id="svg" xmlns="http://www.w3.org/2000/svg">
<g id="resources">
<radialGradient id="fingering-dot-gradient" cx="60%" cy="40%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style="stop-color:rgb(255,0,0); stop-opacity:1"></stop>
<stop offset="100%" style="stop-color:rgb(80,0,0);stop-opacity:1"></stop>
</radialGradient>
<linearGradient id="fretboard-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#2b2b2b"></stop>
<stop offset="10%" style="stop-color:#191919"></stop>
<stop offset="50%" style="stop-color:black"></stop>
<stop offset="90%" style="stop-color:#191919"></stop>
<stop offset="100%" style="stop-color:#2b2b2b"></stop>
</linearGradient>
<linearGradient id="head-gradient" x1="0%" y1="0%" x2="0%" y2="100%">
<stop offset="0%" style="stop-color:#3d3d3d"></stop>
<stop offset="10%" style="stop-color:#191919"></stop>
<stop offset="50%" style="stop-color:black"></stop>
<stop offset="90%" style="stop-color:#191919"></stop>
<stop offset="100%" style="stop-color:#3d3d3d"></stop>
</linearGradient>
<pattern id="pearl-inlay" patternUnits="userSpaceOnUse" width="100" height="100">
<image xlink:href="/images/pearl-inlay.jpg" x="0" y="0" width="100" height="100"></image>
</pattern>
</g>
<g id="fretboard-layer">
</g>
<g id="fingering-layer">
</g>
</svg>
有一些重要的(There are a number of important) id
标签在这里:(tags here:)
- 指点渐变:(fingering-dot-gradient:)指板点的径向渐变.(radial gradient for fretboard dots.)
- 指板渐变:(fretboard-gradient:)指板琴颈的线性渐变.(linear gradient for the fretboard neck.)
- 头部渐变:(head-gradient:)头部的线性梯度.(linear gradient for the head piece.)
- 珍珠镶嵌:(pearl-inlay:)指板3\5\7\9和12上的指板镶嵌元素的图像图案.(image pattern for the fretboard inlay elements on frets 3, 5, 7, 9 and 12.)
- 指板层:(fretboard-layer:)SVG组,将放置所有静态指板琴颈元素(弦,指板,嵌体).(the SVG group where all static fretboard-neck elements (strings, frets, inlays) will be placed.)
- 指法层:(fingering-layer:)将绘制所有点的SVG组.(the SVG group where all dots will be rendered.) 资源组定义了渲染代码使用的某些渐变颜色(将其放置在标记中使用户易于编辑这些值.例如,珍珠镶嵌图像可以简单地替换为纯色或渐变或某些其他图像,或者可以轻松地在标记中直接更改颈部渐变.(The resources group defines some gradient colors used by the rendering code (placing it in the markup makes it easy for the user to edit these values. For example, the pearl-inlay image may simply be substituted for a solid-color or gradient or some other image. Or, the neck gradient can be easily altered directly in the markup.) 接下来,一旦上面的标记到位并加载了框架,使用方代码就简单地执行以下语句:(Next, once the markup above is in place and the framework is loaded, the consuming code simply executes the following statement:)
Fretboard.Neck.Draw(svg);
并在SVG元素中渲染整个指板.结果将如下所示:(and this renders the entire fretboard within the SVG element. The result will look as follows:)
指法是使用(Fingerings are defined using the) Finger
目的:(object:)
new Finger(fret, string, finger)
我们可以使用以下方法在指板中添加注释或"点":(and we can add notes or ‘dots’ to the fretboard with:)
Fretboard.Neck.AddDot(Finger);
因此,任何便条都可以用以下方式呈现:(so, any arbitrary note can be rendered with:)
Fretboard.Neck.AddDot(new Finger(3, 5, 2));
产生:(which produces:)
那和弦呢?(What about Chords?)
的(The) Chord
对象被定义为这样的指法的命名集合(object is defined as a named collection of fingerings like this):(:)
new Chord(name,
[
new Finger(...),
new Finger(...),
new Finger(...),
new Finger(...)
])
例如名为的指法集合(for example the collection of fingerings named)“AØ"看起来像这样(‘AØ’ looks like this):(:)
new Chord('AØ',
[
new Finger(5, 6, 2),
new Finger(5, 4, 3),
new Finger(5, 3, 4),
new Finger(4, 2, 1),
])
但是,在其中存在丰富的和弦库(There exists, however, a rich chord library in the) Fretboard.Chords
名称空间(有关以下内容的讨论,请参见下文)(namespace (see below for the discussion of the) Chord
图书馆).的(library). The) Fretboard.Chords.Dominant7th
例如,对象是的数组(object for instance is an array of) Chord
代表主要第七指法的对象.同样的(objects that represent dominant 7th fingerings. Similarly for) Fretboard.Chords.MajorTriad
还有很多其他(and and many others.)
一旦有了和弦实例,就可以调用DrawChord方法,如下所示:(Once we have a chord instance, we can call the DrawChord method, like so:)
Fretboard.Neck.AddChord(Fretboard.Chords.Dominant7th[0]);
导致:(Resulting in:)
就是这样(And that’s it,)很简单吧?(pretty simple right?) 有关可以使用FretboardJs构建的那种应用的示例,(For an example of the kind of app that can be built using FretboardJs,) 参见演示应用程序” Chord Explorer",(see the demo app ‘Chord Explorer’,) 利用FretboardJs库来探索和弦家族的不同指法位置.输入文本字段允许吉他手输入和弦名称并通过各种指法进行迭代.从上述和弦库中选择和弦(which utilizes the FretboardJs library to explore different fingering positions for families of chords. An input text field allows a guitarist to enter a chord name and iterate through various fingerings. The chords are chosen from the chord library mentioned above).(.)
实作(Implementation)
本节讨论实现的细节(This section discusses implementation details of) FretboardJs
.(.)
定义全局名称空间后(After defining the global namespace) Fretboard
,这两个对象指定了整体指板(, two objects that specify overall fretboard)行为(behavior)定义为:(are defined:) Fretboard.Metrics
和(and)指板.(Fretboard.) Neck
.(.)
指标(Metrics)
Fretboard.Metrics
提供诸如指板宽度,第n个指板长度,弦位置,点位置等值的度量.(provides measures for values such as fretboard width, n-th fret length, string-position, dot-position.)
校准(Calibration)
的(The) Fretboard.Metric
对象是(object is)已校准(calibrated)在初始化时,将直接从SVG的父元素中检索SVG元素的可用宽度.(on initialization, at which point the available width of the SVG element is retrieved directly from the SVG’s parent element.)的(The)最大值(maximum)available with用于将SVG元素本身的宽度设置为父元素宽度的95%.这个(available with is used to set the width of the SVG element itself to 95% of the parent element’s width. This) Width
成为指板的"长度",然后用于(becomes the ‘length’ of the fretboard, which is then used to)确定(determine)颈宽或'(the breadth of the neck or ‘) Height
而是将SVG元素的高度设置为此(’ rather, and the height of SVG element is set to this) Height
值.的(value. The) Height
被任意选择为占22.75%(is arbitrarily chosen to be 22.75% of the) Width
. (在提及这些术语"宽度/高度/长度/(. (There is potential confusion in referring to these terms width/height/length/)宽度(breadth),因此我们在脖子特定术语(例如脖子的长度或脖子的宽度)之间没有区别,现在仅指的是SVG元素的Width和Height.)(, so we drop the distinction between neck specific terminology like length of neck or width of neck, and now refer only to the Width and Height of the SVG element.))
的(The)校准(Calibrate)然后功能将螺母的位置设置为3%(function then sets the position of the nut at 3% of) Width
并将此值存储在私有变量中(and stores this value in private variable) barPosition
.(.)
由于SVG元素使用父元素宽度的95%,因此将SVG元素的左右边界设置为2.5%将创建完全响应的渲染.(Since the SVG element uses 95% of the parent element’s width, setting the left and right margins of the SVG element to 2.5% will create a fully responsive rendering.)
function Calibrate(svg) {
var fretboardApp = svg.parentNode;
self.Width = Math.round(.95 * fretboardApp.clientWidth);
self.Height = Math.round(0.2275 * self.Width);
svg.setAttribute('width', self.Width + "px");
svg.setAttribute('height', self.Height + "px");
barPosition = self.Width * 0.0375;
}
微动位置(Fret Position)
使用(Frets are position using the)Fretboard.Metric.FretPosition(n)(Fretboard.Metric.FretPosition(n))功能(function).此功能使用标准的琴弦宽度功能,使用给定的琴弦沿x轴返回位置.(. This function returns the position along the x-axis for the given fret using the standard luthier’s function for fret widths.)
function FretPosition(n) {
var length = self.Width * 1.85;
var position = barPosition + length - (length / Math.pow(2, (n / 12)));
return position;
}
手指位置(Finger Position)
Fretboard.Metric.FingerPosition(n)(Fretboard.Metric.FingerPosition(n))返回给定品格沿x轴的距离(returns the distance along the x-axis for a given fret) n
.此方法返回(. This method returns the)半(half-way)在品格n和品格(n-1)之间的点.例如,第一品指的位置在中间(point between fret n and fret (n-1). For example, the 1st fret finger position is half way)之间(between)第0个品格和第一个品格.(the 0-th fret and the first fret.)
function FingerPosition(n) {
if (n < 0 || n > highestFret) {
throw "Argument out of range: N-th Fret must be between 0 and 9 inclusive. n = " + n;
}
var p = FretPosition(n - 1);
var q = FretPosition(n);
var position = p + (q - p) / 2;
return position;
}
弦位置(String Position)
最后,(Finally,)指板(Fretboard.Metric.) StringPosition(n)
返回(returns the)位置(position)沿y轴的第n个字符串.(along the y-axis for the n-th string.)
function StringPosition(n) {
if (n < 1 || n > 7) {
throw "Argument out of range: N-th String must be between 1 and 6 inclusive. n = " + n;
}
var result = 0.086 * self.Height + (n - 1) * 0.165 * self.Height;
return result;
}
颈部(Neck)
Fretboard.Neck
负责绘制SVG元素,包括弦,品格,嵌体,(is responsible for drawing the SVG elements including strings, frets, inlays,)等等(etc.),也用于绘制指法.(, and also for drawing fingerings.)
方法(the method) DrawFretboard(svg)
使用SVG元素,配置(takes an SVG element, configures the) Metrics
通过调用对象(object by calling the)校准(Calibration)函数,然后继续渲染(function and then proceeds to render the)颈部(neck),嵌体,品格,细绳和螺母(或头部).(, the inlays, the frets, strings and nut (or head).)
SVG两个重要的SVG组" fretboard-layer"和" fingering-layer"也从SVG元素中检索并存储在私有变量中(The two important SVG groups ‘fretboard-layer’ and ‘fingering-layer’ are also retrieved from the SVG element and stored in private variables) fretboardLayer
和(and) fingeringLayer
.(.)
function DrawFretboard(svg) {
app = svg.parentNode;
fretboardLayer = svg.getElementById('fretboard-layer');
fingeringLayer = svg.getElementById('fingering-layer');
Fretboard.Metrics.Calibrate(svg);
AddNeckDetail(3);
AddNeckDetail(5);
AddNeckDetail(7);
AddNeckDetail(9);
AddNeckDetail(12);
AddFrets();
AddStrings();
DrawNut();
}
抽颈(Draw Neck)
DrawNeck
现在在(now creates a rectangle in the) fretboardLayer
组(在(group (a private variable initialized in the) DrawFretboard
方法).矩形的左上角位置是靠在螺母上,并且距SVG边框的边缘向下3个像素.矩形延伸到SVG元素的整个宽度,并向下延伸到底部SVG边界上方的3个像素.并且为背景填充分配了id值" fretboard-gradient",该值被定义为SVG标记中的线性渐变.(method). The top left position of the rectangle is position to rest against the nut and 3 pixels down from the edge of the SVG border. The rectangle extends to the full width of the SVG element and down to 3 pixel above the bottom SVG border. And the background fill is assigned the id value ‘fretboard-gradient’, which was defined as a linear gradient in the markup for the SVG.)
function DrawNeck() {
var shape = document.createElementNS(Fretboard.NS, "rect");
shape.x.baseVal.value = Fretboard.Metrics.BarPosition;
shape.y.baseVal.value = 3;
shape.width.baseVal.value = width;
shape.height.baseVal.value = height - 6;
shape.setAttribute("height", height - 6);
shape.style.stroke = 'black';
shape.style.strokeWidth = 2;
shape.style.fill = 'url(#fretboard-gradient)';
fretboardLayer.appendChild(shape);
return shape;
}
这时可能会感到奇怪:为什么要在其中定义诸如fretboard-rectangle之类的元素(It may be wondered at this point: why define elements such as this fretboard-rectangle in)的JavaScript(JavaScript)或其他任何元素(字符串,品格等),而不是在标记中?这种方法的问题在于,针对编程元素(如指法)的度量标准将与标记元素区别开来.(, or any of the other elements, the strings, frets etc., rather than in the markup? The problem with that approach is that the metrics for programmatic elements like fingerings would then be defined distinctly from markup elements.)
因此,与上面的代码一样,每个其他指板组件都被渲染到(So, as with the code above, each of the other fretboard components are rendered into the) fretboardLayer
以相同的方式分组.(group in the same way.)
添加烦恼(Add Frets)
每个品格使用(Each fret is drawn using the) DrawFret
使用的方法(method which uses the)Fretboard.Metrics.FretPosition(Fretboard.Metrics.FretPosition)每个品格的功能,并沿x轴在给定距离处绘制白色垂直线.直到每个品格都调用此方法(function for each fret and draws a white vertical line at the given distance along the x-axis. This method is called for each fret up to) Fretboard.Metrics.HighestFret
.(.)
function DrawFret(x1, y1, x2, y2) {
var shape = document.createElementNS(Fretboard.NS, "line");
shape.x1.baseVal.value = x1;
shape.x2.baseVal.value = x2;
shape.y1.baseVal.value = y1;
shape.y2.baseVal.value = y2;
shape.style.stroke = 'white';
shape.style.strokeWidth = width * 0.0035;
fretboardLayer.appendChild(shape);
return shape;
}
function AddFrets() {
for (var i = 1; i <= Fretboard.Metrics.HighestFret; i++) {
var position = Fretboard.Metrics.FretPosition(i);
DrawFret(position, 2, position, height - 2);
}
}
添加字符串(Add String)
重复相同的过程以添加字符串.的(The same procedure is repeated to add the strings. The) AddStrings
函数重试6个琴弦中每个琴弦沿y轴的第n个琴弦位置,并从螺母到指板的右端画一条线.(function retries the n-th string position along the y-axis for each of the 6 string and draws a line from the nut to the right end of the fretboard.)
function DrawString(x1, y1, x2, y2, guage) {
var shape = document.createElementNS(Fretboard.NS, "line");
shape.x1.baseVal.value = x1;
shape.x2.baseVal.value = x2;
shape.y1.baseVal.value = y1;
shape.y2.baseVal.value = y2;
shape.style.stroke = '#cbcbcb';
shape.style.strokeWidth = guage;
fretboardLayer.appendChild(shape);
return shape;
}
function AddStrings() {
for (var i = 1; i < 7; i++) {
var position = Fretboard.Metrics.StringPosition(i);
DrawString(Fretboard.Metrics.BarPosition, position, width, position,
Fretboard.Metrics.StringGague(i));
}
}
加点(Adding Dots)
通过添加点将指法添加到指板.点被添加到(Fingerings are added to the fretboard by adding dots. Dots are added to the) fingeringLayer
SVG组.(SVG group.)
的(The) AddDot
功能需要一个(function takes a) Finger
对象和一个可选(object and an optional) ghost
论据.如果(argument. If) ghost
如果为true,则该点以褪色的白色呈现为部分透明.的(is true then the dot is rendered partially transparent in a faded white color. The) Finger
对象指定(object specifies the) Fret
,(,) String
和(and) Finger
为点.(for the dot.)
现在的功能(The function now)使用创建点(creates the dot using)SVG(an SVG) circle
元素,以及(element, and)取决于是否(depending on whether) ghost
是true或false,用部分透明的白色填充点,或用id值'(is true or false, fills the dot with partially transparent white, or the radial gradient with the id value ‘) fingering-dot-gradient
‘,(’,)在标记中定义(defined in the markup).(.)
接下来,该函数确定是否(Next, the function determines whether) Fret
为0,在这种情况下,填充是透明的,并且(is 0, in which case the fill is transparent, and the) circle
被赋予了较宽的蓝色笔触宽度.(is given a broad blue stroke width.)
的(The) dot
然后附加到(is then appended to the) fingeringLayer
SVG组.(SVG group.)
最后,如果(Finally, if) Fret
不为0,则创建一个显示Finger值的SVG文本元素,并(is not 0, an SVG text element showing value of Finger is created and)居中(centred)在点上.(in the dot.)
function AddDot(finger, ghost) {
var dot = document.createElementNS(Fretboard.NS, "circle");
dot.Finger = finger;
dot.setAttributeNS(null, "cx", Fretboard.Metrics.FingerPosition(finger.Fret));
dot.setAttributeNS(null, "cy", Fretboard.Metrics.StringPosition(finger.String));
dot.setAttributeNS(null, "r", .017 * width);
if (ghost) {
dot.setAttributeNS(null, "fill", "white");
dot.setAttributeNS(null, "opacity", ".1");
}
else {
dot.setAttributeNS(null, "fill", "url(#fingering-dot-gradient)");
}
if (finger.Fret == 0) {
dot.setAttributeNS(null, "cx", .011 * width + width * 0.004);
dot.setAttributeNS(null, "r", .008 * width);
dot.setAttributeNS(null, "fill", "transparent");
dot.style.stroke = '#0090ff';
dot.style.strokeWidth = width * 0.004;
}
fingeringLayer.appendChild(dot);
if (!ghost && !!finger.Fret && !!finger.Finger) {
var text = document.createElementNS(Fretboard.NS, "text");
text.setAttribute('x', Fretboard.Metrics.FingerPosition(finger.Fret) - width * 0.006);
text.setAttribute('y', Fretboard.Metrics.StringPosition(finger.String) + width * 0.007);
text.textContent = finger.Finger;
text.setAttributeNS(null, "fill", "white");
text.style.fontSize = width * .0225 + 'px';
text.style.fontWeight = 'lighter';
fingeringLayer.appendChild(text);
fingeringText.push(text);
}
dot.addEventListener('click', OnClickDot);
return dot;
}
消除指法(Erase Fingerings)
可以通过调用指板来清除指板中的所有指法.(The fretboard can be cleared of all fingerings by calling the) Fretboard.Neck.EraseFingerings
函数,只是删除了所有内部内容(function, which simply removes all inner content of the) fingeringLayer
SVG组.(SVG group.)
function EraseFingerings() {
fingeringLayer.textContent = '';
}
添加和弦和音阶(Adding Chords and Scales)
的(The) AddChord
和(and) AddScale
功能需要(functions take a) Chord
和(and) Scale
对象,分别调用(object, respectively, and call the) AddDot
给定中定义的每个指法的功能(function for each of the fingerings defined in the given) Chord
要么(or) Scale
.(.)
下面显示(The following shows the) AddChord
功能. ((function. (The) AddScale
函数是相同的.)这些函数接受一个(function is identical.) These functions accept a) ghost
参数,并将该值传递给(argument also, and passes that value to the) AddDot
功能.(function.)
function AddChord(chord, ghost) {
chord.Fingering.forEach(function (a) {
AddDot(a, ghost);
});
}
和弦,音阶和指法(Chords, Scales and Fingerings)
的(The) Chord
,(,) Scales
和(and) Finger
对象定义在(objects are defined in) global
范围.不幸的是,这是原始设计的错误,但会得到纠正.(scope. Unfortunately, this was an error of original design, but will be corrected.)
手指(Finger)
手指对象(The Finger object)完全指定指板上任何音符的指法.大多数指板(fully specifies the fingering for any note on the fretboard. Most FretboardJs)组件(components)有一个(have a)依赖(dependency)在手指对象上. Finger对象包含以下属性:(on the Finger object. The Finger object contains the following properties:)
Fret
String
Finger
Degree
这个(This)Finger
对象还包含可选信息,用于指定使用哪个手指以及音阶或和弦(如果存在)中音符的上下文.(object also contains optional information specifying which finger is used and the context of the note within a scale or Chord if one exists.)
function Finger(fret, string, finger, degree) {
var Finger = finger || 0;
var Fret = fret;
var String = string;
var Degree = degree || 0;
var self = {
Degree: Degree,
Finger: Finger,
Fret: Fret,
String: String,
};
return self;
}
弦(Chord)
的(The) Chord
对象是的命名数组(object is a named array of) Finger
对象.(objects.)
附带的和弦库基于标准吉他调音,但可以重新定义以进行其他调音.和弦命名是任意的,并留下了任何指法/命名组合的可能性.(The included chord library is based on standard guitar tuning, but can be redefined for alternate tunings. Chord naming is arbitrary and leaves open the possibility of any fingering/naming combination.)
这给出了基本的结构(This gives the essential structure of the) Chord
对象为:(object as:)
function Chord(def) {
var Name = def.name;
var Fingering = def.fingering;
var self = {
Fingering: Fingering,
Name: Name,
};
return self;
}
的(The) Chord
对象定义了许多功能.(object defines a number of functions however.)
例如,(For example, the) Transpose
功能,可调整(function, which adjusts a copy of the) Chord
给定数量的半音.(a given number of semi-tones.)
function Transpose(n) {
var result = self.Copy();
result.Fingering.forEach(function (a) {
a.Fret += n;
});
return result;
}
锐化或展平和弦度(Sharpen or Flatten Chord Degrees) 随附的和弦库仅用于标准调音.但是,Chord对象上的函数可用于系统地修改Chords:(The included chord library is defined for standard tunings only. However, functions on the Chord object are available to systematically modify Chords:)
function Flaten(degree) {
var result = self.Copy();
result.Fingering.forEach(function (a) {
if (a.Degree == degree) {
a.Fret--;
}
});
return result;
}
function Sharpen(degree) {
var result = self.Copy();
result.Fingering.forEach(function (a) {
if (a.Degree == degree) {
a.Fret++;
}
});
return result;
}
规模(Scale)
比例对象是(The scale object is)几乎相同(virtually identical)和弦对象的相关性,因此此处不再赘述.(to the Chord object so will not be discussed further here.)
和弦图书馆(The Chord Library)
和弦库在名称空间中定义(The chord library is defined in the namespace) Fretboard.Chords
.(.)
Fretboard.Chords = {};
并且该库由命名(And the library consists of named) Chord
组.例如,t(groups. For example, t)他在下面显示了(he following shows the definition of the) MajorTriad
包含两个和弦的和弦组:(chord group containing two chords:)
<span style="font-size: 14px;">Fretboard.Chords.MajorTriad = function () {</span>
var self = [
new Chord({
name: 'E',
fingering: [
new Finger(0, 6, 1, 1),
new Finger(2, 5, 3, 5),
new Finger(2, 4, 4, 1),
new Finger(1, 3, 2, 3),
new Finger(0, 2, 1, 5),
new Finger(0, 1, 1, 1),
],
}),
new Chord({
name: 'D',
fingering: [
new Finger(0, 4, 1, 1),
new Finger(2, 3, 2, 5),
new Finger(3, 2, 4, 1),
new Finger(2, 1, 3, 3),
],
OpenOnly: true
})
];
return self;
}();
Chord
可以从另一个算法定义组(groups can be defined algorithmically from another) Chord
组,如以下代码所示.这里,(group as the following code shows. Here,) MinorTriad
通过将每个和弦的3度从(Chord group is defined by flattening the 3rd degree of each chord from the) MajorTriad
组.可以定义验证规则来确定是否对给定的修改(group. A validation rule can be defined to determine if a modification to a given) Chord
已验证.在这种情况下,该规则要求和弦的手指跨度不能超过四个品格.(is valid. In this case the rule requires that the finger span of a chord not exceed four frets.)
Fretboard.Chords.MinorTriad = function () {
var self = [];
for (var i = 0; i < Fretboard.Chords.MajorTriad.length; i++) {
var chord = Fretboard.Chords.MajorTriad[i].Flaten3rd();
if (chord.Span() > 4)
{
continue;
}
self.push(chord);
}
return self;
}();
库中的和弦组可以被覆盖.(Chord groups in the library can be overwritten.)
剧本(Scripts)
scripts文件夹包含此讨论的所有代码.此文件夹包括以下文件:(The scripts folder contains all the code to this discussion. This folder includes the following files:)
- _namespace.js:(_namespace.js:)定义了称为的基本名称空间(defines the basic namespace called)
Fretboard
.(.) - chord.js:(chord.js:)定义(defines the)
Finger
,(,)Chord
和(and)Notes
对象.(objects.) - chords.js:(chords.js:)定义所有可用的和弦家族(defines all available chord families)
- metrics.js:(metrics.js:)定义全局指标和计算,以确定诸如第n个品格沿x轴的位置之类的各种坐标值.(defines global metrics and calculations to determine various coordinate values for things like the position along the x-axis for the n-th fret.)
- eck.js:(neck.js:)定义主FretboardJs对象(defines the main FretboardJs object)
Neck
.(.) - scale.js:(scale.js:)定义Scale对象,类似于和弦对象(defines the Scale object, similar is use to the Chord object)
- scales.js:(scales.js:)定义一个比例组库(defines a library of scales groups into)
- app.js:(app.js:)定义示例应用程序" Chord Explorer".(defines the sample app ‘‘Chord Explorer’.)
- chord-utility.js:(chord-utility.js:)以正则表达式列表的形式定义一个关联表(defines an associative table in the form of a list of regular expression)比较(comparisons)返回与给定和弦拼写匹配的通用和弦系列.(to return a generic chord family matching a given chord spelling.)
- fretboard-1.3.0.js:(fretboard-1.3.0.js:)捆绑图书馆(the bundled library)
- fretboard-1.3.0.min.js:(fretboard-1.3.0.min.js:)缩小的束(the minified bundle)
历史(History)
- 2014年7月30日-初始帖子,包括对演示应用程序" Chord Explorer"的初步讨论以及FretboardJs的用法(2014, July 30 - initial post including preliminary discussion of the demo app ‘Chord Explorer’, and usage of FretboardJs)弦(chord)图书馆.(library.)
- 2014年8月1日-版本1.3,包括设计和实现讨论(2014, August 1 - version 1.3, include design and implementation discussion)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
Javascript cloud Design Dev 新闻 翻译