Skip to content

Commit

Permalink
Merge pull request #882 from rvilarl/migration/element
Browse files Browse the repository at this point in the history
Migration/element
  • Loading branch information
0xfe authored Apr 8, 2021
2 parents 825ec82 + a61490a commit 83a4794
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 33 deletions.
85 changes: 52 additions & 33 deletions src/element.js → src/element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,33 @@
import { Vex } from './vex';
import { Registry } from './registry';
import { Flow } from './tables';

export class Element {
static newID() {
return 'auto' + Element.ID++;
}

constructor({ type } = {}) {
import { BoundingBox } from './boundingbox';
import { Font } from './smufl';
import { RenderContext, ElementStyle, ElementAttributes } from './types/common';

export abstract class Element {
protected static ID: number = 1000;
protected context?: RenderContext;
protected rendered: boolean;
protected style?: ElementStyle;
private attrs: ElementAttributes;
protected boundingBox?: BoundingBox;
protected fontStack: Font[];
protected musicFont: Font;
protected registry?: Registry;

static newID(): string {
return `auto${Element.ID++}`;
}

constructor({ type }: { type?: string } = {}) {
this.attrs = {
id: Element.newID(),
el: null,
type: type || 'Base',
classes: {},
};

this.boundingBox = null;
this.context = null;
this.rendered = false;
this.fontStack = Flow.DEFAULT_FONT_STACK;
this.musicFont = Flow.DEFAULT_FONT_STACK[0];
Expand All @@ -36,27 +47,31 @@ export class Element {
}

// set music font
setFontStack(fontStack) {
setFontStack(fontStack: Font[]): this {
this.fontStack = fontStack;
this.musicFont = fontStack[0];
return this;
}
getFontStack() {
getFontStack(): Font[] {
return this.fontStack;
}

// set the draw style of a stemmable note:
setStyle(style) {
setStyle(style: ElementStyle): this {
this.style = style;
return this;
}
getStyle() {
getStyle(): ElementStyle | undefined {
return this.style;
}

// Apply current style to Canvas `context`
applyStyle(context = this.context, style = this.getStyle()) {
applyStyle(
context: RenderContext | undefined = this.context,
style: ElementStyle | undefined = this.getStyle()
): this {
if (!style) return this;
if (!context) return this;

context.save();
if (style.shadowColor) context.setShadowColor(style.shadowColor);
Expand All @@ -67,25 +82,31 @@ export class Element {
return this;
}

restoreStyle(context = this.context, style = this.getStyle()) {
restoreStyle(
context: RenderContext | undefined = this.context,
style: ElementStyle | undefined = this.getStyle()
): this {
if (!style) return this;
if (!context) return this;
context.restore();
return this;
}

// draw with style of an element.
drawWithStyle() {
// draw with style of an element. */
drawWithStyle(): void {
this.checkContext();
this.applyStyle();
this.draw();
this.restoreStyle();
}

abstract draw(element?: Element, x_shift?: number): void;

// An element can have multiple class labels.
hasClass(className) {
hasClass(className: string): boolean {
return this.attrs.classes[className] === true;
}
addClass(className) {
addClass(className: string): this {
this.attrs.classes[className] = true;
if (this.registry) {
this.registry.onUpdate({
Expand All @@ -98,7 +119,7 @@ export class Element {
return this;
}

removeClass(className) {
removeClass(className: string): this {
delete this.attrs.classes[className];
if (this.registry) {
this.registry.onUpdate({
Expand All @@ -112,26 +133,26 @@ export class Element {
}

// This is called by the registry after the element is registered.
onRegister(registry) {
onRegister(registry: Registry): this {
this.registry = registry;
return this;
}
isRendered() {
isRendered(): boolean {
return this.rendered;
}
setRendered(rendered = true) {
setRendered(rendered = true): this {
this.rendered = rendered;
return this;
}

getAttributes() {
getAttributes(): ElementAttributes {
return this.attrs;
}
getAttribute(name) {
getAttribute(name: string): string {
return this.attrs[name];
}
setAttribute(name, value) {
const id = this.attrs.id;
setAttribute(name: string, value: string): this {
const { id } = this.attrs;
const oldValue = this.attrs[name];
this.attrs[name] = value;
if (this.registry) {
Expand All @@ -141,24 +162,22 @@ export class Element {
return this;
}

getContext() {
getContext(): RenderContext | undefined {
return this.context;
}
setContext(context) {
setContext(context?: RenderContext): this {
this.context = context;
return this;
}
getBoundingBox() {
getBoundingBox(): BoundingBox | undefined {
return this.boundingBox;
}

// Validators
checkContext() {
checkContext(): RenderContext {
if (!this.context) {
throw new Vex.RERR('NoContext', 'No rendering context attached to instance');
}
return this.context;
}
}

Element.ID = 1000;
62 changes: 62 additions & 0 deletions src/types/common.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/** Element attributes. */
export interface ElementAttributes {
[name: string]: any;
id: string;
type: string;
classes: Record<string, boolean>;
}

/** Contexts common interface */
export interface RenderContext {
clear(): void;
setFont(family: string, size: number, weight?: string): RenderContext;
setRawFont(font: string): RenderContext;
setFillStyle(style: string): RenderContext;
setBackgroundFillStyle(style: string): RenderContext;
setStrokeStyle(style: string): RenderContext;
setShadowColor(color: string): RenderContext;
setShadowBlur(blur: string): RenderContext;
setLineWidth(width: number): RenderContext;
setLineCap(cap_type: string): RenderContext;
setLineDash(dash: string): RenderContext;
scale(x: number, y: number): RenderContext;
resize(width: number, height: number): RenderContext;
fillRect(x: number, y: number, width: number, height: number): RenderContext;
clearRect(x: number, y: number, width: number, height: number): RenderContext;
beginPath(): RenderContext;
moveTo(x: number, y: number): RenderContext;
lineTo(x: number, y: number): RenderContext;
bezierCurveTo(x1: number, y1: number, x2: number, y2: number, x: number, y: number): RenderContext;
quadraticCurveTo(x1: number, y1: number, x2: number, y2: number): RenderContext;
arc(
x: number,
y: number,
radius: number,
startAngle: number,
endAngle: number,
antiClockwise: boolean
): RenderContext;
glow(): RenderContext;
fill(): RenderContext;
stroke(): RenderContext;
closePath(): RenderContext;
fillText(text: string, x: number, y: number): RenderContext;
save(): RenderContext;
restore(): RenderContext;
openGroup(): Node | undefined;
closeGroup(): void;

/**
* canvas returns TextMetrics, SVG returns SVGRect, Raphael returns {width : number, height : number}. Only width is used throughout VexFlow.
*/
measureText(text: string): { width: number };
}

/** Element style */
export interface ElementStyle {
shadowColor?: string;
shadowBlur?: string;
fillStyle?: string;
strokeStyle?: string;
lineWidth?: number;
}
1 change: 1 addition & 0 deletions typedoc.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './src/element';
export * from './src/fraction';
export * from './src/music';
export * from './src/tuning';

0 comments on commit 83a4794

Please sign in to comment.