UNPKG

vexflow

Version:

A JavaScript library for rendering music notation and guitar tablature

116 lines (99 loc) 3.29 kB
// [VexFlow](http://vexflow.com) - Copyright (c) Mohit Muthanna 2010. // @author Mohit Cheppudira // // ## Description // // This file implements a generic base class for VexFlow, with implementations // of general functions and properties that can be inherited by all VexFlow elements. import { Vex } from './vex'; import { Registry } from './registry'; export class Element { static newID() { return 'auto' + (Element.ID++); } constructor({ type } = {}) { this.attrs = { id: Element.newID(), el: null, type: type || 'Base', classes: {}, }; this.boundingBox = null; this.context = null; this.rendered = false; // If a default registry exist, then register with it right away. if (Registry.getDefaultRegistry()) { Registry.getDefaultRegistry().register(this); } } // set the draw style of a stemmable note: setStyle(style) { this.style = style; return this; } getStyle() { return this.style; } // Apply current style to Canvas `context` applyStyle(context = this.context, style = this.getStyle()) { if (!style) return this; context.save(); if (style.shadowColor) context.setShadowColor(style.shadowColor); if (style.shadowBlur) context.setShadowBlur(style.shadowBlur); if (style.fillStyle) context.setFillStyle(style.fillStyle); if (style.strokeStyle) context.setStrokeStyle(style.strokeStyle); if (style.lineWidth) context.setLineWidth(style.lineWidth); return this; } restoreStyle(context = this.context, style = this.getStyle()) { if (!style) return this; context.restore(); return this; } // An element can have multiple class labels. hasClass(className) { return (this.attrs.classes[className] === true); } addClass(className) { this.attrs.classes[className] = true; if (this.registry) { this.registry.onUpdate({ id: this.getAttribute('id'), name: 'class', value: className, oldValue: null, }); } return this; } removeClass(className) { delete this.attrs.classes[className]; if (this.registry) { this.registry.onUpdate({ id: this.getAttribute('id'), name: 'class', value: null, oldValue: className, }); } return this; } // This is called by the registry after the element is registered. onRegister(registry) { this.registry = registry; return this; } isRendered() { return this.rendered; } setRendered(rendered = true) { this.rendered = rendered; return this; } getAttributes() { return this.attrs; } getAttribute(name) { return this.attrs[name]; } setAttribute(name, value) { const id = this.attrs.id; const oldValue = this.attrs[name]; this.attrs[name] = value; if (this.registry) { // Register with old id to support id changes. this.registry.onUpdate({ id, name, value, oldValue }); } return this; } getContext() { return this.context; } setContext(context) { this.context = context; return this; } getBoundingBox() { return this.boundingBox; } // Validators checkContext() { if (!this.context) { throw new Vex.RERR('NoContext', 'No rendering context attached to instance'); } return this.context; } } Element.ID = 1000;