jquery 第一次鼠标移动时平滑滚动到鼠标位置

cczfrluj  于 2022-11-03  发布在  jQuery
关注(0)|答案(1)|浏览(180)

我用mousemove()函数创建了一个自动滚动到鼠标位置的区域。问题是该区域中的第一个mousemove直接跳到没有平滑滚动的位置。
我怎么才能实现呢?它应该只是第一个,在它之后,它应该滚动通过css属性translate 3d。
我创造了一支笔:https://codepen.io/rwillhaus/pen/LYrPNod

var docWidth = $("body").width(),
    slidesWidth = $("#stage").width(),
    rangeX = slidesWidth - docWidth,
    $divStage = $("#stage");

$(window).on("resize", function () {
    var docWidth = $("body").width(),
         slidesWidth = $("#stage").width(),
         rangeX = slidesWidth - docWidth;
});

initialScroll = true;

$(document).mousemove(function (e) {
          var mouseX = e.pageX;
          var percentMouse = mouseX / (docWidth / 2);
          var offset = percentMouse * slidesWidth - percentMouse * docWidth;

          //check if left or right direction
          var sl = offset;

          $divStage.css({
              transform: "translate3d(" + -(offset / 2) + "px,0,0)",
              "-webkit-transform": "translate3d(" + -(offset / 2) + "px,0,0)",
              "-moz-transform": "translate3d(" + -(offset / 2) + "px,0,0)",
              "-ms-transform": "translate3d(" + -(offset / 2) + "px,0,0)",
              "-o-transform": "translate3d(" + -(offset / 2) + "px,0,0)",
          });
});

我试着加了一个“过渡:变换0 s缓进;“,但问题是在第一次平滑滚动到鼠标指针后效果仍然持续。
谢谢

vyswwuz2

vyswwuz21#

我认为您的示例应用程序中可能存在对平滑滚动的误解。
代码中没有任何东西是平滑滚动的。它都会立即跳到它应该在的位置。
只有当鼠标在目标区域内移动时,它才看起来像是平滑滚动。这是因为在div的位置在屏幕中更新之前,鼠标只能移动一点点(可能是每秒60帧)。
同样的行为也发生在mouseenter或第一次mousemove事件上。区别在于鼠标在mouseenter和mouseexit之间的移动量要比两次mousemove事件之间的移动量大得多。因此,它看起来跳跃得不自然。

如何使其平滑滚动

要使它真正平滑滚动,您必须将CSS中的transition属性更改为大于0的值。例如,#stage {transition: 0.1s ease-in;}

回到绘图板

我不确定上面的解决方案是否是你想要的。你可能需要重新开始,考虑你的程序应该如何工作。例如,我可以想象你可能想要这样的东西:

  • 鼠标按下Enter键后,在接下来的1秒内,div应该显示为平滑滚动。
  • 否则,不应该有平滑的滚动。

我认为你可能需要用JavaScript而不是CSS来控制“平滑滚动行为”。否则当你在transition: 0.2s ease-intransition: 0s ease-in之间改变CSS时,div可能会奇怪地跳起来。
您可以尝试以下操作:

// add this somewhere at the top of your code
const stageNode = document.querySelector('#stage');
const msSmoothScrollingOnMouseEnter = 200; // milliseconds. Change this to what you like.

let hasMouseMoveEventFired = false;
let initialMouseMoveDate = new Date();

const getRemainingSmoothScrollingTime = () => {
  return Math.max(
    msSmoothScrollingOnMouseEnter - (new Date() - initialMouseMoveDate),
    0,
  ); // get milliseconds remaining for smooth scrolling
};

$(document).mouseenter(function () {
  initialMouseMoveDate = new Date();
});

$(document).mousemove(function (e) {
  if (!hasMouseMoveEventFired) {
    hasMouseMoveEventFired = true;
    initialMouseMoveDate = new Date();
  }
  const remainingMsSmoothScrollingTime = getRemainingSmoothScrollingTime();
  stageNode.style.transition = `${remainingSmoothScrollingTime / 1000}s linear`;
  // ... rest of the code goes here
});

mouseenter代码设置最后一次鼠标进入的时间。getRemainingSmoothScrollingTime函数返回平滑滚动剩余时间的毫秒数。mousemove处理函数将CSS中的transition属性更改为平滑滚动剩余时间的值。
编辑:修改了示例代码,以解决“第一次鼠标移动”的问题,而不是mouseenter和mouseexit的问题。编辑2:修复了代码中的一个错字。

相关问题