/**
* 3D Foundation Project
* Copyright 2025 Smithsonian Institution
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Property from "@ff/graph/Property";
import { customElement, property, PropertyValues, html } from "@ff/ui/CustomElement";
import "@ff/ui/LinearSlider";
import { ILinearSliderChangeEvent } from "@ff/ui/LinearSlider";
import PropertyBase from "./PropertyBase";
////////////////////////////////////////////////////////////////////////////////
@customElement("sv-property-slider")
export default class PropertySlider extends PropertyBase
{
type = "number";
@property({ type: Number })
min: number = undefined;
@property({ type: Number })
max: number = undefined;
protected firstConnected()
{
super.firstConnected();
this.classList.add("sv-property-slider");
}
protected update(changedProperties: PropertyValues): void
{
if (changedProperties.has("property")) {
const property = changedProperties.get("property") as Property;
if (property) {
property.off("value", this.onUpdate, this);
}
if (this.property) {
this.property.on("value", this.onUpdate, this);
}
}
super.update(changedProperties);
}
protected render()
{
const property = this.property;
const name = this.name || property.name;
const value = property.getValidatedValue();
const min = isFinite(this.min) ? this.min : property.schema.min;
const max = isFinite(this.max) ? this.max : property.schema.max;
const v = (value - min) / (max - min);
return html`
`;
}
protected onSliderChange(event: ILinearSliderChangeEvent)
{
const property = this.property;
const min = isFinite(this.min) ? this.min : property.schema.min;
const max = isFinite(this.max) ? this.max : property.schema.max;
const value = min + event.detail.value * (max - min);
property.setValue(value);
}
protected onKeyDown(event: KeyboardEvent)
{
const property = this.property;
if(event.code === "ArrowRight" || event.code === "ArrowUp" || event.code === "PageUp") {
property.setValue(this.clamp(event.code === "PageUp" ? property.value + 0.1 : property.value + 0.01));
}
else if(event.code === "ArrowLeft" || event.code === "ArrowDown" || event.code === "PageDown") {
property.setValue(this.clamp(event.code === "PageDown" ? property.value - 0.1 : property.value - 0.01));
}
}
protected clamp(input: number) : number
{
const property = this.property;
const min = isFinite(this.min) ? this.min : property.schema.min;
const max = isFinite(this.max) ? this.max : property.schema.max;
return Math.min(Math.max(input, min), max);
}
}