88 lines
2.2 KiB
JavaScript
88 lines
2.2 KiB
JavaScript
// A frameworking class assigning some CSS classes to the canvas to make it integrate nicer with CSS.
|
|
export class Frame extends HTMLCanvasElement {
|
|
static fontFace = "RecVar";
|
|
static monoFontFace = "RecVarMono";
|
|
|
|
constructor() {
|
|
super();
|
|
}
|
|
|
|
async connectedCallback() {
|
|
this.style.cssText = `
|
|
margin-top: 8px;
|
|
margin-bottom: 4px;
|
|
border-radius: 4px;
|
|
max-width: 100%;
|
|
`;
|
|
|
|
this.ctx = this.getContext("2d");
|
|
|
|
requestAnimationFrame(this.#drawLoop.bind(this));
|
|
}
|
|
|
|
#drawLoop() {
|
|
this.ctx.font = "14px RecVar";
|
|
this.draw();
|
|
requestAnimationFrame(this.#drawLoop.bind(this));
|
|
}
|
|
|
|
// Override this!
|
|
draw() {
|
|
throw new ReferenceError("draw() must be overridden");
|
|
}
|
|
|
|
getTextPositionInBox(text, x, y, width, height, hAlign, vAlign) {
|
|
let measurements = this.ctx.measureText(text);
|
|
|
|
let leftX;
|
|
switch (hAlign) {
|
|
case "left":
|
|
leftX = x;
|
|
break;
|
|
case "center":
|
|
leftX = x + width / 2 - measurements.width / 2;
|
|
break;
|
|
case "right":
|
|
leftX = x + width - measurements.width;
|
|
break;
|
|
}
|
|
|
|
let textHeight = measurements.fontBoundingBoxAscent;
|
|
let baselineY;
|
|
switch (vAlign) {
|
|
case "top":
|
|
baselineY = y + textHeight;
|
|
break;
|
|
case "center":
|
|
baselineY = y + height / 2 + textHeight / 2;
|
|
break;
|
|
case "bottom":
|
|
baselineY = y + height;
|
|
break;
|
|
}
|
|
|
|
return { leftX, baselineY };
|
|
}
|
|
|
|
get scaleInViewportX() {
|
|
return this.clientWidth / this.width;
|
|
}
|
|
|
|
get scaleInViewportY() {
|
|
return this.clientHeight / this.height;
|
|
}
|
|
|
|
getMousePositionFromEvent(event) {
|
|
return {
|
|
x: event.offsetX / this.scaleInViewportX,
|
|
y: event.offsetY / this.scaleInViewportY,
|
|
};
|
|
}
|
|
}
|
|
|
|
export function defineFrame(elementName, claß) { // because `class` is a keyword.
|
|
customElements.define(elementName, claß, { extends: "canvas" });
|
|
}
|
|
|
|
defineFrame("tairu--frame", Frame);
|