javascriptcanvashtml5-canvas

javascript range slider with steps in html5 canvas


I'm trying to make a slider in javascript with canvas. The moveSlider() function is called by 'pointermove' eventlistener, and it changes the X coordinate of a rectangle stored in 'Slider' object in 200 pixel range.

I want it to be done in 11 steps, and cant seems to figure out how.

Also for some reason, if I add value of 'delta' to Slider.x the slider moves the opposite direction of the mouse, why?

any help is appreciated.

var startPos = e.clientX

function moveSlider(e) {

    let x = ctx.canvas.width / 2
    let delta = startPos - e.clientX;
    startPos = e.clientX;

    Slider.x -= delta;
    Slider.x = Slider.x > x+100 ? x+100 : Slider.x;  
    Slider.x = Slider.x < x-100 ? x-100 : Slider.x; 
}

Solution

  • You can try setting up an array that contains the "snap to" X-values along the slider. You will also need a function that accepts an X value, and returns the closest "snap to" value. Something like this:

    const left = 100;
    const width = 200;
    const numStops = 11;
    
    const lerp = (from, to, pct) => (to - from) * pct + from;
    
    const sliderPositions = Array.from(
      {length: numStops}, 
      (_, i) => lerp(left, left + width, i / (numStops - 1))
    );
    
    const getClosestSliderPosition = xPos => 
      sliderPositions.reduce((acc, el) => {
        if (Math.abs(xPos - el) < Math.abs(xPos - acc))
          acc = el;
        return acc;
      });
    
    console.log(getClosestSliderPosition(150));
    console.log(getClosestSliderPosition(115));
    console.log(sliderPositions);

    Then in your event handler you can use the getClosestSliderPosition function like so:

    function moveSlider(e) {
        Slider.x = getClosestSliderPosition(e.clientX);
    }