Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Externalise slider #5

Merged
merged 1 commit into from
Sep 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"@microsoft/api-documenter": "7.25.12",
"@microsoft/api-extractor": "7.47.7",
"@trevoreyre/autocomplete-js": "3.0.2",
"csstype": "^3.1.3",
"eslint": "9.9.1",
"eslint-config-prettier": "^9.1.0",
"lit": "3.2.0",
Expand Down
5 changes: 3 additions & 2 deletions src/apps/illumination/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,14 @@ export class NgvAppIllumination extends ABaseApp<IIlluminationConfig> {

render(): HTMLTemplateResult {
const r = super.render();
if (r) {
if (r && !this.config) {
// todo check
return r;
}
return html`
<ngv-structure-app .config=${this.config}>
<ngv-main-illumination
.config=${this.config.app}
.config=${this.config?.app}
></ngv-main-illumination>
</ngv-structure-app>
`;
Expand Down
134 changes: 49 additions & 85 deletions src/apps/illumination/ngv-main-illumination.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {customElement, property, query, state} from 'lit/decorators.js';
import {customElement, property, state} from 'lit/decorators.js';
import type {HTMLTemplateResult} from 'lit';
import {css, html, LitElement} from 'lit';
import {type CesiumWidget, JulianDate} from '@cesium/engine';
import type {IIlluminationConfig} from './ingv-config-illumination.js';

import '../../plugins/cesium/ngv-plugin-cesium-widget.js';
import '../../plugins/ui/ngv-colored-slider.js';
import type {SliderInputEventData} from '../../plugins/ui/ngv-colored-slider.js';

const YEAR = new Date().getFullYear();
const BASE_DATE = new Date(`${YEAR}-01-01T00:00:00`);
Expand All @@ -19,11 +21,6 @@ export class NgvMainIllumination extends LitElement {

private viewer: CesiumWidget;

@query('.hour-slider')
hourSlider: HTMLInputElement;
@query('.day-slider')
daySlider: HTMLInputElement;

@property({type: Object})
config: IIlluminationConfig['app'];

Expand Down Expand Up @@ -52,61 +49,9 @@ export class NgvMainIllumination extends LitElement {
z-index: 1000;
}

.slider-container {
display: flex;
flex-direction: column;
ngv-colored-slider {
width: 100%;
}

.day-slider {
background-image: linear-gradient(
to right,
#1843ef 8.3%,
#96de23 33.3%,
#d2c801 58.3%,
#f8700e 83.3%,
#1843ef 100%
);
//background-image: linear-gradient(to left, #1893EF 8.3%, #f8700e 8.3% 33.3%, #d2c801 33.3% 58.3%, #96de23 58.3% 83.3%, #1893EF 83.3% 100%)
}

.hour-slider {
background-image: linear-gradient(
to right,
#000033 0%,
/* 00:00 Night */ #000033 20%,
/* 05:00 */ #003366 25%,
/* 06:00 Dawn */ #6699ff 33%,
/* 09:00 Day */ #ffffcc 66%,
/* 16:00 Peak Daylight */ #ff9966 75%,
/* 17:00 Dusk */ #cc3300 80%,
/* 19:00 */ #000033 100% /* 23:00 Night */
);
}

.slider-container input {
-webkit-appearance: none;
width: 100%;
height: 10px;
}

.slider-container input::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 12px;
height: 22px;
border: 0;
background: red;
cursor: pointer;
}

.slider-container input::-moz-range-thumb {
width: 12px;
height: 22px;
border: 0;
background: red;
cursor: pointer;
}
`;

// FIXME: extract slider to own component
Expand All @@ -116,30 +61,51 @@ export class NgvMainIllumination extends LitElement {
<div class="app-container">
<label class="year-label">Year: ${YEAR}</label>
<div class="controls">
<div class="slider-container">
<label>Time: ${this.time}</label>
<input
type="range"
class="hour-slider"
min="0"
max="23"
step="1"
value="${this.hour}"
@input="${() => this.updateDayAndHour()}"
/>
</div>
<div class="slider-container">
<label>Day: ${this.date}</label>
<input
type="range"
class="day-slider"
min="1"
max="${this.daysInYear}"
step="1"
value="${this.day}"
@input="${() => this.updateDayAndHour()}"
/>
</div>
<ngv-colored-slider
class="hour-slider"
.title="Time: ${this.time}"
.min=${0}
.max=${23}
.value="${this.hour}"
.colorConfig="${{
side: 'to right',
colors: [
{color: '#000033', percentage: [0]},
{color: '#000033', percentage: [20]},
{color: '#003366', percentage: [25]},
{color: '#6699ff', percentage: [33]},
{color: '#ffffcc', percentage: [66]},
{color: '#ff9966', percentage: [75]},
{color: '#cc3300', percentage: [80]},
{color: '#000033', percentage: [100]},
],
}}"
@valueChanged="${(evt: CustomEvent<SliderInputEventData>) => {
this.hour = evt.detail.value;
this.updateDayAndHour();
}}"
></ngv-colored-slider>
<ngv-colored-slider
class="day-slider"
.title="Day: ${this.date}"
.min=${1}
.max="${this.daysInYear}"
.value="${this.day}"
.colorConfig="${{
side: 'to right',
colors: [
{color: '#1843ef', percentage: [8.3]},
{color: '#96de23', percentage: [33.3]},
{color: '#d2c801', percentage: [58.3]},
{color: '#f8700e', percentage: [83.3]},
{color: '#1843ef', percentage: [100]},
],
}}"
@valueChanged="${(value: CustomEvent<SliderInputEventData>) => {
this.day = value.detail.value;
this.updateDayAndHour();
}}"
></ngv-colored-slider>
</div>
<ngv-plugin-cesium-widget
.cesiumContext=${this.config.cesiumContext}
Expand All @@ -166,8 +132,6 @@ export class NgvMainIllumination extends LitElement {
}

updateDayAndHour(): void {
this.hour = parseInt(this.hourSlider.value);
this.day = parseInt(this.daySlider.value);
JulianDate.addHours(
BASE_JULIAN_DATE,
(this.day - 1) * 24 + this.hour,
Expand Down
94 changes: 94 additions & 0 deletions src/plugins/ui/ngv-colored-slider.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {customElement, property, query} from 'lit/decorators.js';
import type {HTMLTemplateResult} from 'lit';
import {css, html, LitElement} from 'lit';
import type {Properties} from 'csstype';

export type SliderInputEventData = {
value: number;
};

export type SliderColorConfig = {
side: 'to right' | 'to left';
colors: {
color: Properties['color'];
percentage: [number] | [number, number];
}[];
};

@customElement('ngv-colored-slider')
export class NgvColoredSlider extends LitElement {
@property({type: Number}) min: number;
@property({type: Number}) max: number;
@property({type: Number}) value: number;
@property({type: Number}) step: number = 1;
@property({type: String}) title: string | undefined;
@property({type: Object}) colorConfig: SliderColorConfig;
@query('input') input: HTMLInputElement;

static styles = css`
.slider-container {
display: flex;
flex-direction: column;
width: 100%;
}

.slider-container input {
-webkit-appearance: none;
width: 100%;
height: 10px;
}

.slider-container input::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 12px;
height: 22px;
border: 0;
background: red;
cursor: pointer;
}

.slider-container input::-moz-range-thumb {
width: 12px;
height: 22px;
border: 0;
background: red;
cursor: pointer;
}
`;

public override render(): HTMLTemplateResult {
return html`
<div class="slider-container">
<label .hidden="${!this.title}">${this.title}</label>
<input
type="range"
min="${this.min}"
max="${this.max}"
step="${this.step}"
value="${this.value}"
@input="${() => {
this.value = this.input.valueAsNumber;
this.dispatchEvent(
new CustomEvent<SliderInputEventData>('valueChanged', {
detail: {value: this.value},
}),
);
}}"
style="background-image: linear-gradient(${this.colorConfig
.side}, ${this.colorConfig.colors
.map(
(c) => `${c.color} ${c.percentage.map((p) => `${p}%`).join(' ')}`,
)
.join(', ')})"
/>
</div>
`;
}
}

declare global {
interface HTMLElementTagNameMap {
'ngv-colored-slider': NgvColoredSlider;
}
}