Add new component to edit background color in the sidebar with custom
color support
Change-Id: Id238673fea57dbd9768e5dd5e33c8541810f48d9
Reviewed-on: https://skia-review.googlesource.com/c/buildbot/+/703500
Commit-Queue: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Kevin Lubick <kjlubick@google.com>
diff --git a/skottie/modules/skottie-background-settings-sk/BUILD.bazel b/skottie/modules/skottie-background-settings-sk/BUILD.bazel
new file mode 100644
index 0000000..5495d03f
--- /dev/null
+++ b/skottie/modules/skottie-background-settings-sk/BUILD.bazel
@@ -0,0 +1,18 @@
+load("//infra-sk:index.bzl", "sk_element")
+
+sk_element(
+ name = "skottie-background-settings-sk",
+ sass_deps = ["//elements-sk/modules:colors_sass_lib"],
+ sass_srcs = ["skottie-background-settings-sk.scss"],
+ sk_element_deps = ["//skottie/modules/skottie-dropdown-sk"],
+ ts_deps = [
+ "//elements-sk/modules:define_ts_lib",
+ "//infra-sk/modules/ElementSk:index_ts_lib",
+ "@npm//lit-html",
+ ],
+ ts_srcs = [
+ "index.ts",
+ "skottie-background-settings-sk.ts",
+ ],
+ visibility = ["//visibility:public"],
+)
diff --git a/skottie/modules/skottie-background-settings-sk/index.ts b/skottie/modules/skottie-background-settings-sk/index.ts
new file mode 100644
index 0000000..3de74fe
--- /dev/null
+++ b/skottie/modules/skottie-background-settings-sk/index.ts
@@ -0,0 +1 @@
+import './skottie-background-settings-sk';
diff --git a/skottie/modules/skottie-background-settings-sk/skottie-background-settings-sk.scss b/skottie/modules/skottie-background-settings-sk/skottie-background-settings-sk.scss
new file mode 100644
index 0000000..2b8ec84
--- /dev/null
+++ b/skottie/modules/skottie-background-settings-sk/skottie-background-settings-sk.scss
@@ -0,0 +1,32 @@
+@import '../../../elements-sk/modules/colors';
+
+skottie-background-settings-sk {
+ .wrapper {
+ width: 100%;
+ padding: 8px;
+ }
+
+ .color-form {
+ margin-top: 16px;
+
+ &--color {
+ border: 1px solid var(--skottie-on-surface-white);
+ border-right: none;
+ border-radius: 4px 0 0 4px;
+ padding: 4px;
+
+ input {
+ border: none;
+ width: 18px;
+ padding: 6px 0 0 0;
+ }
+ }
+
+ &--opacity {
+ border: 1px solid var(--skottie-on-surface-white);
+ border-radius: 0 4px 4px 0;
+ padding: 4px;
+ width: 80px;
+ }
+ }
+}
diff --git a/skottie/modules/skottie-background-settings-sk/skottie-background-settings-sk.ts b/skottie/modules/skottie-background-settings-sk/skottie-background-settings-sk.ts
new file mode 100644
index 0000000..2cf4d2f
--- /dev/null
+++ b/skottie/modules/skottie-background-settings-sk/skottie-background-settings-sk.ts
@@ -0,0 +1,175 @@
+/**
+ * @module skottie-background-settings-sk
+ * @description <h2><code>skottie-background-settings-sk</code></h2>
+ *
+ * <p>
+ * A component to edit the background color in the sidebar
+ * </p>
+ *
+ *
+ * @evt background-change - This event is triggered every time the
+ * user selects a new color or opacity
+ *
+ */
+import { define } from '../../../elements-sk/modules/define';
+import { html, TemplateResult } from 'lit-html';
+import { ElementSk } from '../../../infra-sk/modules/ElementSk';
+import '../skottie-dropdown-sk';
+import { DropdownSelectEvent } from '../skottie-dropdown-sk/skottie-dropdown-sk';
+
+type BackgroundMode = 'light' | 'dark' | 'custom';
+
+type ValuePair = {
+ color: string;
+ opacity: number;
+};
+
+const values: Record<BackgroundMode, ValuePair> = {
+ light: {
+ color: '#FFFFFF',
+ opacity: 100,
+ },
+ dark: {
+ color: '#000000',
+ opacity: 100,
+ },
+ custom: {
+ color: '#FF0000',
+ opacity: 100,
+ },
+};
+
+export interface SkottieBackgroundSettingsEventDetail {
+ color: string;
+ opacity: number;
+}
+
+export class SkottieBackgroundSettingsSk extends ElementSk {
+ private _color: string = values.light.color;
+
+ private _opacity: number = values.light.opacity;
+
+ private _backgroundMode: BackgroundMode = 'light';
+
+ private static template = (ele: SkottieBackgroundSettingsSk) => html`
+ <div class="wrapper">
+ <skottie-dropdown-sk
+ id="background-selector"
+ .name="background-selector"
+ .options=${[
+ {
+ id: 'light',
+ value: 'Light',
+ selected: ele._backgroundMode === 'light',
+ },
+ {
+ id: 'dark',
+ value: 'Dark',
+ selected: ele._backgroundMode === 'dark',
+ },
+ {
+ id: 'custom',
+ value: 'Custom',
+ selected: ele._backgroundMode === 'custom',
+ },
+ ]}
+ @select=${ele.backgroundSelectHandler}
+ border
+ ></skottie-dropdown-sk>
+ ${ele.renderColorInput()}
+ </div>
+ `;
+
+ constructor() {
+ super(SkottieBackgroundSettingsSk.template);
+ }
+
+ connectedCallback(): void {
+ super.connectedCallback();
+ this._render();
+ // Query params are not set when `connectedCallback` is called.
+ // As a workaround this timeout of 1ms seems to be enough.
+ setTimeout(() => {
+ const params = new URL(document.location.href).searchParams;
+ const color = params.has('bg') ? params.get('bg')! : '';
+ if (color) {
+ let mode: BackgroundMode;
+ if (color === values.light.color) {
+ mode = 'light';
+ } else if (color === values.dark.color) {
+ mode = 'dark';
+ } else {
+ mode = 'custom';
+ }
+ this._backgroundMode = mode;
+ this._opacity = values[this._backgroundMode].opacity;
+ this._color = color;
+ this._render();
+ this._submit();
+ }
+ }, 1);
+ }
+
+ private renderColorInput(): TemplateResult | null {
+ if (this._backgroundMode === 'custom') {
+ return html`
+ <div class="color-form">
+ <label class="color-form--color">
+ <input
+ type="color"
+ value=${this._color}
+ @change=${this.onColorChange}
+ />
+ <span>${this._color}</span>
+ </label>
+ <input
+ type="number"
+ class="color-form--opacity"
+ .value=${this._opacity}
+ @change=${this.onOpacityChange}
+ />
+ </div>
+ `;
+ }
+ return null;
+ }
+
+ private _submit(): void {
+ this.dispatchEvent(
+ new CustomEvent<SkottieBackgroundSettingsEventDetail>(
+ 'background-change',
+ {
+ detail: {
+ color: this._color,
+ opacity: this._opacity,
+ },
+ bubbles: true,
+ }
+ )
+ );
+ }
+
+ private backgroundSelectHandler(ev: CustomEvent<DropdownSelectEvent>): void {
+ this._backgroundMode = ev.detail.value as BackgroundMode;
+ this._color = values[this._backgroundMode].color;
+ this._opacity = values[this._backgroundMode].opacity;
+ this._submit();
+ this._render();
+ }
+
+ private onColorChange(ev: Event): void {
+ const input = ev.target as HTMLInputElement;
+ this._color = input.value;
+ this._submit();
+ this._render();
+ }
+
+ private onOpacityChange(ev: Event): void {
+ const input = ev.target as HTMLInputElement;
+ this._opacity = input.valueAsNumber;
+ this._submit();
+ this._render();
+ }
+}
+
+define('skottie-background-settings-sk', SkottieBackgroundSettingsSk);
diff --git a/skottie/modules/skottie-player-sk/skottie-player-sk.ts b/skottie/modules/skottie-player-sk/skottie-player-sk.ts
index 6d0a54a..1b43f27 100644
--- a/skottie/modules/skottie-player-sk/skottie-player-sk.ts
+++ b/skottie/modules/skottie-player-sk/skottie-player-sk.ts
@@ -265,6 +265,11 @@
);
}
+ getBackgroundColor(): string {
+ const params = new URL(document.location.href).searchParams;
+ return params.has('bg') ? params.get('bg')! : '#fff';
+ }
+
connectedCallback(): void {
super.connectedCallback();
const params = new URL(document.location.href).searchParams;
@@ -275,7 +280,7 @@
? +this.getAttribute('height')!
: 256;
this.showControls = params.has('controls');
- this.bgColor = params.has('bg') ? params.get('bg')! : '#fff';
+ this.bgColor = this.getBackgroundColor();
this._render();
}
@@ -284,6 +289,8 @@
this.height = config.height;
this.renderFPS = config.fps;
this._animationName = config.lottie.nm as string;
+ const params = new URL(document.location.href).searchParams;
+ this.bgColor = this.getBackgroundColor();
this._render();
return canvasReady.then((ck: CanvasKit) => {
diff --git a/skottie/modules/skottie-sk/BUILD.bazel b/skottie/modules/skottie-sk/BUILD.bazel
index 9c0bba8..d6d4d78 100644
--- a/skottie/modules/skottie-sk/BUILD.bazel
+++ b/skottie/modules/skottie-sk/BUILD.bazel
@@ -54,6 +54,7 @@
"//skottie/modules/skottie-file-settings-sk",
"//elements-sk/modules/icons/file-download-icon-sk",
"//skottie/modules/skottie-file-form-sk",
+ "//skottie/modules/skottie-background-settings-sk",
],
ts_deps = [
"//infra-sk/modules/ElementSk:index_ts_lib",
diff --git a/skottie/modules/skottie-sk/skottie-sk.ts b/skottie/modules/skottie-sk/skottie-sk.ts
index cd61596..9b5efde 100644
--- a/skottie/modules/skottie-sk/skottie-sk.ts
+++ b/skottie/modules/skottie-sk/skottie-sk.ts
@@ -29,7 +29,7 @@
import { SoundMap, AudioPlayer } from '../audio';
import '../skottie-performance-sk';
import { renderByDomain } from '../helpers/templates';
-import { supportedDomains } from '../helpers/domains';
+import { isDomain, supportedDomains } from '../helpers/domains';
import '../skottie-audio-sk';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import {
@@ -77,6 +77,8 @@
} from '../skottie-file-settings-sk/skottie-file-settings-sk';
import '../skottie-file-form-sk';
import { SkottieFilesEventDetail } from '../skottie-file-form-sk/skottie-file-form-sk';
+import '../skottie-background-settings-sk';
+import { SkottieBackgroundSettingsEventDetail } from '../skottie-background-settings-sk/skottie-background-settings-sk';
// It is assumed that this symbol is being provided by a version.js file loaded in before this
// file.
@@ -118,7 +120,7 @@
supportedDomains.LOCALHOST,
];
-type UIMode = 'dialog' | 'loading' | 'loaded';
+type UIMode = 'dialog' | 'loading' | 'loaded' | 'idle';
const caption = (text: string, mode: ViewMode) => {
if (mode === 'presentation') {
@@ -208,6 +210,8 @@
default:
case 'dialog':
return this.displayDialog();
+ case 'idle':
+ return this.displayIdle();
case 'loading':
return displayLoading();
case 'loaded':
@@ -227,6 +231,14 @@
></skottie-config-sk>
`;
+ private displayIdle = () => html`
+ <div class="threecol">
+ <div class="left">${this.leftControls()}</div>
+ <div class="main"></div>
+ <div class="right">${this.rightControls()}</div>
+ </div>
+ `;
+
private displayLoaded = () => html`
<div class="threecol">
<div class="left">${this.leftControls()}</div>
@@ -307,8 +319,8 @@
return html`
<details class="embed expando">
<summary id="embed-open">
- <span>Embed</span><expand-less-icon-sk></expand-less-icon-sk
- ><expand-more-icon-sk></expand-more-icon-sk>
+ <span>Embed</span><expand-less-icon-sk></expand-less-icon-sk>
+ <expand-more-icon-sk></expand-more-icon-sk>
</summary>
<label>
Embed using an iframe
@@ -348,7 +360,8 @@
></skottie-file-form-sk>
</div>
- ${this.fileSettingsDialog()} ${this.audioDialog()} ${this.optionsDialog()}
+ ${this.fileSettingsDialog()} ${this.backgroundDialog()}
+ ${this.audioDialog()} ${this.optionsDialog()}
<button
class="apply-button"
@@ -390,8 +403,8 @@
private optionsDialog = () => html`
<details class="expando">
<summary id="options-open">
- <span>Options</span><expand-less-icon-sk></expand-less-icon-sk
- ><expand-more-icon-sk></expand-more-icon-sk>
+ <span>Options</span><expand-less-icon-sk></expand-less-icon-sk>
+ <expand-more-icon-sk></expand-more-icon-sk>
</summary>
<div class="options-container">
<checkbox-sk
@@ -414,8 +427,8 @@
this.toggleAudio((e.target! as HTMLDetailsElement).open)}
>
<summary id="audio-open">
- <span>Audio</span><expand-less-icon-sk></expand-less-icon-sk
- ><expand-more-icon-sk></expand-more-icon-sk>
+ <span>Audio</span><expand-less-icon-sk></expand-less-icon-sk>
+ <expand-more-icon-sk></expand-more-icon-sk>
</summary>
<skottie-audio-sk
@@ -437,8 +450,8 @@
this.toggleFileSettings((e.target! as HTMLDetailsElement).open)}
>
<summary id="fileSettings-open">
- <span>File Settings</span><expand-less-icon-sk></expand-less-icon-sk
- ><expand-more-icon-sk></expand-more-icon-sk>
+ <span>File Settings</span><expand-less-icon-sk></expand-less-icon-sk>
+ <expand-more-icon-sk></expand-more-icon-sk>
</summary>
<skottie-file-settings-sk
.width=${this.width}
@@ -449,6 +462,25 @@
</details>
`;
+ private backgroundDialog = () =>
+ html`
+ <details
+ class="expando"
+ ?open=${this.showBackgroundSettings}
+ @toggle=${(e: Event) =>
+ this.toggleBackgroundSettings((e.target! as HTMLDetailsElement).open)}
+ >
+ <summary>
+ <span>Background color</span>
+ <expand-less-icon-sk></expand-less-icon-sk>
+ <expand-more-icon-sk></expand-more-icon-sk>
+ </summary>
+ <skottie-background-settings-sk
+ @background-change=${this.skottieBackgroundUpdated}
+ ></skottie-background-settings-sk>
+ </details>
+ `;
+
private iframeDirections = () =>
`<iframe width="${this.width}" height="${this.height}" src="${window.location.origin}/e/${this.hash}?w=${this.width}&h=${this.height}" scrolling=no>`;
@@ -485,8 +517,8 @@
this.toggleLibrary((e.target! as HTMLDetailsElement).open)}
>
<summary id="library-open">
- <span>Library</span><expand-less-icon-sk></expand-less-icon-sk
- ><expand-more-icon-sk></expand-more-icon-sk>
+ <span>Library</span><expand-less-icon-sk></expand-less-icon-sk>
+ <expand-more-icon-sk></expand-more-icon-sk>
</summary>
<skottie-library-sk @select=${this.updateAnimation}> </skottie-library-sk>
@@ -540,8 +572,8 @@
this.toggleTextEditor((e.target! as HTMLDetailsElement).open)}
>
<summary id="edit-text-open">
- <span>Edit Text</span><expand-less-icon-sk></expand-less-icon-sk
- ><expand-more-icon-sk></expand-more-icon-sk>
+ <span>Edit Text</span><expand-less-icon-sk></expand-less-icon-sk>
+ <expand-more-icon-sk></expand-more-icon-sk>
</summary>
<skottie-text-editor-sk
@@ -561,8 +593,8 @@
this.toggleShaderEditor((e.target! as HTMLDetailsElement).open)}
>
<summary>
- <span>Edit Shader</span><expand-less-icon-sk></expand-less-icon-sk
- ><expand-more-icon-sk></expand-more-icon-sk>
+ <span>Edit Shader</span><expand-less-icon-sk></expand-less-icon-sk>
+ <expand-more-icon-sk></expand-more-icon-sk>
</summary>
<skottie-shader-editor-sk
@@ -651,6 +683,8 @@
private showFileSettings: boolean = false;
+ private showBackgroundSettings: boolean = false;
+
private skottieLibrary: SkottieLibrarySk | null = null;
private skottiePlayer: SkottiePlayerSk | null = null;
@@ -661,7 +695,7 @@
private stateChanged: () => void;
- private ui: UIMode = 'dialog';
+ private ui: UIMode = 'idle';
private viewMode: ViewMode = 'default';
@@ -694,6 +728,7 @@
bg: this.backgroundColor,
mode: this.viewMode,
fs: this.showFileSettings,
+ b: this.showBackgroundSettings,
}),
/* setState */ (newState) => {
this.showLottie = !!newState.l;
@@ -708,6 +743,7 @@
this.height = +newState.h;
this.fps = +newState.f;
this.showFileSettings = !!newState.fs;
+ this.showBackgroundSettings = !!newState.b;
this.viewMode =
newState.mode === 'presentation' ? 'presentation' : 'default';
this.backgroundColor = String(newState.bg);
@@ -867,12 +903,14 @@
this.width = e.detail.width;
this.height = e.detail.height;
this.fps = e.detail.fps;
- this.autoSize();
this.stateChanged();
+ if (this.state.lottie) {
+ this.autoSize();
+ this.initializePlayer();
+ // Re-sync all players
+ this.rewind();
+ }
this.render();
- this.initializePlayer();
- // Re-sync all players
- this.rewind();
}
private skottieFilesSelected(e: CustomEvent<SkottieFilesEventDetail>) {
@@ -890,6 +928,22 @@
this.upload();
}
+ private skottieBackgroundUpdated(
+ e: CustomEvent<SkottieBackgroundSettingsEventDetail>
+ ) {
+ const background = e.detail;
+ this.backgroundColor = background.color;
+ this.stateChanged();
+ if (this.state.lottie) {
+ this.autoSize();
+ this.initializePlayer();
+ // Re-sync all players
+ this.rewind();
+ }
+
+ this.render();
+ }
+
private selectionCancelled() {
this.ui = 'loaded';
this.render();
@@ -1099,7 +1153,9 @@
errorMessage(msg);
console.error(msg);
window.history.pushState(null, '', '/');
- this.ui = 'dialog';
+ // For development we recover to the loaded state to see the animation
+ // even if the upload didn't work
+ this.ui = isDomain(supportedDomains.LOCALHOST) ? 'loaded' : 'idle';
this.render();
}
@@ -1131,7 +1187,6 @@
}
this.ui = 'loaded';
this.loadAssetsAndRender().then(() => {
- console.log('loaded');
this.dispatchEvent(
new CustomEvent('initial-animation-loaded', { bubbles: true })
);
@@ -1497,6 +1552,12 @@
this.render();
}
+ private toggleBackgroundSettings(open: boolean): void {
+ this.showBackgroundSettings = open;
+ this.stateChanged();
+ this.render();
+ }
+
private toggleLottie(e: Event): void {
// avoid double toggles
e.preventDefault();