@webwriter/geometry-cloze
Version:
Create and view geometry exercises with coloring, styling and labeling options.
107 lines (90 loc) • 2.58 kB
text/typescript
import { MathPoint } from '../../helper/Calc';
import Stylable, { StylableData } from './Stylable';
import Manager from '../../CanvasManager/Abstracts';
export interface DraggableData {
selected?: boolean;
}
export default class Draggable extends Stylable {
private _selected: boolean;
protected clickTargetSize = 0;
protected _x: number = 0;
protected _y: number = 0;
constructor(manager: Manager, data: DraggableData & StylableData = {}) {
super(manager, data);
this._selected = data.selected ?? false;
}
draw(ctx: CanvasRenderingContext2D) {
super.draw(ctx);
if (this.selected) {
ctx.lineWidth = this.lineWidth + 1;
ctx.shadowBlur = 5;
ctx.shadowColor = '#00000050';
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
}
}
public getHit(point: MathPoint, point2?: MathPoint): Draggable[] {
if (this.hidden) return [];
return this.children.flatMap((child) => {
if (child instanceof Draggable) return child.getHit(point, point2);
return [];
});
}
public move(coords: { x?: number; y?: number; relative: boolean }): void {
const change = coords.relative
? coords
: {
x: coords.x ? coords.x - this.x : 0,
y: coords.y ? coords.y - this.y : 0,
relative: true
};
this._x += change.x ?? 0;
this._y += change.y ?? 0;
this.children.forEach((child) => {
if (child instanceof Draggable) child.move(change);
});
this.fireEvent('move', this);
this.requestRedraw();
}
select() {
if (!this.onSelect()) return;
this._selected = true;
this.fireEvent('select', this);
this.requestRedraw();
}
/**
* Gets called when the element is selected
* @returns Whether the element should be selected
*/
protected onSelect(): boolean {
return true;
}
blur() {
if (!this.onBlur()) return;
this._selected = false;
this.fireEvent('blur', this);
this.requestRedraw();
}
/**
* Gets called when the element is unselected
* @returns Whether the element should be unselected
*/
protected onBlur(): boolean {
return true;
}
delete() {
super.delete();
this._selected = false;
this.removeEventListener('select', this.select.bind(this));
this.removeEventListener('unselect', this.blur.bind(this));
}
get selected() {
return this._selected;
}
get x() {
return this._x;
}
get y() {
return this._y;
}
}