罗田县升平网络工作室,一家专业从事网站建设的工作室

资讯论坛

 找回密码
 加入论坛

快捷登录

回帖中禁止出现的内容,违者将被直接永久禁止访问,删除ID处理 :1.违反法律法规 ,包括但不限于出现带有政治、色情、暴恐信息等内容;2.恶意攻击内容,包括但不限于:恶意攻击党和政府、辱骂跟帖者、攻击主题发布者、不服从论坛管理、挑衅管理者、挑战版规等;3.广告、推广内容,尤其出现带有病毒、恶意代码、广告链接等内容,包括但不限于:QQ号、文字QQ号、微信号、手机号、文字手机号、第三方网址、单位公司名称、网站名称等;4.回帖贴出该主题隐藏资源链接或其它主题隐藏资源链接的行为。
查看: 772|回复: 0

js实现拖动缓动效果

[复制链接]

698

主题

677

帖子

765

积分

社区达人

积分
765
发表于 2020-1-20 06:54:24 来自手机 | 显示全部楼层 |阅读模式
话不多说,先上效果,一个体验非常好的拖拽缓动的效果,让页面提升一个档次。
065437kn3x7ha5kb7exekr.gif

这个效果看似很简单,到也困惑了很长时间,为什么别人写出来的拖拽体验为什么这么好?
直到我自己实现了以后,才发现,原来我想的实现方式不对。接下来,我通过简短的几句话,来提供这个功能的实现思路。
首先,我们要明白,我们鼠标拖拽是在一个2d平面上拖拽
2d平面只有x轴和y轴,而且获取的拖拽值也是基于平面的像素获取的。所以,我们第一步,先通过鼠标事件来获取到当前的拖拽的长度像素。
首先,绑定鼠标按下事件,来获取到鼠标基于浏览器窗口左上角的xy平面二维坐标。
然后,绑定move事件,在move事件回调内获取到鼠标拖拽的坐标,和按下坐标相减,求出拖拽的距离。
然后,我们需要通过一定比例,将拖拽的像素转换为旋转角度
我这里设置的比例是,
鼠标横向拖拽10像素,那模型沿3d的Y轴坐标就旋转5度,
鼠标纵向拖拽10像素,模型沿3d世界的X轴坐标旋转1度,并且还设置了范围,即沿x轴旋转再-45度到45度之间
  1. function onDocumentMouseMove(event) {    mouseX = event.clientX;    mouseY = event.clientY;    targetRotationX = targetRotationOnMouseDownX + (mouseX - mouseXOnMouseDownX) * 0.5;    targetRotationY = Math.min(Math.max((targetRotationOnMouseDownY - (mouseY - mouseXOnMouseDownY) * 0.1), -45), 45); //拖拽后的目标位置  }
复制代码
上面获取到目标角度,重点来了,如何实现惰性旋转呢?
通过上面思路,我们知道了目标角度,那么直接设置目标角度,肯定就没有这种想要的效果了,那么如何实现这种惰性效果呢?
接下来,我们需要一个专门实现动画的requestAnimationFrame方法,这个方法是闲时运行,最大根据性能能够达到60帧每秒,有好多小伙伴感觉一直递归运行会不会卡顿,或者影响性能。那是你多虑了,这个方法会根据当前页面性能进行减帧,保证页面流畅运行。
我们有了这个以后,然后做什么呢,就是用来实现缓动,在每一帧里面,获取到目标角度和当前角度的角度差,然后每一次只选择总进度的百分之10 ,然后你会发现选择离目标角度越近,越慢,体验效果也是非常的棒。
而且在运行中,角度也会无限制的接近目标角度,当前demo是通过css3d来实现的:
  1. function animate() {    requestAnimationFrame(animate);    rotateY += (targetRotationX - rotateY) * 0.1;    rotateX += (targetRotationY - rotateX) * 0.1;    box.style.transform = 'rotateY(' + rotateY + 'deg)';    item.style.transform = 'rotateX(' + rotateX + 'deg)';  }
复制代码
案例全部代码
  1. <!DOCTYPE html><html lang="zh"><head>  <meta charset="UTF-8">  <title>css3d翻转</title>  <style>    * {      padding: 0;      margin: 0;    }    body {      display: flex;      justify-content: center;      align-items: center;      height: 100vh;      overflow: hidden;      perspective: 1000px;    }    .item {      width: 50vw;      height: 50vh;      transform: rotateX(-50deg);      perspective: 5000px;      transform-style: preserve-3d;    }    .box {      background: #abb9c5;      width: 100%;      height: 100%;      transform-style: preserve-3d;      position: relative;    }    .font,    .back {      position: absolute;      top: 0;      left: 0;      width: 100%;      height: 100%;      text-align: center;      line-height: 50vh;      background: #4cae4c;      backface-visibility: hidden;    }    .back {      background: #62ebff;      transform: rotateY(180deg);    }  </style></head><body>  <!--item 可以触发翻转的区域-->  <div class="item">    <!--box 可以翻转的容器-->    <div class="box">      <!--font 默认显示的正面-->      <div class="font">正面</div>      <!--back 背面-->      <div class="back">背面</div>    </div>  </div></body><script>  var targetRotationX = 0;  var targetRotationY = 0;  var targetRotationOnMouseDownX = 0;  var targetRotationOnMouseDownY = 0;  var mouseX = 0;  var mouseY = 0;  var mouseXOnMouseDownX = 0;  var mouseXOnMouseDownY = 0;  var box = document.querySelector('.box');  var item = document.querySelector('.item');  var rotateY = 0;  var rotateX = 0;  init();  animate();  function init() {    // EVENTS    document.addEventListener('mousedown', onDocumentMouseDown, false);    document.addEventListener('touchstart', onDocumentTouchStart, false);    document.addEventListener('touchmove', onDocumentTouchMove, false);  }  function onDocumentMouseDown(event) {    event.preventDefault();    document.addEventListener('mousemove', onDocumentMouseMove, false);    document.addEventListener('mouseup', onDocumentMouseUp, false);    mouseXOnMouseDownX = event.clientX;    mouseXOnMouseDownY = event.clientY;    targetRotationOnMouseDownX = targetRotationX;    targetRotationOnMouseDownY = targetRotationY;  }  function onDocumentMouseMove(event) {    mouseX = event.clientX;    mouseY = event.clientY;    targetRotationX = targetRotationOnMouseDownX + (mouseX - mouseXOnMouseDownX) * 0.5;    targetRotationY = Math.min(Math.max((targetRotationOnMouseDownY - (mouseY - mouseXOnMouseDownY) * 0.1), -45), 45); //拖拽后的目标位置  }  function onDocumentMouseUp() {    document.removeEventListener('mousemove', onDocumentMouseMove, false);    document.removeEventListener('mouseup', onDocumentMouseUp, false);  }  function onDocumentTouchStart(event) {    event.preventDefault();    if (event.touches.length === 1) {      mouseXOnMouseDownX = event.touches[0].pageX;      mouseXOnMouseDownY = event.touches[0].pageY;      targetRotationOnMouseDownX = targetRotationX;      targetRotationOnMouseDownY = targetRotationY;    }  }  function onDocumentTouchMove(event) {    event.preventDefault();    if (event.touches.length === 1) {      mouseX = event.touches[0].pageX;      mouseY = event.touches[0].pageY;      targetRotationX = targetRotationOnMouseDownX + (mouseX - mouseXOnMouseDownX) * 0.5;      targetRotationY = Math.min(Math.max((targetRotationOnMouseDownY - (mouseY - mouseXOnMouseDownY) * 0.1), -45), 45); //拖拽后的目标位置    }  }  function animate() {    requestAnimationFrame(animate);    rotateY += (targetRotationX - rotateY) * 0.1;    rotateX += (targetRotationY - rotateX) * 0.1;    box.style.transform = 'rotateY(' + rotateY + 'deg)';    item.style.transform = 'rotateX(' + rotateX + 'deg)';  }</script></html>
复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

来源:http://www.jb51.net/article/178300.htm
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
打赏鼓励一下!
回复

使用道具 举报

回帖中禁止出现的内容,违者将被直接永久禁止访问,删除ID处理 :1.违反法律法规 ,包括但不限于出现带有政治、色情、暴恐信息等内容;2.恶意攻击内容,包括但不限于:恶意攻击党和政府、辱骂跟帖者、攻击主题发布者、不服从论坛管理、挑衅管理者、挑战版规等;3.广告、推广内容,尤其出现带有病毒、恶意代码、广告链接等内容,包括但不限于:QQ号、文字QQ号、微信号、手机号、文字手机号、第三方网址、单位公司名称、网站名称等;4.回帖贴出该主题隐藏资源链接或其它主题隐藏资源链接的行为。

浏览排行

(40335)2019-11-5 公共云钱包资金盘骗局揭秘: 网络传销+原始股骗局合体!

(23451)2019-12-20 12月17日 邓智天法院直播庭审疑问全解答!

(22051)2019-12-1 环保币GEC资金盘骗局最新消息: 即将崩盘!

(18277)2019-11-9 巨胸肥臀大长腿,嫩模糯美子真人COS不知火舞福利污图

(16859)2018-12-24 罗田县人民法院公布【第五批失信被执行人名单】 ...

(16052)2019-11-3 曝光!PTFX已经崩盘跑路,投资者血流成河!

(14114)2019-8-7 湖北电力网上缴费,支付宝绑定户号的初始密码是什么?

(13841)2018-10-17 罗田县人民政府“12345”市民服务热线服务指南

(12192)2019-12-11 公安定性了, 趣码是非法传销! 趣码怎么退回365元?

(12006)2019-12-15 满足你对女同事的幻想 风骚秘书阿朱销魂眼神勾魂摄魄

最新发表

[升平网络工作室]2026-4-23 周黎主持召开城市工作调研会

[升平网络工作室]2026-4-23 [2026-04-23]罗田天气预报

[升平网络工作室]2026-4-22 周黎调研城区重点项目建设工作

[升平网络工作室]2026-4-22 [2026-04-22]罗田天气预报

[升平网络工作室]2026-4-21 罗田县气象局关于开展2026年度雷电防护装置安全性能定期检测的公告

[升平网络工作室]2026-4-21 2026罗田春季全民健康跑圆满举行

[升平网络工作室]2026-4-21 [2026-04-21]罗田天气预报

[升平网络工作室]2026-4-20 罗田县政府招商组举行2026年招商引资工作推进会

[升平网络工作室]2026-4-20 [2026-04-20]罗田天气预报

[升平网络工作室]2026-4-19 罗田县政协召开十一届常委会第二十三次会议

QQ|Archiver|手机版|小黑屋|资讯论坛BBS.SPW8.CN ( 鄂ICP备2021011341号-3 )|网站地图


手机扫一扫继续访问
[免责声明]
本站系本网编辑转载,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。
如涉及作品内容、版权和其它问题,请在30日内与本网联系,我们将在第一时间删除内容!
[声明]本站文章版权归原作者所有 内容为作者个人观点 本站只提供参考并不构成任何投资及应用建议。

进入社区 | 发表新帖 | 百度收录 |
技术提供:罗田县升平网络工作室
站长Email:kefu@spw8.cn
投诉电话(刮开查看):15374567400

GMT+8, 2026-4-24 00:05 , Processed in 0.486787 second(s), 34 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表