带有文本和不同颜色的圆形范围滑块

Round range slider with text and different color

我想做一个有4种不同颜色的圆形滑块,基本上圆形滑块应该是四部分,每个部分代表不同颜色的25%,当有人触发25%时,滑块颜色应该改变并且它的文本中的值也应该更改,例如,如果第一部分背景颜色为红色,则其文本为 name1,第二部分背景颜色应为绿色,其文本为 name2,第三和第四部分也应具有不同的颜色和文本。

供参考,请看图片,我想实现与附图相同的功能,你能帮忙吗,我该如何开发它?

如果您不能为此使用任何第 3 方库,我想您可能会对 this

感兴趣

最糟糕的部分是拖动按钮,所以它只能沿着圆圈边界移动

这里有点fiddle

$(function() {

  const svg = document.querySelector("svg");
  const circleButton = document.querySelector("#circle-button");
  const circle = document.querySelector("#circle2");
  const baseX = Number(circle.getAttributeNS(null, "cx"));
  const baseY = Number(circle.getAttributeNS(null, "cy"));
  const radius = Number(circle.getAttributeNS(null, "r"));
  
  let sliderHandle = null;
  let value = 0;
  let chunk = Math.PI * radius * 2 / 10;
  
  $("#start").click(function() {
  
    if(sliderHandle) {
      $(this).text('Start Slider');
      clearTimeout(sliderHandle);
      sliderHandle = null;
      return;
    }
  
    const loop = () => {
      circle.setAttributeNS(null, "stroke-dashoffset", value);
      value = value - chunk;
      sliderHandle = setTimeout(loop, 500);
    }
    
    $(this).text('Stop Slider');
    sliderHandle = setTimeout(loop, 500);
  })
  
  let handle = null;
  
  $("#move-button").click(function() {
    if(handle) {
      clearTimeout(handle);
      handle = null;
      $(this).text('Move Button');
      return;
    }
    $(this).text('Stop Button');
    runTimer();
  }) 
  
  
  svg.addEventListener('mousedown', startDrag);
  svg.addEventListener('mousemove', drag);
  svg.addEventListener('mouseup', endDrag);
  svg.addEventListener('mouseleave', endDrag);
  
  function getMousePosition({clientY, clientX}) {
    const {a, d, e, f} = svg.getScreenCTM();

    return {
      x: (clientX - e) / a,
      y: (clientY - f) / d
    };
  }
  
  let offset = {
    x: -1,
    y: -1
  }
  
  let isDragging = false;
  let selectedElement = null;
  
  function startDrag(event) {
    selectedElement = event.target;
    isDragging = true;
    offset = getMousePosition(event);
    offset.x -= parseFloat(circle.getAttributeNS(null, "cx"));
    offset.y -= parseFloat(circle.getAttributeNS(null, "cy"));
  }
  
  function drag(event) {
  
    if(!isDragging) {
      return;
    }
    
    event.preventDefault();
    const coord = getMousePosition(event);
    
    const cx = coord.x - offset.x;    
    const cy = coord.y - offset.y;    
    
    selectedElement.setAttributeNS(null, "cx", cx);
    selectedElement.setAttributeNS(null, "cy", cy);
  }
  
  const inc = Math.PI / 90;
  let t = 0;
  
  function runTimer() {
    const loop = () => {
      const cx = baseX + radius * Math.cos(t);
      const cy = baseY + radius * Math.sin(t);
      t = t + inc;

      circleButton.setAttributeNS(null, "cx", cx);
      circleButton.setAttributeNS(null, "cy", cy);
      handle = setTimeout(loop, 100);
    }
    
    handle = setTimeout(loop, 100);
  }
  
  function endDrag(event) {
    selectedElement = null;
    isDragging = false;
  }
  
})
#circle2, #circle-button {
  transition: all .2s ease-in;
}

#circle-button {
  cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<svg xmlns="http://www.w3.org/2000/svg"
    width="200" height="200">
<circle
  cx="100" cy="100" r="50"
  fill="none"
  stroke="gray"
  stroke-width="10"
  ></circle>
<circle
  id="circle2"
  cx="100" cy="100" r="50"
  fill="none"
  stroke="red"
  stroke-width="10"
  stroke-dasharray="320"
  stroke-dashoffset="0"></circle>
  <circle
  id="circle-button"
  cx="150"
  cy="100"
  r="12"
  fill="black"></circle>
</svg>
<button id="start">Start Slider</button>
<button id="move-button">Move Button</button>

编码愉快!

如果您愿意使用 roundSlider 插件,那么我会根据您的要求制作一个演示,而不是开发您自己的插件。

由于编写自定义逻辑涉及更多代码和需要考虑的检查点。

查看下面的演示,您仍然可以进行更多自定义。

DEMO

截图: