namespace pxsim.visuals { type SVGStylable = any; const LED_PART_XOFF = -8; const LED_PART_YOFF = -7; const LED_PART_WIDTH = 68; const LED_PART_HEIGHT = 180; const LED_PART = ` 330Ω `; // For the intructions export function mkLedPart(xy: Coord = [0, 0]): SVGElAndSize { let [x, y] = xy; let l = x + LED_PART_XOFF; let t = y + LED_PART_YOFF; let w = LED_PART_WIDTH; let h = LED_PART_HEIGHT; let img = svg.elt("image"); svg.hydrate(img, { class: "sim-led", x: l, y: t, width: w, height: h, href: svg.toDataUri(LED_PART) }); return { el: img, x: l, y: t, w: w, h: h }; } export class LedView implements IBoardPart { element: SVGElement; defs: SVGElement[]; private led: SVGPathElement; private text: SVGTSpanElement; private parsePinString: (s: string) => Pin; private color: string = "rgb(0,255,0)"; // green color by default private part: SVGElAndSize; private bus: EventBus; public style: string; private state: ToggleState; private pin: Pin; private currentValue: number; private currentMode: PinFlags; constructor(parsePinString: (s: string) => Pin) { this.parsePinString = parsePinString; } public init(bus: EventBus, state: EdgeConnectorState, svgEl: SVGSVGElement, otherParams: Map): void { this.pin = this.parsePinString(otherParams["name"] || otherParams["pin"]); this.bus = bus; this.initDom(); this.updateState(); } initDom() { this.element = svg.elt("g"); const image = new DOMParser().parseFromString(LED_PART, "image/svg+xml").querySelector("svg") as SVGSVGElement; svg.hydrate(image, { class: "sim-led", width: LED_PART_WIDTH, height: LED_PART_HEIGHT, }); this.led = image.getElementById('LED') as SVGPathElement; this.text = image.getElementById('tspan4522') as SVGTSpanElement; this.element.appendChild(image); } public moveToCoord(xy: Coord) { translateEl(this.element, [xy[0] + LED_PART_XOFF, xy[1] + LED_PART_YOFF]); } public updateTheme() { } public updateState() { if (this.currentValue === this.pin.value && this.currentMode == this.pin.mode) return; this.currentValue = this.pin.value; this.currentMode = this.pin.mode; const style = (this.led).style; if (this.currentMode & PinFlags.Digital) { style.fill = this.currentValue ? "#00ff00" : "#ffffff"; style.opacity = "0.9"; this.text.textContent = this.currentValue ? "1" : "0"; } else { style.fill = "#00ff00"; style.opacity = (0.1 + Math.max(0, Math.min(1023, this.currentValue)) / 1023 * 0.8).toString(); this.text.textContent = `~${this.currentValue}` } } } }