admin管理员组文章数量:1391918
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;
}
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;
}
Share
Improve this question
asked Mar 16 at 23:20
NahNah
431 silver badge9 bronze badges
2
|
2 Answers
Reset to default 1You 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);
}
Canvas is fixed in px as you are already aware. If you want to streamline your code why not base it on:
e.pageX
: The horizontal coordinate of your mouse in relation to the left edge of the document.The offset between the left edge of the document and the left edge of the area within the canvas (not the offset of the whole canvas).
The offset between the left edge of the document and the right edge of the area within the canvas.
In the example below, the area within the canvas is the red line which starts 60px from the left edge of the document and its right edge is 260px from the left edge of the document. The essential lines of the "pointermove" event handler are:
if (dragging && e.pageX < 260 && e.pageX > 59) {
x = e.pageX;
draw();
const cvs = document.getElementById("cvs");
const ctx = cvs.getContext("2d");
const xpx = document.getElementById("xpx");
const xpc = document.getElementById("xpc");
const w = 220;
const h = 30;
let dragging = false;
let x = 60;
let rAF;
const rect = (x, y, w, h) => {
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.closePath();
ctx.fill();
}
const clear = () => {
ctx.clearRect(50, 50, w, h);
}
const draw = () => {
clear();
ctx.fillStyle = "#CCCCCC";
rect(50, 50, w, h);
ctx.fillStyle = "#FF0000";
rect(60, 60, 200, 10);
ctx.fillStyle = "#444444";
rect(x - 5, 60, 10, 10);
if (dragging) {
rAF = requestAnimationFrame(draw);
}
cancelAnimationFrame(rAF);
};
const pointerMove = (e) => {
if (dragging && e.pageX < 260 && e.pageX > 59) {
x = e.pageX;
draw();
cvs.style.cursor = "ew-resize";
xpx.value = Math.ceil(x) + "px";
xpc.value = Math.ceil(((x - 60) / 200) * 100) + "%";
}
};
const pointerDown = (e) => {
if (e.pageX < 260 && e.pageX > 59) {
x = e.pageX;
dragging = true;
cvs.onpointermove = pointerMove;
cvs.style.cursor = "ew-resize";
xpx.value = Math.ceil(x) + "px";
xpc.value = Math.ceil(((x - 60) / 200) * 100) + "%";
}
};
const pointerClick = (e) => {
if (e.pageX < 260 && e.pageX > 59) {
x = e.pageX;
}
};
const pointerExit = () => {
dragging = false;
cvs.onpointermove = null;
cvs.style.cursor = "default";
};
cvs.onpointerdown = pointerDown;
cvs.onclick = pointerClick;
cvs.onpointerup = pointerExit;
draw();
* {
margin: 0;
padding: 0;
box-sizing: border-box
}
<canvas id="cvs" width="275" height="90"></canvas>
<output id="xpx"></output>
<output id="xpc"></output>
本文标签: javascript range slider with steps in html5 canvasStack Overflow
版权声明:本文标题:javascript range slider with steps in html5 canvas - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744584095a2614095.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
Slider.x -= delta;
try adding it:Slider.x += delta;
– zer00ne Commented Mar 17 at 0:40let delta = startPos - e.clientX
– James Commented Mar 17 at 2:15