Added scrolling to sliders, resolves #38

This commit is contained in:
Lucas Dower 2022-05-12 18:59:36 +01:00
parent 9d760b1b84
commit 8e17342413
3 changed files with 62 additions and 22 deletions

View File

@ -34,6 +34,10 @@ export const roundToNearest = (value: number, base: number) => {
return Math.round(value / base) * base;
};
export const mapRange = (value: number, fromMin: number, fromMax: number, toMin: number, toMax: number) => {
return (value - fromMin)/(fromMax - fromMin) * (toMax - toMin) + toMin;
};
export const wayThrough = (value: number, min: number, max: number) => {
// ASSERT(value >= min && value <= max);
return (value - min) / (max - min);

View File

@ -1,5 +1,5 @@
import { ASSERT } from '../../util';
import { clamp } from '../../math';
import { clamp, mapRange, wayThrough } from '../../math';
import { LabelledElement } from './labelled_element';
export class SliderElement extends LabelledElement<number> {
@ -7,14 +7,18 @@ export class SliderElement extends LabelledElement<number> {
private _max: number;
private _decimals: number;
private _dragging: boolean;
private _step: number;
private _hovering: boolean;
public constructor(label: string, min: number, max: number, decimals: number, value: number) {
public constructor(label: string, min: number, max: number, decimals: number, value: number, step: number) {
super(label);
this._min = min;
this._max = max;
this._decimals = decimals;
this._value = value;
this._step = step;
this._dragging = false;
this._hovering = false;
}
public generateInnerHTML() {
@ -38,6 +42,7 @@ export class SliderElement extends LabelledElement<number> {
ASSERT(element !== null);
element.onmouseenter = () => {
this._hovering = true;
if (this._isEnabled) {
element.classList.add('new-slider-hover');
elementBar.classList.add('new-slider-bar-hover');
@ -45,49 +50,80 @@ export class SliderElement extends LabelledElement<number> {
};
element.onmouseleave = () => {
element.classList.remove('new-slider-hover');
elementBar.classList.remove('new-slider-bar-hover');
this._hovering = false;
if (!this._dragging) {
element.classList.remove('new-slider-hover');
elementBar.classList.remove('new-slider-bar-hover');
}
};
element.onmousedown = () => {
this._dragging = true;
};
document.addEventListener('mousemove', (e: any) => {
document.addEventListener('mousemove', (e: MouseEvent) => {
if (this._dragging) {
this._updateValue(e);
this._onDragSlider(e);
}
});
document.addEventListener('mouseup', (e: any) => {
document.addEventListener('mouseup', (e: MouseEvent) => {
if (this._dragging) {
this._updateValue(e);
this._onDragSlider(e);
}
if (!this._hovering) {
element.classList.remove('new-slider-hover');
elementBar.classList.remove('new-slider-bar-hover');
}
this._dragging = false;
});
element.addEventListener('wheel', (e: WheelEvent) => {
if (!this._dragging && this._isEnabled) {
e.preventDefault();
this._onScrollSlider(e);
}
});
}
private _updateValue(e: MouseEvent) {
private _onScrollSlider(e: WheelEvent) {
if (!this._isEnabled) {
return;
}
ASSERT(this._value);
this._value -= (e.deltaY / 150) * this._step;
this._value = clamp(this._value, this._min, this._max);
this._onValueUpdated();
}
private _onDragSlider(e: MouseEvent) {
if (!this._isEnabled) {
return;
}
const element = document.getElementById(this._id) as HTMLDivElement;
ASSERT(element !== null);
const box = element.getBoundingClientRect();
const left = box.x;
const right = box.x + box.width;
this._value = mapRange(e.clientX, left, right, this._min, this._max);
this._value = clamp(this._value, this._min, this._max);
this._onValueUpdated();
}
private _onValueUpdated() {
const elementBar = document.getElementById(this._id + '-bar') as HTMLDivElement;
const elementValue = document.getElementById(this._id + '-value') as HTMLDivElement;
ASSERT(element !== null && elementBar !== null && elementValue !== null);
ASSERT(elementBar !== null && elementValue !== null);
const mouseEvent = e as MouseEvent;
const xOffset = mouseEvent.clientX - elementBar.getBoundingClientRect().x;
const width = element.clientWidth;
const norm = clamp(xOffset / width, 0.0, 1.0);
const norm = wayThrough(this.getValue(), this._min, this._max);
elementBar.style.width = `${norm * 100}%`;
const value = (norm * (this._max - this._min)) + this._min;
const displayValue = value.toFixed(this._decimals);
elementValue.innerHTML = displayValue;
this._value = parseFloat(displayValue);
elementValue.innerHTML = this.getValue().toFixed(this._decimals);
}
protected _onEnabledChanged() {

View File

@ -45,7 +45,7 @@ export class UI {
'simplify': {
label: 'Simplify',
elements: {
'ratio': new SliderElement('Ratio', 0.0, 1.0, 2, 0.5),
'ratio': new SliderElement('Ratio', 0.0, 1.0, 2, 0.5, 0.01),
},
elementsOrder: ['ratio'],
submitButton: new ButtonElement('Simplify mesh', () => {
@ -56,7 +56,7 @@ export class UI {
'build': {
label: 'Build',
elements: {
'height': new SliderElement('Desired height', 3, 320, 0, 80),
'height': new SliderElement('Desired height', 3, 320, 0, 80, 1),
'voxeliser': new ComboBoxElement('Algorithm', [
{ id: 'bvhraybased', displayText: 'BVH Ray-based' },
{ id: 'normalcorrectedraybased', displayText: 'NCRB' },