spreadtheweb / multi-range-slider

Simple, small and fast vanilla JavaScript multi range slider without dependencies, with ability to have multiple values and points to slide
31 stars 7 forks source link

Wrong handle positioning when using inside a position: sticky container #1

Open simosulev opened 1 year ago

simosulev commented 1 year ago

There seems to be an issue with the handle position calculations when using sliders inside a position: sticky container.

Would love to get this working correctly.

Otherwise nice plugin. Keep up the good work!

S.

Florian-Piault commented 1 year ago

Hello, I used this component in my Angular application. I am using the slider in a sticky container aswell and I just fixed the issue by replacing the documentMouseMoveHandler function and changing the values depending on the container's bounding rectangle :

ngAfterViewInit(): void {
    this.slider = new RangeSlider('#range', {
      values: this.values,
      step: this.step,
      min: this.min,
      max: this.max,
      pointRadius: this.thumbRadius,
      trackHeight: this.trackHeight,
      railHeight: this.railHeight,
      colors: {
        points: ["#0075ff"],
        tracks: ["#0075ff"],
        rail: "#c4c4c4",
      }
    }).onChange((v: number[]) => this.valuesChange.emit(v));

    this.slider.documentMouseMoveHandler = (e) => this.overriddenMouseMoveHandle(e, this.slider);
  }

  private overriddenMouseMoveHandle(e, slider) {
    const {left, width} = slider.container.getBoundingClientRect();

    let newPosition = e.pageX - left;
    const extra = Math.floor(newPosition % slider.jump);

    if (extra > slider.jump / 2) newPosition += slider.jump - extra;
    else newPosition -= extra;

    if (newPosition < 0) newPosition = 0;
    else if (newPosition > width) newPosition = width;

    slider.pointPositions[slider.selectedPointIndex] = newPosition;

    slider.allProps.values[slider.selectedPointIndex] = slider.possibleValues[Math.floor(newPosition / slider.jump)];
    slider.draw();
  }
gmsarates commented 5 months ago

Hello, I used this component in my Angular application. I am using the slider in a sticky container aswell and I just fixed the issue by replacing the documentMouseMoveHandler function and changing the values depending on the container's bounding rectangle :

ngAfterViewInit(): void {
    this.slider = new RangeSlider('#range', {
      values: this.values,
      step: this.step,
      min: this.min,
      max: this.max,
      pointRadius: this.thumbRadius,
      trackHeight: this.trackHeight,
      railHeight: this.railHeight,
      colors: {
        points: ["#0075ff"],
        tracks: ["#0075ff"],
        rail: "#c4c4c4",
      }
    }).onChange((v: number[]) => this.valuesChange.emit(v));

    this.slider.documentMouseMoveHandler = (e) => this.overriddenMouseMoveHandle(e, this.slider);
  }

  private overriddenMouseMoveHandle(e, slider) {
    const {left, width} = slider.container.getBoundingClientRect();

    let newPosition = e.pageX - left;
    const extra = Math.floor(newPosition % slider.jump);

    if (extra > slider.jump / 2) newPosition += slider.jump - extra;
    else newPosition -= extra;

    if (newPosition < 0) newPosition = 0;
    else if (newPosition > width) newPosition = width;

    slider.pointPositions[slider.selectedPointIndex] = newPosition;

    slider.allProps.values[slider.selectedPointIndex] = slider.possibleValues[Math.floor(newPosition / slider.jump)];
    slider.draw();
  }

Thanks! Your answer fix the problem when sliding the points, but with the click on the bar the bug still happening. 😢