class Gauge extends HTMLElement { constructor(iconName, label, description) { super(); this.iconName = iconName; this.label = label; this.description = description; } connectedCallback() { this.role = "progressbar"; this.classList.add("icon", `icon-${this.iconName}`); this.full = this.appendChild(document.createElement("div")); this.full.classList.add("full", "icon", `icon-${this.iconName}-white`); this.normalizedValue = 0; this.updateVisibility(); } setValue(value, valueMax) { let clampedNormalized = Math.max(0, Math.min(1, value / valueMax)); this.normalizedValue = clampedNormalized; this.style.setProperty("--progress", `${clampedNormalized * 100}%`); this.title = `${this.label}: ${value} / ${valueMax} (${Math.ceil(clampedNormalized * 100)}%)\n${this.description}`; this.updateVisibility(); } updateVisibility() { this.visible = this.normalizedValue > 0.25; if (!this.visible) this.classList.add("hidden"); else this.classList.remove("hidden"); } } customElements.define("rkgk-brush-cost-gauge", Gauge); export class BrushCostGauges extends HTMLElement { constructor() { super(); } connectedCallback() { this.codeSizeGauge = this.appendChild( createGauge({ className: "code-size", iconName: "brackets", label: "Code size", description: "How large your code is.\n" + "The more syntactic elements there are, the bigger it gets!\n" + "Note that this is not the same as the character count.", }), ); this.fuelGauge = this.appendChild( createGauge({ className: "fuel", iconName: "droplet", label: "Fuel", description: "How long your code runs.\n" + "The longer it runs, the more fuel it consumes!\n" + "Remember that built-in functions are cheaper than ones you write yourself.", }), ); this.memoryGauge = this.appendChild( createGauge({ className: "memory", iconName: "memory", label: "Memory", description: "How much memory your code uses.\n" + "This includes a baseline amount of memory for temporary data.\n" + "Excessive list transformations can fill up your memory very quickly!", }), ); this.codeSizeGauge.setValue(0); this.fuelGauge.setValue(0); this.memoryGauge.setValue(0); } update(stats) { this.codeSizeGauge.setValue(stats.astSize, stats.astSizeMax); this.fuelGauge.setValue(stats.fuel, stats.fuelMax); this.memoryGauge.setValue(stats.memory, stats.memoryMax); let visible = this.codeSizeGauge.visible || this.fuelGauge.visible || this.memoryGauge.visible; if (!visible) this.classList.add("hidden"); else this.classList.remove("hidden"); } } customElements.define("rkgk-brush-cost-gauges", BrushCostGauges); function createGauge({ className, iconName, label, description }) { let gauge = new Gauge(iconName, label, description); gauge.classList.add(className); return gauge; }