JS如何使用Math.atan2获取两点之间角度的实践案例
本文主要介绍使用如何实现手动拖拽旋转元素的效果。
1、简述
最近在研究如何实现手动控制元素的旋转效果,在网上找了很多,都没有找出类似的实现,因此经过一些调研和计算,最终完美实现效果,在这里记录下来。
2、效果展示
通过手动旋转的方式,实现组件的360度无缝旋转。图示是实现结果的几个截图:
0deg

顺时针转到
66deg

逆时针转到
315deg

转到
180deg

3、实现分析
如图所示,实现难点在于计算出两点间连线的倾斜角 angle

这里需要掌握的几个知识点:
3.1 获取转动的角度
使用 Math.atan2() 函数可以非常高效的实现之,它是返回点与原点之间的倾斜角,如图所示,如果想计算出点 (x1,y1) 与 原点 (cx,cy) 与X轴的角度,只需要执行:
Math.atan2(y1 - cy, x1 - cx)
需要注意的是,它的取值范围是[-PI, PI]。
当 (x1, y1) 在第一象限, 0 < θ < PI/2
当 (x1, y1) 在第二象限 PI/2 < θ≤PI
当 (x1, y1) 在第三象限, -PI < θ < -PI/2
当 (x1, y1) 在第四象限, -PI/2 < θ < 0
3.2 角度与弧度之间的转换
角度 = 弧度 * 180 / Math.PI;
弧度= 角度 * Math.PI / 180;
3.3 组件中心点位置计算
使用getBoundingClientRect() 的方法可以获取出容器的位置信息,用当前位置减去宽/高的一半,即可获取中心点位置。

//中心点
cx = x + width / 2;
cy = y + height / 2;
4、最终代码
/**
* 获得旋转夹角
* @param {*} x1 旋转点1
* @param {*} y1
* @param {*} x2 旋转点2
* @param {*} y2
*/
function getAngle(x1, y1, x2, y2) {
// 获取组件的位置信息
let rect = document.getElementsByClassName('active-ele')[0].getBoundingClientRect();
let {
x,
y,
width,
height
} = rect;
//中心点
let cx = x + width / 2;
let cy = y + height / 2;
//2个点之间的角度获取
let c1 = Math.atan2(y1 - cy, x1 - cx) * 180 / (Math.PI);
let c2 = Math.atan2(y2 - cy, x2 - cx) * 180 / (Math.PI);
let angle;
c1 = c1 <= -90 ? (360 + c1) : c1;
c2 = c2 <= -90 ? (360 + c2) : c2;
//夹角获取
angle = Math.floor(c2 - c1);
angle = angle < 0 ? angle + 360 : angle;
return angle;
}
/**
* 获得旋转夹角
* @param startPos.x 指的是初始位置的x坐标
* @param startPos.y 指的是初始位置的y坐标
* @param startPos.r 指的是初始的旋转角度
*/
let angle = getAngle(startPos.x, startPos.y, e.x, e.y);
let startAngle = startPos.r;
let deg;
// 赋值的旋转角度
let rotate;
// 顺时针旋转
if (e.x - startX > 0) {
deg = startAngle + angle;
rotate = deg > 360 ? deg - 360 : deg;
} else {
// 逆时针旋转
angle = 360 - angle;
deg = startAngle - angle;
rotate = deg < 0 ? deg + 360 : deg;
}
JS如何使用Math.atan2获取两点之间角度的实践案例的更多相关文章
- 转:Math: Math.atan() 与 Math.atan2() 计算两点间连线的夹角
我们可以使用正切操作将角度转变为斜率,那么怎样利用斜率来转换为角度呢?可以利用斜率的反正切函数将他转换为相应的角度.as中有两个函数可以计算反正切,我们来看一下. 1.Math.atan() Math ...
- arcgis for js 之 获取两点之间的距离
换了新公司,接触新行业,半路出家,看着别人的代码,看着api慢慢理解. 需求如下:已知两点坐标求距离. 思路,没有,站在同事的肩膀上踩路子,给的这个链接 https://developers.arcg ...
- JAVA通过经纬度获取两点之间的距离
private static double EARTH_RADIUS = 6378.137; private static double rad(double d) { return d * Math ...
- js通过经纬度计算两点之间的距离
最近这几天在做地图的时候,获取到目的地经纬度和当前所在位置的经纬度,通过这几个参数,用js代码就能获取到这两点之间的直线距离: function (lat1, lng1, lat2, lng2) { ...
- (转)c# math 计算两点之间的角度公式
计算两点之间的角度公式是: 假设点一(X1,Y1),点二(X2,Y2) double angleOfLine = Math.Atan2((Y2 - Y1), (X2 - X2)) * 180 / Ma ...
- js math atan2
在双十二活动中,视觉要求实现一个鼠标跟随运动的的效果,就像“觉”的那个效果类似 其实原理很简单,看鼠标从哪个方向进的及从哪个方向出的,然后区块里绝对定位的浮层就可以根据鼠标方向 运动; 如:在鼠标进入 ...
- 获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等)
如何获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等) 目标:使用百度定位sdk开发实时移动距离计算功能,根据经纬度的定位,计算行驶公里数并实时刷新界面显示.大家 ...
- js中的Math
js中的Math Math.round 取最接近的整数 Math.round(-2.7) // -3 Math.ceil 向上取整 Math.ceil(1.1) // 2 Math.floor 向下取 ...
- 数学API Math.atan() 和Math.atan2() 三角函数复习
今天在学习贝塞尔曲线看到需要结合三角函数 以及两个不认识的Api :API Math.atan() 和Math.atan2() 先看下三角函数 正切函数图:(180为一个周期 即45=45+180) ...
随机推荐
- Maven环境下面多项目之间的引用
如图: https://github.com/sdl/odata-example sdl OData例子包含了4个项目,下载到本地后编译.发现只有model项目是可以编译过去了.其他几个暂时编译不过 ...
- pip安装本地文件
I do a lot of development without an internet connection1, so being able to install packages into a ...
- 2019 CCPC-Wannafly Winter Camp Day7(Div2, onsite)
solve 6/11 补题: A.迷宫 Code:zz Thinking:zz kk 把每个节点的深度都处理出来,同一深度的点的冲突度为 (x-1),x为同层次点数减一. 然后冲突度不断下传(冲突度为 ...
- 创建djangoapp
1.python3 manage.py startapp goods 2.startapp users 3.启动django服务器 # make new migrationspython3 manag ...
- pandas数据清洗
1.我已安装好Anavonda3.5.所以我只用打开"jupyter notebook",然后打开浏览器 然后点击右侧的“new",然后打开python3
- How to Deinstall Oracle Clusterware Home Manually
###sample 0:安装GI 和DB soft 都成功,如何回退DB soft [opdb@pdbdb01:/db/db/app/db/product/11204/deinstall]$ ./de ...
- Oracle PL/SQL编程之包(packages)
1.简介 包用于在逻辑上组合过程和函数,它由包规范和包体组成. 我们可以使用create package来创建包,代码如下: ok,包创建完成,通过包的代码发现包的功能就是申明包中包含的过程和方法,红 ...
- selenium IDE 命令二(断言、验证、等待、变量)
测试用例需要做断言和验证,在seleniumIDE中提供了断言和验证来对结果进行比较 首先通过打开seleniumIDE,在页面任意一个元素右键,选择最后一个选项“show all available ...
- Eclipse取消或者关闭tomcat所有自动发布(部署)方法
1.设置publishing为Never publish automaticallu 2.modules->edit->auto reloading enabled 3.Windows & ...
- linux mint 18.1 安装nvidia显卡驱动
原文地址 http://www.gamersonlinux.com/forum/threads/updating-nvidia-drivers-mint.1746/ 主要步骤很简答 就是将ppa仓库地 ...