Bump V3.0.22 (#110)
* change simulator svg * change radio image * Remove google fonts cdn * change color of 'advanced' button * font fix * font fix 2 * display fix * change fullsceen simulator bg * Continuous servo * handle continuous state * adding shims * update rendering for continuous servos * fixing sim * fix sig * typo * fix sim * bump pxt * bump pxt * rerun travis * Input blocks revision - add Button and Pin event types - merge onPinPressed & onPinReleased in new onPinEvent function - create new onButtonEvent function * update input blocks in docs and tests * remove device_pin_release block * Hide DAL.x behind Enum * bring back deprecated blocks, but hide them * shims and locales files * fix input.input. typing * remove buildpr * bump V3 * update simulator aspect ratio * add Loudness Block * revoke loudness block * Adds soundLevel To be replaced by pxt-common-packages when DAL is updated. * Remove P0 & P3 from AnalogPin Co-authored-by: Juri <gitkraken@juriwolf.de>
This commit is contained in:
		@@ -3,8 +3,7 @@ namespace pxsim.visuals {
 | 
			
		||||
        return new visuals.MicrobitBoardSvg({
 | 
			
		||||
            runtime: runtime,
 | 
			
		||||
            theme: visuals.randomTheme(),
 | 
			
		||||
            disableTilt: false,
 | 
			
		||||
            wireframe: opts.wireframe,
 | 
			
		||||
            wireframe: opts.wireframe
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@@ -140,9 +140,31 @@ namespace pxsim.visuals {
 | 
			
		||||
            stroke: none;
 | 
			
		||||
            fill: #777;
 | 
			
		||||
        }
 | 
			
		||||
        .sim-label, .sim-button-label {
 | 
			
		||||
            fill: #000;
 | 
			
		||||
        }
 | 
			
		||||
        .sim-wireframe .sim-board {
 | 
			
		||||
            stroke-width: 2px;
 | 
			
		||||
        }
 | 
			
		||||
        *:focus {
 | 
			
		||||
            outline: none;
 | 
			
		||||
        }
 | 
			
		||||
        *:focus .sim-button-outer,
 | 
			
		||||
        .sim-pin:focus,
 | 
			
		||||
        .sim-thermometer:focus,
 | 
			
		||||
        .sim-shake:focus,
 | 
			
		||||
        .sim-light-level-button:focus {
 | 
			
		||||
            stroke: #4D90FE;
 | 
			
		||||
            stroke-width: 5px !important;
 | 
			
		||||
        }
 | 
			
		||||
        .no-drag, .sim-text, .sim-text-pin {
 | 
			
		||||
            user-drag: none;
 | 
			
		||||
            user-select: none;
 | 
			
		||||
            -moz-user-select: none;
 | 
			
		||||
            -webkit-user-drag: none;
 | 
			
		||||
            -webkit-user-select: none;
 | 
			
		||||
            -ms-user-select: none;
 | 
			
		||||
        }
 | 
			
		||||
    `;
 | 
			
		||||
    const BOARD_SVG = `<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
    <svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
 | 
			
		||||
@@ -692,8 +714,8 @@ namespace pxsim.visuals {
 | 
			
		||||
    export interface IBoardProps {
 | 
			
		||||
        runtime?: pxsim.Runtime;
 | 
			
		||||
        theme?: IBoardTheme;
 | 
			
		||||
        disableTilt?: boolean;
 | 
			
		||||
        wireframe?: boolean;
 | 
			
		||||
        disableTilt?: boolean;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export class MicrobitBoardSvg implements BoardView {
 | 
			
		||||
@@ -711,6 +733,7 @@ namespace pxsim.visuals {
 | 
			
		||||
        private leds: SVGElement[];
 | 
			
		||||
        private systemLed: SVGCircleElement;
 | 
			
		||||
        private antenna: SVGPolylineElement;
 | 
			
		||||
        private rssi: SVGTextElement;
 | 
			
		||||
        private lightLevelButton: SVGCircleElement;
 | 
			
		||||
        private lightLevelGradient: SVGLinearGradientElement;
 | 
			
		||||
        private lightLevelText: SVGTextElement;
 | 
			
		||||
@@ -925,6 +948,7 @@ namespace pxsim.visuals {
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
        constructor(public props: IBoardProps) {
 | 
			
		||||
            
 | 
			
		||||
            this.buildDom();
 | 
			
		||||
            if (props && props.wireframe)
 | 
			
		||||
                U.addClass(this.element, "sim-wireframe");
 | 
			
		||||
@@ -968,7 +992,6 @@ namespace pxsim.visuals {
 | 
			
		||||
				const r = p.getBoundingClientRect();
 | 
			
		||||
                this.pinNmToCoord[nm] = [r.left + r.width / 2, r.top + r.height / 2];
 | 
			
		||||
            });
 | 
			
		||||
			console.log(JSON.stringify(this.pinNmToCoord, null, 2))
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private updateTheme() {
 | 
			
		||||
@@ -981,6 +1004,7 @@ namespace pxsim.visuals {
 | 
			
		||||
            svg.fill(this.buttons[1], theme.buttonUps[1]);
 | 
			
		||||
            svg.fill(this.buttonsOuter[2], theme.virtualButtonOuter);
 | 
			
		||||
            svg.fill(this.buttons[2], theme.virtualButtonUp);
 | 
			
		||||
            if (this.shakeButton) svg.fill(this.shakeButton, theme.virtualButtonUp);
 | 
			
		||||
 | 
			
		||||
            this.pinGradients.forEach(lg => svg.setGradientColors(lg, theme.pin, theme.pinActive));
 | 
			
		||||
            svg.setGradientColors(this.lightLevelGradient, theme.lightLevelOn, theme.lightLevelOff);
 | 
			
		||||
@@ -1031,6 +1055,7 @@ namespace pxsim.visuals {
 | 
			
		||||
            this.updateGestures();
 | 
			
		||||
            this.updateRgbLed();
 | 
			
		||||
			this.updateSpeaker();
 | 
			
		||||
            this.updateRSSI();
 | 
			
		||||
 | 
			
		||||
            if (!runtime || runtime.dead) U.addClass(this.element, "grayscale");
 | 
			
		||||
            else U.removeClass(this.element, "grayscale");
 | 
			
		||||
@@ -1092,6 +1117,33 @@ namespace pxsim.visuals {
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private updateRSSI() {
 | 
			
		||||
            let state = this.board;
 | 
			
		||||
            if (!state) return;
 | 
			
		||||
            const v = state.radioState.datagram.rssi;
 | 
			
		||||
            if (v === undefined) return;
 | 
			
		||||
 | 
			
		||||
            if (!this.rssi) {
 | 
			
		||||
                let ax = 380;
 | 
			
		||||
                let dax = 18;
 | 
			
		||||
                let ayt = 10;
 | 
			
		||||
                let ayb = 40;
 | 
			
		||||
                const wh = dax * 5;
 | 
			
		||||
                for (let i = 0; i < 4; ++i)
 | 
			
		||||
                    svg.child(this.g, "rect", { x: ax - 90 + i * 6, y: ayt + 28 - i * 4, width: 4, height: 2 + i * 4, fill: "#fff" })
 | 
			
		||||
                this.rssi = svg.child(this.g, "text", { x: ax - 64, y: ayb, class: "sim-text" }) as SVGTextElement;
 | 
			
		||||
                this.rssi.textContent = "";
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            const vt = v.toString();
 | 
			
		||||
            if (vt !== this.rssi.textContent) {
 | 
			
		||||
                this.rssi.textContent = v.toString();
 | 
			
		||||
                this.antenna.setAttribute("aria-valuenow", this.rssi.textContent);
 | 
			
		||||
                accessibility.setLiveContent(this.rssi.textContent);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private updatePin(pin: Pin, index: number) {
 | 
			
		||||
            if (!pin) return;
 | 
			
		||||
            let text = this.pinTexts[pin.id];
 | 
			
		||||
@@ -1106,12 +1158,22 @@ namespace pxsim.visuals {
 | 
			
		||||
            }
 | 
			
		||||
            else if (pin.mode & PinFlags.Touch) {
 | 
			
		||||
                v = pin.touched ? "0%" : "100%";
 | 
			
		||||
                if (text) text.textContent = "TOUCHED";
 | 
			
		||||
                if (text) text.textContent = "";
 | 
			
		||||
            } else {
 | 
			
		||||
                v = "100%";
 | 
			
		||||
                if (text) text.textContent = "unused";
 | 
			
		||||
                if (text) text.textContent = "";
 | 
			
		||||
            }
 | 
			
		||||
            if (v) svg.setGradientValue(this.pinGradients[index], v);
 | 
			
		||||
 | 
			
		||||
            if (pin.mode !== PinFlags.Unused) {
 | 
			
		||||
                accessibility.makeFocusable(this.pins[index]);
 | 
			
		||||
                accessibility.setAria(this.pins[index], "slider", this.pins[index].firstChild.textContent);
 | 
			
		||||
                this.pins[index].setAttribute("aria-valuemin", "0");
 | 
			
		||||
                this.pins[index].setAttribute("aria-valuemax", pin.mode & PinFlags.Analog ? "1023" : "100");
 | 
			
		||||
                this.pins[index].setAttribute("aria-orientation", "vertical");
 | 
			
		||||
                this.pins[index].setAttribute("aria-valuenow", text ? text.textContent : v);
 | 
			
		||||
                accessibility.setLiveContent(text ? text.textContent : v);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private updateTemperature() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,242 +0,0 @@
 | 
			
		||||
/// <reference path="../../node_modules/pxt-core/built/pxtsim.d.ts"/>
 | 
			
		||||
/// <reference path="../../libs/core/dal.d.ts"/>
 | 
			
		||||
/// <reference path="../../libs/core/enums.d.ts"/>
 | 
			
		||||
 | 
			
		||||
namespace pxsim.visuals {
 | 
			
		||||
    const PIXEL_SPACING = PIN_DIST * 3;
 | 
			
		||||
    const PIXEL_RADIUS = PIN_DIST;
 | 
			
		||||
    const CANVAS_WIDTH = 1.2 * PIN_DIST;
 | 
			
		||||
    const CANVAS_HEIGHT = 12 * PIN_DIST;
 | 
			
		||||
    const CANVAS_VIEW_WIDTH = CANVAS_WIDTH;
 | 
			
		||||
    const CANVAS_VIEW_HEIGHT = CANVAS_HEIGHT;
 | 
			
		||||
    const CANVAS_VIEW_PADDING = PIN_DIST * 4;
 | 
			
		||||
    const CANVAS_LEFT = 1.4 * PIN_DIST;
 | 
			
		||||
    const CANVAS_TOP = PIN_DIST;
 | 
			
		||||
 | 
			
		||||
    // For the instructions parts list
 | 
			
		||||
    export function mkNeoPixelPart(xy: Coord = [0, 0]): SVGElAndSize {
 | 
			
		||||
        const NP_PART_XOFF = -13.5;
 | 
			
		||||
        const NP_PART_YOFF = -11;
 | 
			
		||||
        const NP_PART_WIDTH = 87.5;
 | 
			
		||||
        const NP_PART_HEIGHT = 190;
 | 
			
		||||
        const NEOPIXEL_PART_IMG = `<svg viewBox="-5 -1 53 112" xmlns="http://www.w3.org/2000/svg" xmlns:bx="https://boxy-svg.com">
 | 
			
		||||
  <rect x="2.5" width="38" height="100" style="fill: rgb(68, 68, 68);"/>
 | 
			
		||||
  <rect x="11.748" y="3.2" width="1.391" height="2.553" style="fill: none; stroke-linejoin: round; stroke-width: 3; stroke: rgb(165, 103, 52);"/>
 | 
			
		||||
  <rect x="20.75" y="3.2" width="1.391" height="2.553" style="fill: none; stroke-linejoin: round; stroke-width: 3; stroke: rgb(165, 103, 52);"/>
 | 
			
		||||
  <rect x="29.75" y="3.2" width="1.391" height="2.553" style="fill: none; stroke-linejoin: round; stroke-width: 3; stroke: rgb(165, 103, 52);"/>
 | 
			
		||||
  <g>
 | 
			
		||||
    <rect x="9" y="16.562" width="25" height="3.238" style="fill: rgb(216, 216, 216);"/>
 | 
			
		||||
    <rect x="9" y="22.562" width="25" height="3.238" style="fill: rgb(216, 216, 216);"/>
 | 
			
		||||
    <rect x="9" y="28.563" width="25" height="3.238" style="fill: rgb(216, 216, 216);"/>
 | 
			
		||||
    <rect x="11.607" y="14.833" width="19.787" height="18.697" style="fill: rgb(0, 0, 0);"/>
 | 
			
		||||
    <ellipse style="fill: rgb(216, 216, 216);" cx="21.5" cy="24.181" rx="7" ry="7"/>
 | 
			
		||||
  </g>
 | 
			
		||||
  <path d="M -7.25 -103.2 L -2.5 -100.003 L -12 -100.003 L -7.25 -103.2 Z" style="fill: rgb(68, 68, 68);" transform="matrix(-1, 0, 0, -1, 0, 0)" bx:shape="triangle -12 -103.2 9.5 3.197 0.5 0 1@ad6f5cac"/>
 | 
			
		||||
  <path d="M -16.75 -103.197 L -12 -100 L -21.5 -100 L -16.75 -103.197 Z" style="fill: rgb(68, 68, 68);" transform="matrix(-1, 0, 0, -1, 0, 0)" bx:shape="triangle -21.5 -103.197 9.5 3.197 0.5 0 1@07d73149"/>
 | 
			
		||||
  <path d="M -26.25 -103.2 L -21.5 -100.003 L -31 -100.003 L -26.25 -103.2 Z" style="fill: rgb(68, 68, 68);" transform="matrix(-1, 0, 0, -1, 0, 0)" bx:shape="triangle -31 -103.2 9.5 3.197 0.5 0 1@54403e2d"/>
 | 
			
		||||
  <path d="M -35.75 -103.197 L -31 -100 L -40.5 -100 L -35.75 -103.197 Z" style="fill: rgb(68, 68, 68);" transform="matrix(-1, 0, 0, -1, 0, 0)" bx:shape="triangle -40.5 -103.197 9.5 3.197 0.5 0 1@21c9b772"/>
 | 
			
		||||
  <g transform="matrix(1, 0, 0, 1, 0.000002, 29.999994)">
 | 
			
		||||
    <rect x="9" y="16.562" width="25" height="3.238" style="fill: rgb(216, 216, 216);"/>
 | 
			
		||||
    <rect x="9" y="22.562" width="25" height="3.238" style="fill: rgb(216, 216, 216);"/>
 | 
			
		||||
    <rect x="9" y="28.563" width="25" height="3.238" style="fill: rgb(216, 216, 216);"/>
 | 
			
		||||
    <rect x="11.607" y="14.833" width="19.787" height="18.697" style="fill: rgb(0, 0, 0);"/>
 | 
			
		||||
    <ellipse style="fill: rgb(216, 216, 216);" cx="21.5" cy="24.181" rx="7" ry="7"/>
 | 
			
		||||
  </g>
 | 
			
		||||
  <g transform="matrix(1, 0, 0, 1, 0.000005, 59.999992)">
 | 
			
		||||
    <rect x="9" y="16.562" width="25" height="3.238" style="fill: rgb(216, 216, 216);"/>
 | 
			
		||||
    <rect x="9" y="22.562" width="25" height="3.238" style="fill: rgb(216, 216, 216);"/>
 | 
			
		||||
    <rect x="9" y="28.563" width="25" height="3.238" style="fill: rgb(216, 216, 216);"/>
 | 
			
		||||
    <rect x="11.607" y="14.833" width="19.787" height="18.697" style="fill: rgb(0, 0, 0);"/>
 | 
			
		||||
    <ellipse style="fill: rgb(216, 216, 216);" cx="21.5" cy="24.181" rx="7" ry="7"/>
 | 
			
		||||
  </g>
 | 
			
		||||
</svg>`;
 | 
			
		||||
        let [x, y] = xy;
 | 
			
		||||
        let l = x + NP_PART_XOFF;
 | 
			
		||||
        let t = y + NP_PART_YOFF;
 | 
			
		||||
        let w = NP_PART_WIDTH;
 | 
			
		||||
        let h = NP_PART_HEIGHT;
 | 
			
		||||
        let img = <SVGImageElement>svg.elt("image");
 | 
			
		||||
        svg.hydrate(img, {
 | 
			
		||||
            class: "sim-neopixel-strip", x: l, y: t, width: w, height: h,
 | 
			
		||||
            href: svg.toDataUri(NEOPIXEL_PART_IMG)
 | 
			
		||||
        });
 | 
			
		||||
        return { el: img, x: l, y: t, w: w, h: h };
 | 
			
		||||
    }
 | 
			
		||||
    export class NeoPixel {
 | 
			
		||||
        public el: SVGElement;
 | 
			
		||||
        public cy: number;
 | 
			
		||||
 | 
			
		||||
        constructor(xy: Coord = [0, 0]) {
 | 
			
		||||
            let el = <SVGElement>svg.elt("rect");
 | 
			
		||||
            let r = PIXEL_RADIUS;
 | 
			
		||||
            let [cx, cy] = xy;
 | 
			
		||||
            let y = cy - r;
 | 
			
		||||
            svg.hydrate(el, { x: "-50%", y: y, width: "100%", height: r * 2, class: "sim-neopixel" });
 | 
			
		||||
            this.el = el;
 | 
			
		||||
            this.cy = cy;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public setRgb(rgb: [number, number, number]) {
 | 
			
		||||
            let hsl = visuals.rgbToHsl(rgb);
 | 
			
		||||
            let [h, s, l] = hsl;
 | 
			
		||||
            // at least 70% luminosity
 | 
			
		||||
            l = Math.max(l, 60);
 | 
			
		||||
            let fill = `hsl(${h}, ${s}%, ${l}%)`;
 | 
			
		||||
            this.el.setAttribute("fill", fill);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export class NeoPixelCanvas {
 | 
			
		||||
        public canvas: SVGSVGElement;
 | 
			
		||||
        public pin: number;
 | 
			
		||||
        public pixels: NeoPixel[];
 | 
			
		||||
        private viewBox: [number, number, number, number];
 | 
			
		||||
        private background: SVGRectElement;
 | 
			
		||||
 | 
			
		||||
        constructor(pin: number) {
 | 
			
		||||
            this.pixels = [];
 | 
			
		||||
            this.pin = pin;
 | 
			
		||||
            let el = <SVGSVGElement>svg.elt("svg");
 | 
			
		||||
            svg.hydrate(el, {
 | 
			
		||||
                "class": `sim-neopixel-canvas`,
 | 
			
		||||
                "x": "0px",
 | 
			
		||||
                "y": "0px",
 | 
			
		||||
                "width": `${CANVAS_WIDTH}px`,
 | 
			
		||||
                "height": `${CANVAS_HEIGHT}px`,
 | 
			
		||||
            });
 | 
			
		||||
            this.canvas = el;
 | 
			
		||||
            this.background = <SVGRectElement>svg.child(el, "rect", { class: "sim-neopixel-background hidden" });
 | 
			
		||||
            this.updateViewBox(-CANVAS_VIEW_WIDTH / 2, 0, CANVAS_VIEW_WIDTH, CANVAS_VIEW_HEIGHT);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private updateViewBox(x: number, y: number, w: number, h: number) {
 | 
			
		||||
            this.viewBox = [x, y, w, h];
 | 
			
		||||
            svg.hydrate(this.canvas, { "viewBox": `${x} ${y} ${w} ${h}` });
 | 
			
		||||
            svg.hydrate(this.background, { "x": x, "y": y, "width": w, "height": h });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public update(colors: RGBW[]) {
 | 
			
		||||
            if (!colors || colors.length <= 0)
 | 
			
		||||
                return;
 | 
			
		||||
 | 
			
		||||
            for (let i = 0; i < colors.length; i++) {
 | 
			
		||||
                let pixel = this.pixels[i];
 | 
			
		||||
                if (!pixel) {
 | 
			
		||||
                    let cxy: Coord = [0, CANVAS_VIEW_PADDING + i * PIXEL_SPACING];
 | 
			
		||||
                    pixel = this.pixels[i] = new NeoPixel(cxy);
 | 
			
		||||
                    svg.hydrate(pixel.el, { title: `offset: ${i}` });
 | 
			
		||||
                    this.canvas.appendChild(pixel.el);
 | 
			
		||||
                }
 | 
			
		||||
                let color = colors[i];
 | 
			
		||||
                pixel.setRgb([color[0], color[1], color[2]]);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //show the canvas if it's hidden
 | 
			
		||||
            U.removeClass(this.background, "hidden");
 | 
			
		||||
 | 
			
		||||
            //resize if necessary
 | 
			
		||||
            let [first, last] = [this.pixels[0], this.pixels[this.pixels.length - 1]]
 | 
			
		||||
            let yDiff = last.cy - first.cy;
 | 
			
		||||
            let newH = yDiff + CANVAS_VIEW_PADDING * 2;
 | 
			
		||||
            let [oldX, oldY, oldW, oldH] = this.viewBox;
 | 
			
		||||
            if (oldH < newH) {
 | 
			
		||||
                let scalar = newH / oldH;
 | 
			
		||||
                let newW = oldW * scalar;
 | 
			
		||||
                this.updateViewBox(-newW / 2, oldY, newW, newH);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public setLoc(xy: Coord) {
 | 
			
		||||
            let [x, y] = xy;
 | 
			
		||||
            svg.hydrate(this.canvas, { x: x, y: y });
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    function digitalPinToPinNumber(gpioPin: string): number {
 | 
			
		||||
        const MICROBIT_ID_IO_P0 = 7; //TODO: don't hardcode this, import enums.d.ts
 | 
			
		||||
        if (gpioPin == "*") {
 | 
			
		||||
            return MICROBIT_ID_IO_P0;
 | 
			
		||||
        }
 | 
			
		||||
        let pinSplit = gpioPin.split("DigitalPin.P");
 | 
			
		||||
        U.assert(pinSplit.length === 2, "Unknown format for pin (for NeoPixel): " + gpioPin);
 | 
			
		||||
        let pinNumStr = pinSplit[1];
 | 
			
		||||
        let pinNum = Number(pinNumStr) + MICROBIT_ID_IO_P0;
 | 
			
		||||
        return pinNum
 | 
			
		||||
    }
 | 
			
		||||
    function parseNeoPixelMode(modeStr: string): NeoPixelMode {
 | 
			
		||||
        const modeMap: Map<NeoPixelMode> = {
 | 
			
		||||
            "NeoPixelMode.RGB": NeoPixelMode.RGB,
 | 
			
		||||
            "NeoPixelMode.RGBW": NeoPixelMode.RGBW
 | 
			
		||||
        };
 | 
			
		||||
        return modeMap[modeStr] || NeoPixelMode.RGB;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export class NeoPixelView implements IBoardPart<NeoPixelState> {
 | 
			
		||||
        public style: string = `
 | 
			
		||||
            .sim-neopixel-canvas {
 | 
			
		||||
            }
 | 
			
		||||
            .sim-neopixel-canvas-parent:hover {
 | 
			
		||||
                transform-origin: center;
 | 
			
		||||
                transform: scale(4) translateY(-60px);
 | 
			
		||||
                -moz-transform: scale(4) translateY(-220px);
 | 
			
		||||
            }
 | 
			
		||||
            .sim-neopixel-canvas .hidden {
 | 
			
		||||
                visibility:hidden;
 | 
			
		||||
            }
 | 
			
		||||
            .sim-neopixel-background {
 | 
			
		||||
                fill: rgba(255,255,255,0.9);
 | 
			
		||||
            }
 | 
			
		||||
            .sim-neopixel-strip {
 | 
			
		||||
            }
 | 
			
		||||
        `;
 | 
			
		||||
        public element: SVGElement;
 | 
			
		||||
        public overElement: SVGElement;
 | 
			
		||||
        public defs: SVGElement[];
 | 
			
		||||
        private state: NeoPixelState;
 | 
			
		||||
        private canvas: NeoPixelCanvas;
 | 
			
		||||
        private part: SVGElAndSize;
 | 
			
		||||
        private stripGroup: SVGGElement;
 | 
			
		||||
        private lastLocation: Coord;
 | 
			
		||||
        private pin: number;
 | 
			
		||||
        private mode: NeoPixelMode;
 | 
			
		||||
 | 
			
		||||
        public init(bus: EventBus, state: NeoPixelState, svgEl: SVGSVGElement, otherParams: Map<string>): void {
 | 
			
		||||
            U.assert(!!otherParams["mode"], "NeoPixels assumes a RGB vs RGBW mode is passed to it");
 | 
			
		||||
            U.assert(!!otherParams["pin"], "NeoPixels assumes a pin is passed to it");
 | 
			
		||||
            let modeStr = otherParams["mode"];
 | 
			
		||||
            this.mode = parseNeoPixelMode(modeStr);
 | 
			
		||||
            this.state = state;
 | 
			
		||||
            this.stripGroup = <SVGGElement>svg.elt("g");
 | 
			
		||||
            this.element = this.stripGroup;
 | 
			
		||||
            let pinStr = otherParams["pin"];
 | 
			
		||||
            this.pin = digitalPinToPinNumber(pinStr);
 | 
			
		||||
            this.lastLocation = [0, 0];
 | 
			
		||||
            let part = mkNeoPixelPart();
 | 
			
		||||
            this.part = part;
 | 
			
		||||
            this.stripGroup.appendChild(part.el);
 | 
			
		||||
            let canvas = new NeoPixelCanvas(this.pin);
 | 
			
		||||
            this.canvas = canvas;
 | 
			
		||||
            let canvasG = svg.elt("g", { class: "sim-neopixel-canvas-parent" });
 | 
			
		||||
            this.overElement = canvasG;
 | 
			
		||||
            canvasG.appendChild(canvas.canvas);
 | 
			
		||||
            this.updateStripLoc();
 | 
			
		||||
        }
 | 
			
		||||
        public moveToCoord(xy: Coord): void {
 | 
			
		||||
            let [x, y] = xy;
 | 
			
		||||
            let loc: Coord = [x, y];
 | 
			
		||||
            this.lastLocation = loc;
 | 
			
		||||
            this.updateStripLoc();
 | 
			
		||||
        }
 | 
			
		||||
        private updateStripLoc() {
 | 
			
		||||
            let [x, y] = this.lastLocation;
 | 
			
		||||
            U.assert(typeof x === "number" && typeof y === "number", "invalid x,y for NeoPixel strip");
 | 
			
		||||
            this.canvas.setLoc([x + CANVAS_LEFT, y + CANVAS_TOP]);
 | 
			
		||||
            svg.hydrate(this.part.el, { transform: `translate(${x} ${y})` }); //TODO: update part's l,h, etc.
 | 
			
		||||
        }
 | 
			
		||||
        public updateState(): void {
 | 
			
		||||
            let colors = this.state.getColors(this.pin, this.mode);
 | 
			
		||||
            this.canvas.update(colors);
 | 
			
		||||
        }
 | 
			
		||||
        public updateTheme(): void { }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user