VexFlow - Copyright (c) Mohit Muthanna 2010.
This file implements utility methods used by the rest of the VexFlow codebase.
const Vex = () => {};
Default log function sends all arguments to console.
Vex.L = (block, args) => {
if (!args) return;
const line = Array.prototype.slice.call(args).join(' ');
window.console.log(block + ': ' + line);
};
Default runtime exception.
class RuntimeError {
constructor(code, message) {
this.code = code;
this.message = message;
}
toString() {
return 'RuntimeError: ' + this.message;
}
}
Shortcut method for RuntimeError
.
Vex.RuntimeError = RuntimeError;
Vex.RERR = Vex.RuntimeError;
Merge destination
hash with source
hash, overwriting like keys
in source
if necessary.
Vex.Merge = (destination, source) => {
for (const property in source) { // eslint-disable-line guard-for-in
destination[property] = source[property];
}
return destination;
};
DEPRECATED. Use Math.*
.
Vex.Min = Math.min;
Vex.Max = Math.max;
Vex.forEach = (a, fn) => {
for (let i = 0; i < a.length; i++) {
fn(a[i], i);
}
};
Round number to nearest fractional value (.5
, .25
, etc.)
Vex.RoundN = (x, n) =>
(x % n) >= (n / 2)
? parseInt(x / n, 10) * n + n
: parseInt(x / n, 10) * n;
Locate the mid point between stave lines. Returns a fractional line if a space.
Vex.MidLine = (a, b) => {
let mid_line = b + (a - b) / 2;
if (mid_line % 2 > 0) {
mid_line = Vex.RoundN(mid_line * 10, 5) / 10;
}
return mid_line;
};
Take arr
and return a new list consisting of the sorted, unique,
contents of arr. Does not modify arr
.
Vex.SortAndUnique = (arr, cmp, eq) => {
if (arr.length > 1) {
const newArr = [];
let last;
arr.sort(cmp);
for (let i = 0; i < arr.length; ++i) {
if (i === 0 || !eq(arr[i], last)) {
newArr.push(arr[i]);
}
last = arr[i];
}
return newArr;
} else {
return arr;
}
};
Check if array a
contains obj
.
Vex.Contains = (a, obj) => {
let i = a.length;
while (i--) {
if (a[i] === obj) {
return true;
}
}
return false;
};
Get the 2D Canvas context from DOM element canvas_sel
.
Vex.getCanvasContext = canvas_sel => {
if (!canvas_sel) {
throw new Vex.RERR('BadArgument', 'Invalid canvas selector: ' + canvas_sel);
}
const canvas = document.getElementById(canvas_sel);
if (!(canvas && canvas.getContext)) {
throw new Vex.RERR(
'UnsupportedBrowserError', 'This browser does not support HTML5 Canvas'
);
}
return canvas.getContext('2d');
};
Draw a tiny dot marker on the specified canvas. A great debugging aid.
ctx
: Canvas context.
x
, y
: Dot coordinates.
Vex.drawDot = (ctx, x, y, color = '#55') => {
ctx.save();
ctx.setFillStyle(color);
draw a circle
ctx.beginPath();
ctx.arc(x, y, 3, 0, Math.PI * 2, true);
ctx.closePath();
ctx.fill();
ctx.restore();
};
Benchmark. Run function f
once and report time elapsed shifted by s
milliseconds.
Vex.BM = (s, f) => {
const start_time = new Date().getTime();
f();
const elapsed = new Date().getTime() - start_time;
Vex.L(s + elapsed + 'ms');
};
Get stack trace.
Vex.StackTrace = () => {
const err = new Error();
return err.stack;
};
Dump warning to console.
Vex.W = (...args) => {
const line = Array.prototype.slice.call(args).join(' ');
window.console.log('Warning: ', line, Vex.StackTrace());
};
Used by various classes (e.g., SVGContext) to provide a unique prefix to element names (or other keys in shared namespaces).
Vex.Prefix = text => Vex.Prefix.prefix + text;
Vex.Prefix.prefix = 'vf-';
export { Vex };