jjzjj

Javascript 移动元素与 mousemove 事件 60 FPS requestAnimationFrame

coder 2023-08-10 原文

那里!我在让 #drag 元素平滑移动方面遇到了问题。

我看这篇文章:http://www.html5rocks.com/en/tutorials/speed/animations/#debouncing-mouse-events

它说:“移动元素时 mousemove 事件的问题是 mousemove 事件触发过多

所以,我尝试使用他们的方法:使用 requestAnimationFrame + boolean checking

看看这个 fiddle 的现场表演:https://jsfiddle.net/5f181w9t/

HTML:

<div id="drag">this is draggable</div>

CSS:

#drag {width:100px; height:50px; background-color:red; transform:translate3d(0, 0, 0); }

JS:

var el               = document.getElementById("drag"),
    startPosition    = 0, // start position mousedown event
    currentPosition  = 0, // count current translateX value
    distancePosition = 0, // count distance between "down" & "move" event
    isMouseDown      = false; // check if mouse is down or not 

function mouseDown(e) {
    e.preventDefault(); // reset default behavior
    isMouseDown     = true;
    startPosition   = e.pageX; // get position X
    currentPosition = getTranslateX(); // get current translateX value
    requestAnimationFrame(update); // request 60fps animation
}    

function mouseMove(e) {
    e.preventDefault();
    distancePosition = (e.pageX - startPosition) + currentPosition; // count it!  
}

function mouseUp(e) {
    e.preventDefault();
    isMouseDown = false; // reset mouse is down boolean
}

function getTranslateX() {
   var translateX = parseInt(getComputedStyle(el, null).getPropertyValue("transform").split(",")[4]);

   return translateX; // get translateX value

}

function update() {
    if (isMouseDown) { // check if mouse is down
        requestAnimationFrame(update); // request 60 fps animation
    }
    el.style.transform = "translate3d(" + distancePosition + "px, 0, 0)";
  // move it!
}

el.addEventListener("mousedown", mouseDown);
document.addEventListener("mousemove", mouseMove);
document.addEventListener("mouseup", mouseUp);

这是完成它的正确方法吗?

我的代码有什么问题?

谢谢

最佳答案

问题是您在 mouseDown 事件监听器中使用了 requestAnimationFrame()。您应该在 mouseMove 事件监听器中进行所有更新,因为您希望在鼠标移动时而不是在鼠标单击时更新显示。因此,您应该在 update 函数中根据 isMouseDown 条件更新所有变量。我建议按如下方式更正代码。

HTML

<div id="drag">this is draggable</div>

CSS

#drag {
width:100px;
height:50px;
background-color:red;
transform:translateX(0);
}

JS

var el               = drag,
    startPosition    = 0, // start position mousedown event
    currentPosition  = 0, // count current translateX value
    distancePosition = 0, // count distance between "down" & "move" event
    isMouseDown      = false, // check if mouse is down or not
    needForRAF       = true;  // to prevent redundant rAF calls

function mouseDown(e) {
  e.preventDefault(); // reset default behavior
  isMouseDown     = true;
  currentPosition = getTranslateX(); // get current translateX value
  startPosition   = e.clientX; // get position X
}    

function mouseMove(e) {
    e.preventDefault();
  distancePosition = (e.clientX - startPosition) + currentPosition; // count it!  
  if (needForRAF && isMouseDown) {
    needForRAF = false;            // no need to call rAF up until next frame
    requestAnimationFrame(update); // request 60fps animation
  }; 
}

function mouseUp(e) {
  e.preventDefault();
  isMouseDown = false; // reset mouse is down boolean
}

function getTranslateX() {
  var translateX = parseInt(getComputedStyle(el, null).getPropertyValue("transform").split(",")[4]);
  return translateX; // get translateX value
}

function update() {
  needForRAF = true; // rAF now consumes the movement instruction so a new one can come
  el.style.transform = "translateX(" + distancePosition + "px)";// move it!
}

el.addEventListener("mousedown", mouseDown);
document.addEventListener("mousemove", mouseMove);
document.addEventListener("mouseup", mouseUp);

检查一下 here

关于Javascript 移动元素与 mousemove 事件 60 FPS requestAnimationFrame,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36098039/

有关Javascript 移动元素与 mousemove 事件 60 FPS requestAnimationFrame的更多相关文章

  1. ruby - 多次弹出/移动 ruby​​ 数组 - 2

    我的代码目前看起来像这样numbers=[1,2,3,4,5]defpop_threepop=[]3.times{pop有没有办法在一行中完成pop_three方法中的内容?我基本上想做类似numbers.slice(0,3)的事情,但要删除切片中的数组项。嗯...嗯,我想我刚刚意识到我可以试试slice! 最佳答案 是numbers.pop(3)或者numbers.shift(3)如果你想要另一边。 关于ruby-多次弹出/移动ruby​​数组,我们在StackOverflow上找到一

  2. ruby - 无法在 60 秒内获得稳定的 Firefox 连接 (127.0.0.1 :7055) - 2

    我使用的是Firefox版本36.0.1和Selenium-Webdrivergem版本2.45.0。我能够创建Firefox实例,但无法使用脚本继续进行进一步的操作无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055)错误。有人能帮帮我吗? 最佳答案 我遇到了同样的问题。降级到firefoxv33后一切正常。您可以找到旧版本here 关于ruby-无法在60秒内获得稳定的Firefox连接(127.0.0.1:7055),我们在StackOverflow上找到一个类

  3. ruby-on-rails - 如何重命名或移动 Rails 的 README_FOR_APP - 2

    当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?

  4. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  5. ruby-on-rails - 事件管理员日期过滤器日期格式自定义 - 2

    是否有简单的方法来更改默认ISO格式(yyyy-mm-dd)的ActiveAdmin日期过滤器显示格式? 最佳答案 您可以像这样为日期选择器提供额外的选项,而不是覆盖js:=f.input:my_date,as::datepicker,datepicker_options:{dateFormat:"mm/dd/yy"} 关于ruby-on-rails-事件管理员日期过滤器日期格式自定义,我们在StackOverflow上找到一个类似的问题: https://s

  6. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  7. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  8. ruby-on-rails - 事件记录 : Select max of limit - 2

    我正在尝试将以下SQL查询转换为ActiveRecord,它正在融化我的大脑。deletefromtablewhereid有什么想法吗?我想做的是限制表中的行数。所以,我想删除少于最近10个条目的所有内容。编辑:通过结合以下几个答案找到了解决方案。Temperature.where('id这给我留下了最新的10个条目。 最佳答案 从您的SQL来看,您似乎想要从表中删除前10条记录。我相信到目前为止的大多数答案都会如此。这里有两个额外的选择:基于MurifoX的版本:Table.where(:id=>Table.order(:id).

  9. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

  10. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

随机推荐