程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长


+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

暂无数据

通过捕捉功能移动拇指穿过轨迹

发布于2024-11-03 21:55     阅读(687)     评论(0)     点赞(28)     收藏(1)


首先,与下面的例子进行交互。

此组件必须与输入类型范围完全相同。我遇到的问题是计算步长值,根据当前步长和最大值的比例将拇指捕捉到轨迹中(再次,与范围输入完全相同)。

欢迎任何使用原生范围输入来控制此行为的回应。我没有使用它只是因为捕捉不流畅。

const thumb = document.querySelector(".stepper__step");
const trail = document.querySelector(".stepper__trail");

// Variables that controls the range snap and values
var minVal = 0;
var maxVal = 20;
var step = 2;

thumb.ondragstart = function() {
  return false;
};

thumb.addEventListener("mousedown", function(event) {
  event.preventDefault();
  addGrabbingClassFromThumb();

  let shiftX = event.clientX - thumb.getBoundingClientRect().left;
  // shiftY not needed, the thumb moves only horizontally

  document.addEventListener("mousemove", onMouseMove);
  document.addEventListener("mouseup", onMouseUp);

  function onMouseMove(event) {
    let newLeft = event.clientX - shiftX - trail.getBoundingClientRect().left;

    // the pointer is out of trail => lock the thumb within the bounaries
    if (newLeft < 0) {
      newLeft = 0;
    }
    let rightEdge = trail.offsetWidth - thumb.offsetWidth;
    if (newLeft > rightEdge) {
      newLeft = rightEdge;
    }

    thumb.style.left = newLeft + "px";
  }

  function onMouseUp() {
    document.removeEventListener("mouseup", onMouseUp);
    document.removeEventListener("mousemove", onMouseMove);
  }
});

thumb.addEventListener("mouseup", function() {
  removeGrabbingClassFromThumb();
});

function addGrabbingClassFromThumb() {
  thumb.className += " stepper__step--grabbing";
}

function removeGrabbingClassFromThumb() {
  thumb.className = thumb.className.replace(/stepper__step--grabbing/g, "");
}
body {
  background-color: #333333;
}

.stepper-wrapper {
  width: 350px;
  margin: 80px auto;
  position: relative;
}

.stepper__trail {
  height: 2px;
  background-color: rgba(255, 255, 255, 0.25);
}

.stepper__step {
  height: 20px;
  position: absolute;
  left: 0;
  width: 50px;
  bottom: 0;
  transition: left 0.25s ease-in-out;
  cursor: -webkit-grab;
  cursor: grab;
}
.stepper__step:after {
  content: "";
  display: block;
  position: absolute;
  left: 0;
  bottom: 0;
  right: 0;
  height: 100%;
  background-color: #fff;
}

.stepper__step--grabbing {
  cursor: -webkit-grabbing;
  cursor: grabbing;
  transition: unset;
}
<div class="stepper-wrapper">
  <div class="stepper__step"></div>
  <div class="stepper__trail"></div>
</div>


解决方案


我认为您只是缺少一些计算和辅助函数来确定如何捕捉。

首先,我们需要包装器:

const wrapper = document.querySelector('.stepper-wrapper');

接下来,我们需要计算一些值来生成范围点:

const containerWidth = wrapper.offsetWidth
const pixelsPerStep = Math.round(containerWidth / maxVal)
const totalSteps = Math.round(pixelsPerStep / step);

一个快速的耦合辅助函数可以生成我们的范围并找到我们最接近的可能捕捉点:

const range = (start, stop, step = 1) =>
  Array(Math.ceil((stop - start) / step)).fill(start).map((x, y) => x + y * step)

const closest = (range, goal) => {
  return range.reduce((prev, curr) => {
    return (Math.abs(curr - goal) < Math.abs(prev - goal) ? curr : prev)
  })
}

在我们的mousedown事件监听器中,我们可以生成可以捕捉的点:

const snapTo = closest(rangePoints, newLeft);

这可以用作元素.left的属性thumb

jsFiddle用于说明。




所属网站分类: 技术文章 > 问答

作者:黑洞官方问答小能手

链接:http://www.qianduanheidong.com/blog/article/534980/e76d8cb8d11e0085b164/

来源:前端黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

28 0
收藏该文
已收藏

评论内容:(最多支持255个字符)