@stringsync/vexml
Version:
MusicXML to Vexflow
101 lines (100 loc) • 3.97 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.GapOverlay = void 0;
const util = __importStar(require("../util"));
const spatial_1 = require("../spatial");
const textmeasurer_1 = require("./textmeasurer");
const label_1 = require("./label");
class GapOverlay {
config;
log;
label;
fragmentRender;
style;
ctx = null;
constructor(config, log, label, fragmentRender, style) {
this.config = config;
this.log = log;
this.label = label;
this.fragmentRender = fragmentRender;
this.style = style;
util.assert(fragmentRender.rectSrc !== 'none'); // This means we can trust the rects.
}
setContext(ctx) {
this.ctx = ctx;
return this;
}
draw() {
const ctx = this.ctx;
util.assertNotNull(ctx);
const topRect = this.fragmentRender.partRenders.at(0)?.staveRenders.at(0)?.playableRect;
util.assertDefined(topRect);
const bottomRect = this.fragmentRender.partRenders.at(-1)?.staveRenders.at(-1)?.playableRect;
util.assertDefined(bottomRect);
const rect = spatial_1.Rect.merge([topRect, bottomRect]);
ctx.save();
const fontSize = this.style?.fontSize ?? this.config.DEFAULT_GAP_OVERLAY_FONT_SIZE;
const fontFamily = this.style?.fontFamily ?? this.config.DEFAULT_GAP_OVERLAY_FONT_FAMILY;
const fontColor = this.style?.fontColor ?? this.config.DEFAULT_GAP_OVERLAY_FONT_COLOR;
this.drawRect(rect);
// Draw the label in the center of the overlay.
if (this.label) {
const textMeasurer = new textmeasurer_1.TextMeasurer({
size: fontSize,
family: fontFamily,
});
const measurement = textMeasurer.measure(this.label);
const x = rect.center().x - measurement.width / 2;
const y = rect.center().y + measurement.approximateHeight / 2;
const position = new spatial_1.Point(x, y);
label_1.Label.singleLine(this.config, this.log, this.label, position, {}, { size: fontSize, family: fontFamily, color: fontColor })
.setContext(ctx)
.draw();
}
ctx.restore();
return this;
}
drawRect(rect) {
const ctx = this.ctx;
util.assertNotNull(ctx);
ctx.save();
const fill = this.style?.fill ?? this.config.DEFAULT_GAP_OVERLAY_FILL_COLOR;
ctx.setFillStyle(fill);
ctx.fillRect(rect.x, rect.y, rect.w, rect.h);
ctx.restore();
}
}
exports.GapOverlay = GapOverlay;