@dartbot/segment
Version:
Segmented display implementd as a vanilla Web Component
145 lines • 6.21 kB
JavaScript
var _SevenSegment_canvas, _SevenSegment_style, _SevenSegment_shadow, _SevenSegment_format, _SevenSegment_mask;
import { __classPrivateFieldGet, __classPrivateFieldSet } from "tslib";
import { charMasks } from './render-segment/char-masks';
import { render } from './render-segment/render-segment';
import { createTheme, Token, tokenDefaults } from './render-segment/token';
import { debounce } from './utils';
export var SevenSegmentAttributes;
(function (SevenSegmentAttributes) {
SevenSegmentAttributes["Format"] = "format";
SevenSegmentAttributes["DisplayText"] = "displaytext";
})(SevenSegmentAttributes || (SevenSegmentAttributes = {}));
export class SevenSegment extends HTMLElement {
static get observedAttributes() {
return [SevenSegmentAttributes.Format, SevenSegmentAttributes.DisplayText];
}
get count() {
return __classPrivateFieldGet(this, _SevenSegment_format, "f").match(/#/g)?.length || 0;
}
constructor() {
super();
_SevenSegment_canvas.set(this, void 0);
_SevenSegment_style.set(this, void 0);
_SevenSegment_shadow.set(this, void 0);
_SevenSegment_format.set(this, void 0);
_SevenSegment_mask.set(this, []);
__classPrivateFieldSet(this, _SevenSegment_format, '#####', "f");
__classPrivateFieldSet(this, _SevenSegment_shadow, this.attachShadow({ mode: 'open' }), "f");
__classPrivateFieldGet(this, _SevenSegment_shadow, "f").innerHTML = `
<style>
:host {
display: flex;
width: 100%;
aspect-ratio: ${this.count} / 1.75;
box-sizing: border-box;
user-select: none;
background: var(${Token.segmentBackground}, ${tokenDefaults[Token.segmentBackground]});
}
canvas {
width: 100%;
height: 100%;
background: var(${Token.segmentBackground}, ${tokenDefaults[Token.segmentBackground]});
}
</style>
<canvas></canvas>
`;
__classPrivateFieldSet(this, _SevenSegment_canvas, __classPrivateFieldGet(this, _SevenSegment_shadow, "f").querySelector('canvas'), "f");
__classPrivateFieldSet(this, _SevenSegment_style, __classPrivateFieldGet(this, _SevenSegment_shadow, "f").querySelector('style'), "f");
const resizeObserver = new ResizeObserver(debounce((entries) => {
const entry = entries.find(e => e.target === this);
const box = entry.devicePixelContentBoxSize?.[0];
const boxC = entry.contentBoxSize[0];
const physical = (n) => Math.round(n * devicePixelRatio);
__classPrivateFieldGet(this, _SevenSegment_canvas, "f").width = box?.inlineSize ?? physical(boxC.inlineSize);
__classPrivateFieldGet(this, _SevenSegment_canvas, "f").height = box?.blockSize ?? physical(boxC.blockSize);
this.render();
}, SevenSegment.RESIZE_DEBOUNCE_MS, { leading: true, trailing: true }));
resizeObserver.observe(this, { box: 'content-box' });
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue === newValue) {
return;
}
switch (name) {
case SevenSegmentAttributes.Format:
__classPrivateFieldSet(this, _SevenSegment_format, String(newValue), "f");
__classPrivateFieldGet(this, _SevenSegment_style, "f").innerHTML = `
:host {
display: flex;
width: 100%;
aspect-ratio: ${this.count} / 1.75;
box-sizing: border-box;
user-select: none;
background: var(${Token.segmentBackground}, ${tokenDefaults[Token.segmentBackground]});
}
canvas {
width: 100%;
height: 100%;
background: var(${Token.segmentBackground}, ${tokenDefaults[Token.segmentBackground]});
}
`;
break;
case SevenSegmentAttributes.DisplayText:
this.setText(String(newValue));
break;
default:
break;
}
this.render();
}
render() {
const ctx = __classPrivateFieldGet(this, _SevenSegment_canvas, "f").getContext('2d');
if (ctx == null) {
return;
}
const style = getComputedStyle(this);
const theme = createTheme(style);
const props = { format: __classPrivateFieldGet(this, _SevenSegment_format, "f") };
render(theme, props, ctx, __classPrivateFieldGet(this, _SevenSegment_mask, "f"));
}
setMask(mask) {
__classPrivateFieldSet(this, _SevenSegment_mask, mask, "f");
this.render();
}
setText(val) {
const chars = Array.from(val);
const masks = chars.map(c => charMasks[c] ||
charMasks[c.toLocaleUpperCase()] ||
charMasks[c.toLocaleLowerCase()] ||
charMasks[' ']);
__classPrivateFieldSet(this, _SevenSegment_mask, masks, "f");
this.render();
}
setNumber(val) {
const v = String(val);
this.setText(v);
}
/**
* Return the image data encoded as a data URL.
* @param type The image format. Default is `image/png`.
* @param quality The image quality. Default is `1.0`.
*/
toDataURL(type, quality) {
return __classPrivateFieldGet(this, _SevenSegment_canvas, "f").toDataURL(type, quality);
}
/**
* Return the image data as a Blob.
* @param type The image format. Default is `image/png`.
* @param quality The image quality. Default is `1.0`.
*/
toBlob(type, quality) {
return new Promise(resolve => {
__classPrivateFieldGet(this, _SevenSegment_canvas, "f").toBlob(blob => {
resolve(blob);
}, type, quality);
});
}
}
_SevenSegment_canvas = new WeakMap(), _SevenSegment_style = new WeakMap(), _SevenSegment_shadow = new WeakMap(), _SevenSegment_format = new WeakMap(), _SevenSegment_mask = new WeakMap();
Object.defineProperty(SevenSegment, "RESIZE_DEBOUNCE_MS", {
enumerable: true,
configurable: true,
writable: true,
value: 100
});
//# sourceMappingURL=SevenSegment.js.map