abcjs 6.0.3 → 6.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/RELEASE.md +53 -1
- package/SECURITY.md +9 -0
- package/dist/abcjs-basic-min.js +2 -2
- package/dist/abcjs-basic.js +1378 -484
- package/dist/abcjs-basic.js.map +1 -1
- package/dist/abcjs-plugin-min.js +2 -2
- package/index.js +2 -0
- package/package.json +2 -2
- package/src/api/abc_tunebook_svg.js +2 -98
- package/src/const/key-accidentals.js +53 -0
- package/src/const/relative-major.js +92 -0
- package/src/parse/abc_parse.js +20 -9
- package/src/parse/abc_parse_book.js +3 -2
- package/src/parse/abc_parse_key_voice.js +1 -148
- package/src/parse/abc_parse_music.js +2 -2
- package/src/parse/abc_transpose.js +9 -68
- package/src/parse/transpose-chord.js +80 -0
- package/src/str/output.js +433 -0
- package/src/synth/abc_midi_flattener.js +1 -1
- package/src/synth/create-note-map.js +4 -0
- package/src/test/abc_parser_lint.js +1 -1
- package/src/write/abc_abstract_engraver.js +12 -0
- package/src/write/abc_beam_element.js +24 -0
- package/src/write/abc_decoration.js +13 -0
- package/src/write/abc_engraver_controller.js +64 -1
- package/src/write/abc_glissando_element.js +7 -0
- package/src/write/draw/draw.js +8 -0
- package/src/write/draw/glissando.js +75 -0
- package/src/write/draw/staff-group.js +5 -5
- package/src/write/draw/voice.js +4 -0
- package/src/write/selection.js +48 -12
- package/src/write/top-text.js +1 -1
- package/types/index.d.ts +56 -8
- package/version.js +1 -1
- package/temp.txt +0 -16
|
@@ -32,6 +32,7 @@ var tablatures = require('../api/abc_tablatures');
|
|
|
32
32
|
*/
|
|
33
33
|
var EngraverController = function(paper, params) {
|
|
34
34
|
params = params || {};
|
|
35
|
+
this.oneSvgPerLine = params.oneSvgPerLine;
|
|
35
36
|
this.selectionColor = params.selectionColor;
|
|
36
37
|
this.dragColor = params.dragColor ? params.dragColor : params.selectionColor;
|
|
37
38
|
this.dragging = !!params.dragging;
|
|
@@ -246,9 +247,71 @@ EngraverController.prototype.engraveTune = function (abcTune, tuneNumber, lineOf
|
|
|
246
247
|
this.staffgroups = ret.staffgroups;
|
|
247
248
|
this.selectables = ret.selectables;
|
|
248
249
|
|
|
249
|
-
|
|
250
|
+
if (this.oneSvgPerLine) {
|
|
251
|
+
var div = this.renderer.paper.svg.parentNode
|
|
252
|
+
this.svgs = splitSvgIntoLines(div, abcTune.metaText.title)
|
|
253
|
+
} else {
|
|
254
|
+
this.svgs = [this.renderer.paper.svg];
|
|
255
|
+
}
|
|
256
|
+
setupSelection(this, this.svgs);
|
|
250
257
|
};
|
|
251
258
|
|
|
259
|
+
function splitSvgIntoLines(output, title) {
|
|
260
|
+
// Each line is a top level <g> in the svg. To split it into separate
|
|
261
|
+
// svgs iterate through each of those and put them in a new svg. Since
|
|
262
|
+
// they are placed absolutely, the viewBox needs to be manipulated to
|
|
263
|
+
// get the correct vertical positioning.
|
|
264
|
+
// We copy all the attributes from the original svg except for the aria-label
|
|
265
|
+
// since we want that to include a count. And the height is now a fraction of the original svg.
|
|
266
|
+
if (!title) title = "Untitled"
|
|
267
|
+
var source = output.querySelector("svg")
|
|
268
|
+
var style = source.querySelector("style")
|
|
269
|
+
var width = source.getAttribute("width")
|
|
270
|
+
var sections = output.querySelectorAll("svg > g") // each section is a line, or the top matter or the bottom matter, or text that has been inserted.
|
|
271
|
+
var nextTop = 0 // There are often gaps between the elements for spacing, so the actual top and height needs to be inferred.
|
|
272
|
+
var wrappers = [] // Create all the elements and place them at once because we use the current svg to get data. It would disappear after placing the first line.
|
|
273
|
+
var svgs = []
|
|
274
|
+
for (var i = 0; i < sections.length; i++) {
|
|
275
|
+
var section = sections[i]
|
|
276
|
+
var box = section.getBBox()
|
|
277
|
+
var gapBetweenLines = box.y - nextTop // take the margin into account
|
|
278
|
+
var height = box.height + gapBetweenLines;
|
|
279
|
+
var wrapper = document.createElement("div");
|
|
280
|
+
wrapper.setAttribute("style", "overflow: hidden;height:"+height+"px;")
|
|
281
|
+
var svg = duplicateSvg(source)
|
|
282
|
+
var fullTitle = "Sheet Music for \"" + title + "\" section " + (i+1)
|
|
283
|
+
svg.setAttribute("aria-label", fullTitle)
|
|
284
|
+
svg.setAttribute("height", height)
|
|
285
|
+
svg.setAttribute("viewBox", "0 " + nextTop + " " + width + " " + height )
|
|
286
|
+
svg.appendChild(style.cloneNode(true))
|
|
287
|
+
var titleEl = document.createElement("title")
|
|
288
|
+
titleEl.innerText = fullTitle
|
|
289
|
+
svg.appendChild(titleEl)
|
|
290
|
+
svg.appendChild(section)
|
|
291
|
+
|
|
292
|
+
wrapper.appendChild(svg)
|
|
293
|
+
svgs.push(svg)
|
|
294
|
+
output.appendChild(wrapper)
|
|
295
|
+
//wrappers.push(wrapper)
|
|
296
|
+
nextTop = box.y+box.height
|
|
297
|
+
}
|
|
298
|
+
// for (i = 0; i < wrappers.length; i++)
|
|
299
|
+
// output.appendChild(wrappers[i])
|
|
300
|
+
output.removeChild(source)
|
|
301
|
+
return svgs;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function duplicateSvg(source) {
|
|
305
|
+
var svgNS = "http://www.w3.org/2000/svg";
|
|
306
|
+
var svg = document.createElementNS(svgNS, "svg");
|
|
307
|
+
for (var i = 0; i < source.attributes.length; i++) {
|
|
308
|
+
var attr = source.attributes[i];
|
|
309
|
+
if (attr.name !== "height" && attr.name != "aria-label")
|
|
310
|
+
svg.setAttribute(attr.name, attr.value)
|
|
311
|
+
}
|
|
312
|
+
return svg;
|
|
313
|
+
}
|
|
314
|
+
|
|
252
315
|
EngraverController.prototype.getDim = function(historyEl) {
|
|
253
316
|
// Get the dimensions on demand because the getBBox call is expensive.
|
|
254
317
|
if (!historyEl.dim) {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
var GlissandoElem = function GlissandoElem(anchor1, anchor2) {
|
|
2
|
+
this.type = "GlissandoElem";
|
|
3
|
+
this.anchor1 = anchor1; // must have a .x and a .parent property or be null (means starts at the "beginning" of the line - after keysig)
|
|
4
|
+
this.anchor2 = anchor2; // must have a .x property or be null (means ends at the end of the line)
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
module.exports = GlissandoElem;
|
package/src/write/draw/draw.js
CHANGED
|
@@ -6,14 +6,17 @@ var Selectables = require('./selectables');
|
|
|
6
6
|
|
|
7
7
|
function draw(renderer, classes, abcTune, width, maxWidth, responsive, scale, selectTypes, tuneNumber, lineOffset) {
|
|
8
8
|
var selectables = new Selectables(renderer.paper, selectTypes, tuneNumber);
|
|
9
|
+
renderer.paper.openGroup()
|
|
9
10
|
renderer.moveY(renderer.padding.top);
|
|
10
11
|
nonMusic(renderer, abcTune.topText, selectables);
|
|
12
|
+
renderer.paper.closeGroup()
|
|
11
13
|
renderer.moveY(renderer.spacing.music);
|
|
12
14
|
var staffgroups = [];
|
|
13
15
|
for (var line = 0; line < abcTune.lines.length; line++) {
|
|
14
16
|
classes.incrLine();
|
|
15
17
|
var abcLine = abcTune.lines[line];
|
|
16
18
|
if (abcLine.staff) {
|
|
19
|
+
renderer.paper.openGroup()
|
|
17
20
|
if (abcLine.vskip) {
|
|
18
21
|
renderer.moveY(abcLine.vskip);
|
|
19
22
|
}
|
|
@@ -22,15 +25,20 @@ function draw(renderer, classes, abcTune, width, maxWidth, responsive, scale, se
|
|
|
22
25
|
var staffgroup = engraveStaffLine(renderer, abcLine.staffGroup, selectables,line);
|
|
23
26
|
staffgroup.line = lineOffset+line; // If there are non-music lines then the staffgroup array won't line up with the line array, so this keeps track.
|
|
24
27
|
staffgroups.push(staffgroup);
|
|
28
|
+
renderer.paper.closeGroup()
|
|
25
29
|
} else if (abcLine.nonMusic) {
|
|
30
|
+
renderer.paper.openGroup()
|
|
26
31
|
nonMusic(renderer, abcLine.nonMusic, selectables);
|
|
32
|
+
renderer.paper.closeGroup()
|
|
27
33
|
}
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
classes.reset();
|
|
31
37
|
if (abcTune.bottomText && abcTune.bottomText.rows && abcTune.bottomText.rows.length > 0) {
|
|
38
|
+
renderer.paper.openGroup()
|
|
32
39
|
renderer.moveY(24); // TODO-PER: Empirically discovered. What variable should this be?
|
|
33
40
|
nonMusic(renderer, abcTune.bottomText, selectables);
|
|
41
|
+
renderer.paper.closeGroup()
|
|
34
42
|
}
|
|
35
43
|
setPaperSize(renderer, maxWidth, scale, responsive);
|
|
36
44
|
return { staffgroups: staffgroups, selectables: selectables.getElements() };
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
var sprintf = require('./sprintf');
|
|
2
|
+
var printPath = require('./print-path');
|
|
3
|
+
var roundNumber = require("./round-number");
|
|
4
|
+
|
|
5
|
+
function drawGlissando(renderer, params, selectables) {
|
|
6
|
+
if (!params.anchor1 || !params.anchor2 || !params.anchor1.heads || !params.anchor2.heads || params.anchor1.heads.length === 0 || params.anchor2.heads.length === 0)
|
|
7
|
+
window.console.error("Glissando Element not set.");
|
|
8
|
+
|
|
9
|
+
var margin = 4;
|
|
10
|
+
var leftY = renderer.calcY(params.anchor1.heads[0].pitch)
|
|
11
|
+
var rightY = renderer.calcY(params.anchor2.heads[0].pitch)
|
|
12
|
+
var leftX = params.anchor1.x + params.anchor1.w/2
|
|
13
|
+
var rightX = params.anchor2.x + params.anchor2.w/2
|
|
14
|
+
var len = lineLength(leftX, leftY, rightX, rightY)
|
|
15
|
+
var marginLeft = params.anchor1.w/2 + margin
|
|
16
|
+
var marginRight = params.anchor2.w/2 + margin
|
|
17
|
+
var s = slope(leftX, leftY, rightX, rightY)
|
|
18
|
+
var leftYAdj = getY(leftY, s, marginLeft)
|
|
19
|
+
var rightYAdj = getY(rightY, s, -marginRight)
|
|
20
|
+
var num = numSquigglies(len-marginLeft-marginRight)
|
|
21
|
+
|
|
22
|
+
var el = drawSquiggly(renderer, leftX+marginLeft, leftYAdj, num, s)
|
|
23
|
+
selectables.wrapSvgEl({el_type: "glissando", startChar: -1, endChar: -1}, el);
|
|
24
|
+
return [el];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function lineLength(leftX, leftY, rightX, rightY) {
|
|
28
|
+
// The length from notehead center to notehead center.
|
|
29
|
+
var w = rightX - leftX
|
|
30
|
+
var h = rightY - leftY
|
|
31
|
+
return Math.sqrt(w*w + h*h)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function slope(leftX, leftY, rightX, rightY) {
|
|
35
|
+
return (rightY-leftY) / (rightX - leftX)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function getY(y, slope, xOfs) {
|
|
39
|
+
return roundNumber(y + (xOfs)*slope);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function numSquigglies(length) {
|
|
43
|
+
var endLen = 5; // The width of the end - that is, the non repeating part
|
|
44
|
+
return Math.max(2, Math.floor((length - endLen*2) / 6));
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
var leftStart = [[3.5, -4.8]]
|
|
48
|
+
var right = [[1.5, -1], [.3, -.3], [-3.5, 3.8]]
|
|
49
|
+
var leftEnd = [[-1.5, 2]]
|
|
50
|
+
var top = [[3, 4], [3, -4]]
|
|
51
|
+
var bottom = [[-3, 4], [-3, -4]]
|
|
52
|
+
|
|
53
|
+
function segment(arr, slope) {
|
|
54
|
+
var ret = "";
|
|
55
|
+
for (var i = 0; i < arr.length; i++) {
|
|
56
|
+
ret += 'l' + arr[i][0] + ' ' + getY(arr[i][1], slope, arr[i][0])
|
|
57
|
+
}
|
|
58
|
+
return ret
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
var drawSquiggly = function(renderer, x, y, num, slope) {
|
|
62
|
+
var p = sprintf("M %f %f", x, y);
|
|
63
|
+
p += segment(leftStart, slope)
|
|
64
|
+
var i
|
|
65
|
+
for (i = 0; i < num; i++) {
|
|
66
|
+
p+=segment(top, slope)
|
|
67
|
+
}
|
|
68
|
+
p += segment(right, slope)
|
|
69
|
+
for ( i = 0; i < num; i++)
|
|
70
|
+
p+=segment(bottom, slope)
|
|
71
|
+
p+=segment(leftEnd, slope) + 'z'
|
|
72
|
+
return printPath(renderer, {path:p, highlight: "stroke", stroke:renderer.foregroundColor, 'class': renderer.controller.classes.generate('decoration'), "data-name": "glissando"});
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
module.exports = drawGlissando;
|
|
@@ -15,7 +15,7 @@ function drawStaffGroup(renderer, params, selectables,lineNumber) {
|
|
|
15
15
|
var colorIndex;
|
|
16
16
|
|
|
17
17
|
// An invisible marker is useful to be able to find where each system starts.
|
|
18
|
-
addInvisibleMarker(renderer, "abcjs-top-of-system");
|
|
18
|
+
//addInvisibleMarker(renderer, "abcjs-top-of-system");
|
|
19
19
|
|
|
20
20
|
var startY = renderer.y; // So that it can be restored after we're done.
|
|
21
21
|
// Set the absolute Y position for each staff here, so the voice drawing below can just use if.
|
|
@@ -177,10 +177,10 @@ function printBrace(renderer, absoluteY, brace, index, selectables) {
|
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
function addInvisibleMarker(renderer, className) {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
180
|
+
// function addInvisibleMarker(renderer, className) {
|
|
181
|
+
// var y = Math.round(renderer.y);
|
|
182
|
+
// renderer.paper.pathToBack({path:"M 0 " + y + " L 0 0", stroke:"none", fill:"none", "stroke-opacity": 0, "fill-opacity": 0, 'class': renderer.controller.classes.generate(className), 'data-vertical': y });
|
|
183
|
+
// }
|
|
184
184
|
|
|
185
185
|
function boxAllElements(renderer, voices, which) {
|
|
186
186
|
for (var i = 0; i < which.length; i++) {
|
package/src/write/draw/voice.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
var drawGlissando = require('./glissando');
|
|
1
2
|
var drawCrescendo = require('./crescendo');
|
|
2
3
|
var drawDynamics = require('./dynamics');
|
|
3
4
|
var drawTriplet = require('./triplet');
|
|
@@ -67,6 +68,9 @@ function drawVoice(renderer, params, bartop, selectables, staffPos) {
|
|
|
67
68
|
renderer.controller.classes.incrMeasure();
|
|
68
69
|
} else {
|
|
69
70
|
switch (child.type) {
|
|
71
|
+
case "GlissandoElem":
|
|
72
|
+
child.elemset = drawGlissando(renderer, child, selectables);
|
|
73
|
+
break;
|
|
70
74
|
case "CrescendoElem":
|
|
71
75
|
child.elemset = drawCrescendo(renderer, child, selectables);
|
|
72
76
|
break;
|
package/src/write/selection.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
var spacing = require('./abc_spacing');
|
|
2
2
|
|
|
3
|
-
function setupSelection(engraver) {
|
|
3
|
+
function setupSelection(engraver, svgs) {
|
|
4
4
|
engraver.rangeHighlight = rangeHighlight;
|
|
5
5
|
if (engraver.dragging) {
|
|
6
6
|
for (var h = 0; h < engraver.selectables.length; h++) {
|
|
@@ -14,14 +14,21 @@ function setupSelection(engraver) {
|
|
|
14
14
|
}
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
for (var i = 0; i < svgs.length; i++) {
|
|
18
|
+
svgs[i].addEventListener('touchstart', mouseDown.bind(engraver));
|
|
19
|
+
svgs[i].addEventListener('touchmove', mouseMove.bind(engraver));
|
|
20
|
+
svgs[i].addEventListener('touchend', mouseUp.bind(engraver));
|
|
21
|
+
svgs[i].addEventListener('mousedown', mouseDown.bind(engraver));
|
|
22
|
+
svgs[i].addEventListener('mousemove', mouseMove.bind(engraver));
|
|
23
|
+
svgs[i].addEventListener('mouseup', mouseUp.bind(engraver));
|
|
24
|
+
}
|
|
20
25
|
}
|
|
21
26
|
|
|
22
|
-
function getCoord(ev
|
|
27
|
+
function getCoord(ev) {
|
|
23
28
|
var scaleX = 1;
|
|
24
29
|
var scaleY = 1;
|
|
30
|
+
var svg = ev.target.closest('svg')
|
|
31
|
+
var yOffset = 0
|
|
25
32
|
|
|
26
33
|
// when renderer.options.responsive === 'resize' the click coords are in relation to the HTML
|
|
27
34
|
// element, we need to convert to the SVG viewBox coords
|
|
@@ -31,6 +38,7 @@ function getCoord(ev, svg) {
|
|
|
31
38
|
scaleX = svg.viewBox.baseVal.width / svg.clientWidth
|
|
32
39
|
if (svg.viewBox.baseVal.height !== 0)
|
|
33
40
|
scaleY = svg.viewBox.baseVal.height / svg.clientHeight
|
|
41
|
+
yOffset = svg.viewBox.baseVal.y
|
|
34
42
|
}
|
|
35
43
|
|
|
36
44
|
var svgClicked = ev.target.tagName === "svg";
|
|
@@ -48,7 +56,7 @@ function getCoord(ev, svg) {
|
|
|
48
56
|
y = y * scaleY;
|
|
49
57
|
//console.log(x, y)
|
|
50
58
|
|
|
51
|
-
return [x, y];
|
|
59
|
+
return [x, y+yOffset];
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
function elementFocused(ev) {
|
|
@@ -120,7 +128,7 @@ function keyboardSelection(ev) {
|
|
|
120
128
|
|
|
121
129
|
function findElementInHistory(selectables, el) {
|
|
122
130
|
for (var i = 0; i < selectables.length; i++) {
|
|
123
|
-
if (el === selectables[i].svgEl)
|
|
131
|
+
if (el.dataset.index === selectables[i].svgEl.dataset.index)
|
|
124
132
|
return i;
|
|
125
133
|
}
|
|
126
134
|
return -1;
|
|
@@ -216,7 +224,7 @@ function getMousePosition(self, ev) {
|
|
|
216
224
|
//console.log("clicked on", clickedOn, x, y, self.selectables[clickedOn].svgEl.getBBox(), ev.target.getBBox());
|
|
217
225
|
} else {
|
|
218
226
|
// See if they clicked close to an element.
|
|
219
|
-
box = getCoord(ev
|
|
227
|
+
box = getCoord(ev);
|
|
220
228
|
x = box[0];
|
|
221
229
|
y = box[1];
|
|
222
230
|
clickedOn = findElementByCoord(self, x, y);
|
|
@@ -225,13 +233,30 @@ function getMousePosition(self, ev) {
|
|
|
225
233
|
return { x: x, y: y, clickedOn: clickedOn };
|
|
226
234
|
}
|
|
227
235
|
|
|
236
|
+
function attachMissingTouchEventAttributes(touchEv) {
|
|
237
|
+
var rect = touchEv.target.getBoundingClientRect();
|
|
238
|
+
var offsetX = touchEv.touches[0].pageX - rect.left;
|
|
239
|
+
var offsetY = touchEv.touches[0].pageY - rect.top;
|
|
240
|
+
|
|
241
|
+
touchEv.touches[0].offsetX = offsetX;
|
|
242
|
+
touchEv.touches[0].offsetY = offsetY;
|
|
243
|
+
|
|
244
|
+
touchEv.touches[0].layerX = touchEv.touches[0].pageX;
|
|
245
|
+
touchEv.touches[0].layerY = touchEv.touches[0].pageY;
|
|
246
|
+
}
|
|
247
|
+
|
|
228
248
|
function mouseDown(ev) {
|
|
229
249
|
// "this" is the EngraverController because of the bind(this) when setting the event listener.
|
|
250
|
+
var _ev = ev;
|
|
251
|
+
if (ev.type === 'touchstart') {
|
|
252
|
+
attachMissingTouchEventAttributes(ev);
|
|
253
|
+
_ev = ev.touches[0];
|
|
254
|
+
}
|
|
230
255
|
|
|
231
|
-
var positioning = getMousePosition(this,
|
|
256
|
+
var positioning = getMousePosition(this, _ev);
|
|
232
257
|
|
|
233
258
|
// Only start dragging if the user clicked close enough to an element and clicked with the main mouse button.
|
|
234
|
-
if (positioning.clickedOn >= 0 && ev.button === 0) {
|
|
259
|
+
if (positioning.clickedOn >= 0 && (ev.type === 'touchstart' || ev.button === 0)) {
|
|
235
260
|
this.dragTarget = this.selectables[positioning.clickedOn];
|
|
236
261
|
this.dragIndex = positioning.clickedOn;
|
|
237
262
|
this.dragMechanism = "mouse";
|
|
@@ -244,12 +269,18 @@ function mouseDown(ev) {
|
|
|
244
269
|
}
|
|
245
270
|
|
|
246
271
|
function mouseMove(ev) {
|
|
272
|
+
var _ev = ev;
|
|
273
|
+
if (ev.type === 'touchmove') {
|
|
274
|
+
attachMissingTouchEventAttributes(ev);
|
|
275
|
+
_ev = ev.touches[0];
|
|
276
|
+
}
|
|
277
|
+
this.lastTouchMove = ev;
|
|
247
278
|
// "this" is the EngraverController because of the bind(this) when setting the event listener.
|
|
248
279
|
|
|
249
280
|
if (!this.dragTarget || !this.dragging || !this.dragTarget.isDraggable || this.dragMechanism !== 'mouse')
|
|
250
281
|
return;
|
|
251
282
|
|
|
252
|
-
var positioning = getMousePosition(this,
|
|
283
|
+
var positioning = getMousePosition(this, _ev);
|
|
253
284
|
|
|
254
285
|
var yDist = Math.round((positioning.y - this.dragMouseStart.y)/spacing.STEP);
|
|
255
286
|
if (yDist !== this.dragYStep) {
|
|
@@ -260,6 +291,11 @@ function mouseMove(ev) {
|
|
|
260
291
|
|
|
261
292
|
function mouseUp(ev) {
|
|
262
293
|
// "this" is the EngraverController because of the bind(this) when setting the event listener.
|
|
294
|
+
var _ev = ev;
|
|
295
|
+
if (ev.type === 'touchend') {
|
|
296
|
+
attachMissingTouchEventAttributes(this.lastTouchMove);
|
|
297
|
+
_ev = this.lastTouchMove.touches[0];
|
|
298
|
+
}
|
|
263
299
|
|
|
264
300
|
if (!this.dragTarget)
|
|
265
301
|
return;
|
|
@@ -270,7 +306,7 @@ function mouseUp(ev) {
|
|
|
270
306
|
this.dragTarget.absEl.highlight(undefined, this.selectionColor);
|
|
271
307
|
}
|
|
272
308
|
|
|
273
|
-
notifySelect.bind(this)(this.dragTarget, this.dragYStep, this.selectables.length, this.dragIndex,
|
|
309
|
+
notifySelect.bind(this)(this.dragTarget, this.dragYStep, this.selectables.length, this.dragIndex, _ev);
|
|
274
310
|
if (this.dragTarget.svgEl && this.dragTarget.svgEl.focus) {
|
|
275
311
|
this.dragTarget.svgEl.focus();
|
|
276
312
|
this.dragTarget = null;
|
package/src/write/top-text.js
CHANGED
|
@@ -32,7 +32,7 @@ function TopText(metaText, metaTextInfo, formatting, lines, width, isPrint, padd
|
|
|
32
32
|
this.rows.push({move: spacing.composer});
|
|
33
33
|
if (metaText.rhythm && metaText.rhythm.length > 0) {
|
|
34
34
|
var noMove = !!(metaText.composer || metaText.origin);
|
|
35
|
-
addTextIf(this.rows, { marginLeft: paddingLeft, text: metaText.rhythm, font: 'infofont', klass: 'meta-top rhythm', absElemType: "rhythm", noMove:
|
|
35
|
+
addTextIf(this.rows, { marginLeft: paddingLeft, text: metaText.rhythm, font: 'infofont', klass: 'meta-top rhythm', absElemType: "rhythm", noMove: noMove, info: metaTextInfo.rhythm, name: "rhythm"}, getTextSize);
|
|
36
36
|
}
|
|
37
37
|
var composerLine = "";
|
|
38
38
|
if (metaText.composer) composerLine += metaText.composer;
|
package/types/index.d.ts
CHANGED
|
@@ -64,7 +64,7 @@ declare module 'abcjs' {
|
|
|
64
64
|
export type Decorations = "trill" | "lowermordent" | "uppermordent" | "mordent" | "pralltriller" | "accent" |
|
|
65
65
|
"fermata" | "invertedfermata" | "tenuto" | "0" | "1" | "2" | "3" | "4" | "5" | "+" | "wedge" |
|
|
66
66
|
"open" | "thumb" | "snap" | "turn" | "roll" | "irishroll" | "breath" | "shortphrase" | "mediumphrase" | "longphrase" |
|
|
67
|
-
"segno" | "coda" | "D.S." | "D.C." | "fine" | "crescendo(" | "crescendo)" | "diminuendo(" | "diminuendo)" |
|
|
67
|
+
"segno" | "coda" | "D.S." | "D.C." | "fine" | "crescendo(" | "crescendo)" | "diminuendo(" | "diminuendo)" |"glissando(" | "glissando)" |
|
|
68
68
|
"p" | "pp" | "f" | "ff" | "mf" | "mp" | "ppp" | "pppp" | "fff" | "ffff" | "sfz" | "repeatbar" | "repeatbar2" | "slide" |
|
|
69
69
|
"upbow" | "downbow" | "staccato" | "trem1" | "trem2" | "trem3" | "trem4" |
|
|
70
70
|
"/" | "//" | "///" | "////" | "turnx" | "invertedturn" | "invertedturnx" | "arpeggio" | "trill(" | "trill)" | "xstem" |
|
|
@@ -73,13 +73,13 @@ declare module 'abcjs' {
|
|
|
73
73
|
//
|
|
74
74
|
// Basic types
|
|
75
75
|
//
|
|
76
|
-
export type Selector =
|
|
76
|
+
export type Selector = string | HTMLElement
|
|
77
77
|
|
|
78
78
|
type NumberFunction = () => number;
|
|
79
79
|
|
|
80
80
|
export interface MeterFraction {
|
|
81
|
-
num:
|
|
82
|
-
den?:
|
|
81
|
+
num: number;
|
|
82
|
+
den?: number;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
export interface ClefProperties {
|
|
@@ -171,6 +171,8 @@ declare module 'abcjs' {
|
|
|
171
171
|
|
|
172
172
|
export type AbsoluteElement = any; // TODO
|
|
173
173
|
|
|
174
|
+
export type AbstractEngraver = any;
|
|
175
|
+
|
|
174
176
|
export type NoteProperties = any; // TODO
|
|
175
177
|
|
|
176
178
|
export type AudioTrackCommand = 'program' | 'text' | 'note';
|
|
@@ -261,6 +263,8 @@ declare module 'abcjs' {
|
|
|
261
263
|
instrument: number;
|
|
262
264
|
start: number;
|
|
263
265
|
end: number;
|
|
266
|
+
startChar: number;
|
|
267
|
+
endChar: number;
|
|
264
268
|
volume: number;
|
|
265
269
|
style?: string;
|
|
266
270
|
cents?: number;
|
|
@@ -502,6 +506,34 @@ declare module 'abcjs' {
|
|
|
502
506
|
wordsfont: Font;
|
|
503
507
|
}
|
|
504
508
|
|
|
509
|
+
export interface EngraverController {
|
|
510
|
+
classes: any;
|
|
511
|
+
dragColor: string;
|
|
512
|
+
dragIndex: number;
|
|
513
|
+
dragMouseStart: { x: number, y: number; };
|
|
514
|
+
dragTarget: null | any;
|
|
515
|
+
dragYStep: number;
|
|
516
|
+
dragging: boolean;
|
|
517
|
+
engraver: AbstractEngraver;
|
|
518
|
+
getFontAndAttr: any;
|
|
519
|
+
getTextSize: any;
|
|
520
|
+
listeners: [ClickListener];
|
|
521
|
+
rangeHighlight: any;
|
|
522
|
+
renderer: any;
|
|
523
|
+
responsive?: boolean;
|
|
524
|
+
scale: number;
|
|
525
|
+
initialClef?: any;
|
|
526
|
+
selectTypes: boolean | Array<DragTypes>;
|
|
527
|
+
selectables: Array<Selectable>;
|
|
528
|
+
selected: Array<any>;
|
|
529
|
+
selectionColor: string;
|
|
530
|
+
space: number;
|
|
531
|
+
staffgroups: [any];
|
|
532
|
+
staffwidthPrint: number;
|
|
533
|
+
staffwidthScreen: number;
|
|
534
|
+
width: number;
|
|
535
|
+
}
|
|
536
|
+
|
|
505
537
|
export interface MetaText {
|
|
506
538
|
"abc-copyright"?: string;
|
|
507
539
|
"abc-creator"?: string;
|
|
@@ -710,6 +742,7 @@ declare module 'abcjs' {
|
|
|
710
742
|
|
|
711
743
|
export interface TuneObject {
|
|
712
744
|
formatting: Formatting;
|
|
745
|
+
engraver?: EngraverController;
|
|
713
746
|
lines: Array<TuneLine>;
|
|
714
747
|
media: Media;
|
|
715
748
|
metaText: MetaText;
|
|
@@ -730,12 +763,23 @@ declare module 'abcjs' {
|
|
|
730
763
|
millisecondsPerMeasure: NumberFunction;
|
|
731
764
|
setTiming: (bpm?: number, measuresOfDelay? : number) => void;
|
|
732
765
|
setUpAudio: (options: SynthOptions) => AudioTracks;
|
|
766
|
+
makeVoicesArray: () => Array<Selectable[]>
|
|
733
767
|
lineBreaks?: Array<number>;
|
|
734
768
|
visualTranspose?: number;
|
|
735
769
|
}
|
|
736
770
|
|
|
737
771
|
export type TuneObjectArray = [TuneObject]
|
|
738
772
|
|
|
773
|
+
export interface Selectable {
|
|
774
|
+
absEl: AbsoluteElement;
|
|
775
|
+
isDraggable: boolean;
|
|
776
|
+
staffPos: {
|
|
777
|
+
height: number;
|
|
778
|
+
top: number;
|
|
779
|
+
zero: number;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
|
|
739
783
|
export interface AbcElem {
|
|
740
784
|
el_type: string //TODO enumerate these
|
|
741
785
|
abselem: any;
|
|
@@ -904,7 +948,7 @@ declare module 'abcjs' {
|
|
|
904
948
|
|
|
905
949
|
export interface AudioTrack {
|
|
906
950
|
cmd: AudioTrackCommand;
|
|
907
|
-
[param: any
|
|
951
|
+
[param: string]: any; // TODO - make this a union
|
|
908
952
|
}
|
|
909
953
|
|
|
910
954
|
export interface AudioTracks {
|
|
@@ -1042,7 +1086,7 @@ declare module 'abcjs' {
|
|
|
1042
1086
|
|
|
1043
1087
|
export interface SynthObjectController {
|
|
1044
1088
|
disable(isDisabled: boolean): void
|
|
1045
|
-
setTune(visualObj: TuneObject, userAction:
|
|
1089
|
+
setTune(visualObj: TuneObject, userAction: boolean, audioParams?: any): Promise<SynthInitResponse>
|
|
1046
1090
|
load(selector: string, cursorControl?: any, visualOptions?: SynthVisualOptions): void
|
|
1047
1091
|
play(): void
|
|
1048
1092
|
pause(): void
|
|
@@ -1054,7 +1098,9 @@ declare module 'abcjs' {
|
|
|
1054
1098
|
}
|
|
1055
1099
|
|
|
1056
1100
|
export interface SynthSequenceClass {
|
|
1057
|
-
|
|
1101
|
+
addTrack(): AudioTrack
|
|
1102
|
+
setInstrument(trackNumber: number, instrumentNumber: number): void
|
|
1103
|
+
appendNote(trackNumber: number, pitch: number, durationInMeasures: number, volume: number, cents: number): void
|
|
1058
1104
|
}
|
|
1059
1105
|
|
|
1060
1106
|
export namespace synth {
|
|
@@ -1068,7 +1114,7 @@ declare module 'abcjs' {
|
|
|
1068
1114
|
export function registerAudioContext(ac?: AudioContext): boolean
|
|
1069
1115
|
export function activeAudioContext(): AudioContext
|
|
1070
1116
|
export function CreateSynthControl(element: Selector, options: AbcVisualParams): AudioControl
|
|
1071
|
-
export function getMidiFile(source:
|
|
1117
|
+
export function getMidiFile(source: string | TuneObject, options?: MidiFileOptions): MidiFile;
|
|
1072
1118
|
export function playEvent(pitches: MidiPitches, graceNotes: MidiGracePitches, milliSecondsPerMeasure: number): Promise<void>;
|
|
1073
1119
|
export function sequence(visualObj: TuneObject, options: AbcVisualParams): AudioSequence
|
|
1074
1120
|
}
|
|
@@ -1087,6 +1133,8 @@ declare module 'abcjs' {
|
|
|
1087
1133
|
|
|
1088
1134
|
export function numberOfTunes(abc: string) : number;
|
|
1089
1135
|
export function extractMeasures(abc: string) : Array<MeasureList>;
|
|
1136
|
+
|
|
1137
|
+
export function strTranspose(originalAbc: string, visualObj: TuneObject, steps: number): string;
|
|
1090
1138
|
|
|
1091
1139
|
//
|
|
1092
1140
|
// Glyph
|
package/version.js
CHANGED
package/temp.txt
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
Fix unhandled rejection if there is a problem with an input note when creating notes.
|
|
2
|
-
|
|
3
|
-
put the height of ties/slurs in the line height calculation
|
|
4
|
-
|
|
5
|
-
Add transposition tests.
|
|
6
|
-
|
|
7
|
-
Add example of reusing created synth buffers.
|
|
8
|
-
|
|
9
|
-
Measurements that used "px" were reporting a warning.
|
|
10
|
-
|
|
11
|
-
Add quote to be escaped in chord.
|
|
12
|
-
|
|
13
|
-
Fix example in docs on creating a drum rhythm
|
|
14
|
-
|
|
15
|
-
Fix bass note in jazz chord when it contains a sharp or flat
|
|
16
|
-
|