Sim gif generation (#1877)

* enable simulator screenshot

* use viewhost screenshotAsync facility

* setup giftransparency

* tweak css for gif generation

* patch colors

* update theme

* specify custom gif color

* moving as experiement

* bump pxt
This commit is contained in:
Peli de Halleux 2019-02-27 15:04:03 -08:00 committed by GitHub
parent fea7634da7
commit 835e1b2e1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 23 additions and 14 deletions

BIN
docs/static/experiments/simgif.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

View File

@ -43,6 +43,6 @@
},
"dependencies": {
"pxt-common-packages": "6.4.5",
"pxt-core": "5.5.13"
"pxt-core": "5.5.15"
}
}

View File

@ -17,6 +17,7 @@
"workspace": false,
"packages": true,
"sharing": true,
"thumbnails": true,
"publishing": true,
"importing": true,
"preferredPackages": [
@ -282,7 +283,9 @@
"instructions",
"debugger",
"bluetoothUartConsole",
"bluetoothPartialFlashing"
"bluetoothPartialFlashing",
"simScreenshot",
"simGif"
],
"bluetoothUartFilters": [{
"namePrefix": "BBC micro:bit"
@ -440,6 +443,7 @@
"editorVersionPaths": {
"0": "v0"
},
"scriptManager": true
"scriptManager": true,
"simGifTransparent": "rgba(0,0,0,0)"
}
}

View File

@ -17,6 +17,7 @@ namespace pxsim {
fileSystem: FileSystemState;
// visual
viewHost: visuals.BoardHost;
view: SVGElement;
constructor() {
@ -119,8 +120,6 @@ namespace pxsim {
initAsync(msg: SimulatorRunMessage): Promise<void> {
super.initAsync(msg);
const options = (msg.options || {}) as RuntimeOptions;
const boardDef = msg.boardDefinition;
const cmpsList = msg.parts;
const cmpDefs = msg.partDefinitions || {};
@ -136,20 +135,20 @@ namespace pxsim {
maxHeight: "100%",
highContrast: msg.highContrast
};
const viewHost = new visuals.BoardHost(pxsim.visuals.mkBoardView({
this.viewHost = new visuals.BoardHost(pxsim.visuals.mkBoardView({
visual: boardDef.visual,
boardDef: boardDef,
highContrast: msg.highContrast
}), opts);
document.body.innerHTML = ""; // clear children
document.body.appendChild(this.view = viewHost.getView());
document.body.appendChild(this.view = this.viewHost.getView());
return Promise.resolve();
}
screenshot(): string {
return svg.toDataUri(new XMLSerializer().serializeToString(this.view));
screenshotAsync(): Promise<ImageData> {
return this.viewHost.screenshotAsync();
}
}

View File

@ -10,7 +10,7 @@ namespace pxsim.visuals {
<path id="VCC" fill="red" stroke-width="2" d="M53.72 21.93h5.504v22.627H53.72z"/>
<path id="LOGIC" fill="#fc0" stroke-width="2" d="M47.3 21.93h5.503v22.627H47.3z"/>
<path id="GND" fill="#a02c2c" stroke-width="2" d="M60.14 21.93h5.505v22.627H60.14z"/>
<path id="connector" stroke-width="2" d="M45.064 0a1.488 1.488 0 0 0-1.488 1.488v24.5a1.488 1.488 0 0 0 1.488 1.487h22.71a1.488 1.488 0 0 0 1.49-1.488v-24.5A1.488 1.488 0 0 0 67.774 0h-22.71z"/>
<path id="connector" fill="#111" stroke-width="2" d="M45.064 0a1.488 1.488 0 0 0-1.488 1.488v24.5a1.488 1.488 0 0 0 1.488 1.487h22.71a1.488 1.488 0 0 0 1.49-1.488v-24.5A1.488 1.488 0 0 0 67.774 0h-22.71z"/>
<g id="crank" transform="translate(0 -752.688)">
<path id="arm" fill="#ececec" stroke="#000" stroke-width="1.372" d="M47.767 880.88c-4.447 1.162-8.412 8.278-8.412 18.492s3.77 18.312 8.412 18.494c8.024.314 78.496 5.06 78.51-16.952.012-22.013-74.377-21.117-78.51-20.035z"/>
<circle id="path8216" cx="56.661" cy="899.475" r="8.972" fill="gray" stroke-width="2"/>

View File

@ -17,7 +17,9 @@ namespace pxsim.visuals {
.sim-button {
pointer-events: none;
}
.sim-board, .sim-display, sim-button {
fill: #111;
}
.sim-button-outer:hover {
stroke:grey;
stroke-width: 3px;
@ -241,14 +243,14 @@ path.sim-board {
export var themes: IBoardTheme[] = ["#3ADCFE", "#FFD43A", "#3AFFB3", "#FF3A54"].map(accent => {
return {
accent: accent,
display: "#000",
display: "#111",
pin: "#D4AF37",
pinTouched: "#FFA500",
pinActive: "#FF5500",
ledOn: "#ff7f7f",
ledOff: "#202020",
buttonOuter: "#979797",
buttonUp: "#000",
buttonUp: "#111",
buttonDown: "#FFA500",
virtualButtonOuter: "#333",
virtualButtonUp: "#fff",
@ -761,6 +763,7 @@ path.sim-board {
"y": "0px",
"width": MB_WIDTH + "px",
"height": MB_HEIGHT + "px",
"fill": "rgba(0,0,0,0)"
});
this.style = <SVGStyleElement>svg.child(this.element, "style", {});
this.style.textContent = MB_STYLE + (this.props.theme.highContrast ? MB_HIGHCONTRAST : "");
@ -785,10 +788,12 @@ path.sim-board {
for (let i = 0; i < 3; ++i) svg.child(merge, "feMergeNode", { in: "glow" })
// outline
svg.path(this.g, "sim-board", "M498,31.9C498,14.3,483.7,0,466.1,0H31.9C14.3,0,0,14.3,0,31.9v342.2C0,391.7,14.3,406,31.9,406h434.2c17.6,0,31.9-14.3,31.9-31.9V31.9z M14.3,206.7c-2.7,0-4.8-2.2-4.8-4.8c0-2.7,2.2-4.8,4.8-4.8c2.7,0,4.8,2.2,4.8,4.8C19.2,204.6,17,206.7,14.3,206.7z M486.2,206.7c-2.7,0-4.8-2.2-4.8-4.8c0-2.72.2-4.8,4.8-4.8c2.7,0,4.8,2.2,4.8,4.8C491,204.6,488.8,206.7,486.2,206.7z");
const pkg = svg.path(this.g, "sim-board", "M498,31.9C498,14.3,483.7,0,466.1,0H31.9C14.3,0,0,14.3,0,31.9v342.2C0,391.7,14.3,406,31.9,406h434.2c17.6,0,31.9-14.3,31.9-31.9V31.9z M14.3,206.7c-2.7,0-4.8-2.2-4.8-4.8c0-2.7,2.2-4.8,4.8-4.8c2.7,0,4.8,2.2,4.8,4.8C19.2,204.6,17,206.7,14.3,206.7z M486.2,206.7c-2.7,0-4.8-2.2-4.8-4.8c0-2.72.2-4.8,4.8-4.8c2.7,0,4.8,2.2,4.8,4.8C491,204.6,488.8,206.7,486.2,206.7z");
svg.hydrate(pkg, { fill: "#111" });
// script background
this.display = svg.path(this.g, "sim-display", "M333.8,310.3H165.9c-8.3,0-15-6.7-15-15V127.5c0-8.3,6.7-15,15-15h167.8c8.3,0,15,6.7,15,15v167.8C348.8,303.6,342.1,310.3,333.8,310.3z");
svg.hydrate(this.display, { fill: "#111" });
this.logos = [];
this.logos.push(svg.child(this.g, "polygon", { class: "sim-theme", points: "115,56.7 173.1,0 115,0" }));
@ -876,6 +881,7 @@ path.sim-board {
this.buttons.push(svg.child(this.g, "circle", { class: "sim-button", cx: 446, cy: 278, r: 16.5 }));
(<any>this.buttonsOuter[2]).style.visibility = "hidden";
(<any>this.buttons[2]).style.visibility = "hidden";
this.buttons.forEach(btn => svg.hydrate(btn, { fill: "#111" }));
svg.path(this.g, "sim-label", "M35.7,376.4c0-2.8,2.1-5.1,5.5-5.1c3.3,0,5.5,2.4,5.5,5.1v4.7c0,2.8-2.2,5.1-5.5,5.1c-3.3,0-5.5-2.4-5.5-5.1V376.4zM43.3,376.4c0-1.3-0.8-2.3-2.2-2.3c-1.3,0-2.1,1.1-2.1,2.3v4.7c0,1.2,0.8,2.3,2.1,2.3c1.3,0,2.2-1.1,2.2-2.3V376.4z");
svg.path(this.g, "sim-label", "M136.2,374.1c2.8,0,3.4-0.8,3.4-2.5h2.9v14.3h-3.4v-9.5h-3V374.1z");