Javascript 用于范围输入的SVG圆弧滑块

Javascript 用于范围输入的SVG圆弧滑块,javascript,css,svg,slider,Javascript,Css,Svg,Slider,我的目标是设计一个弧形滑块,看起来像这样 我有以下模板结构 <svg width="500" height="300"> <path id="track" stroke="lightgrey" fill="transparent" stroke-width="20" d=" M 50 50 A 90 90 0 0 0 300

我的目标是设计一个弧形滑块,看起来像这样

我有以下模板结构

<svg width="500" height="300">
  <path id="track" stroke="lightgrey" fill="transparent" stroke-width="20" d="
     M 50 50
     A 90 90 0 0 0 300 50
  "/>
  <path id="trackFill" fill="cyan" stroke-width="20" d="
     M 50 50
     A 90 90 0 0 0 [some dynamic value?] [some dynamic value?]
  "/>
  <circle id="knob" fill="lightblue"  cx="[dynamic, initial - 50]" cy="[dynamic, initial - 50]" r="25"/>
</svg>


旋钮
-用户应拖动以更改值的控件

轨迹
-幻灯片的全弧

trackFill
-旋钮前的滑块路径部分


沿滑块曲线拖动滑块时,是否可以使
轨迹填充
覆盖旋钮前的滑块部分?如果是,哪些API或CSS规则将帮助我实现这样的结果?

下面是一个简单的示例:

常数半径=50;
常数offsetX=10;
常数偏移=10;

//0你想要的是这样的东西吗

let svg=document.getElementById(“滑块”);
让trackFill=document.getElementById(“trackFill”);
让旋钮=document.getElementById(“旋钮”);
让IsDraging=错误;
设sliderDragOffset={dx:0,dy:0};
设弧心={x:175,y:50};
设圆弧半径=125;
设sliderValue=0;
设置滑动值(滑动值);
函数setSliderValue(值)
{
//将值限制为(0..sliderMax)
让sliderMax=track.getTotalLength();
sliderValue=Math.max(0,Math.min(value,sliderMax));
//计算旋钮的新位置
设knobRotation=sliderValue*Math.PI/sliderMax;
设knobX=弧_中心.x-数学cos(knobtation)*弧_半径;
设knobY=ARC_center.y+Math.sin(knobRotation)*ARC_半径;
//调整trackFill仪表板模式,使其仅将部分拉至旋钮位置
setAttribute(“stroke dasharray”,sliderValue+“”+sliderMax);
//更新旋钮位置
设置属性(“cx”,knobX);
旋钮。设置属性(“cy”,旋钮);
}
旋钮.addEventListener(“鼠标向下”,evt=>{
IsDraging=true;
//记得我们在哪里点击旋钮,以便准确拖动吗
sliderDragOffset.dx=evt.offsetX-knob.cx.baseVal.value;
sliderDragOffset.dy=evt.offsetY-knob.cy.baseVal.value;
//将move事件附加到svg,以便在您移动到旋钮圈外时它可以工作
addEventListener(“mousemove”,knobMove);
//将移动事件附加到窗口,以便在您移动到svg之外时它可以工作
window.addEventListener(“mouseup”,knobRelease);
});
功能旋钮移动(evt)
{
//计算调整后的阻力位置
设x=evt.offsetX+SLIDEDRAGOFFSET.dx;
设y=evt.offsetY+SLIDEDRAGOFFSET.dy;
//相对于滑块弧中心的位置
x-=弧_中心.x;
y-=弧心y;
//获取相对于滑块中心的拖动位置角度
设角度=Math.atan2(y,-x);
//弧中心以上的位置将为负值,因此请优雅地处理它们
//通过与圆弧最近端的夹角
角度=(角度<-Math.PI/2)?Math.PI:(角度<0)?0:角度;
//从该角度计算新滑块值(滑块长度*角度/180度)
setSliderValue(angle*track.getTotalLength()/Math.PI);
}
功能旋钮释放(evt)
{
//取消事件处理程序
removeEventListener(“mousemove”,knobMove);
window.removeEventListener(“mouseup”,knobRelease);
IsDraging=错误;
}


无需动态更改轨迹填充路径。相反,你可以通过使用
stroke dasharray
@PaulLeBeau来控制它的绘制量。你能举个简单的例子吗?嗨,Michael,你能解释一下
x
y
坐标背后的数学吗?为什么我们需要x\y偏移值?当然。这是一个基本的三角学。旋钮相对于滑块中心的位置为:x=cos(角度)*半径,y=sin(角度)*半径。角度为180*pos(以度为单位)或PI*pos(以弧度为单位)。中心坐标为x:offsetX+半径;y=offsetY+radiusSorry,中心的y=offsetY。其余的都是正确的:)太棒了,非常感谢。还有一件事,这个滑块可以在移动设备和桌面设备上工作吗?简单地用触摸事件替换鼠标事件似乎不是在W3C标准Web组件中使用多个实例的正确方法page@MaxLiapkalo触摸基本上是一样的。但是对于
touchstart
touchmove
您需要访问
touchs
属性。另一个复杂问题是触摸事件没有
offsetX/Y
属性,因此您需要自己计算这些属性(请参阅)