本文主要介绍使用如何实现手动拖拽旋转元素的效果。

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获取两点之间角度的实践案例的更多相关文章

  1. 转:Math: Math.atan() 与 Math.atan2() 计算两点间连线的夹角

    我们可以使用正切操作将角度转变为斜率,那么怎样利用斜率来转换为角度呢?可以利用斜率的反正切函数将他转换为相应的角度.as中有两个函数可以计算反正切,我们来看一下. 1.Math.atan() Math ...

  2. arcgis for js 之 获取两点之间的距离

    换了新公司,接触新行业,半路出家,看着别人的代码,看着api慢慢理解. 需求如下:已知两点坐标求距离. 思路,没有,站在同事的肩膀上踩路子,给的这个链接 https://developers.arcg ...

  3. JAVA通过经纬度获取两点之间的距离

    private static double EARTH_RADIUS = 6378.137; private static double rad(double d) { return d * Math ...

  4. js通过经纬度计算两点之间的距离

    最近这几天在做地图的时候,获取到目的地经纬度和当前所在位置的经纬度,通过这几个参数,用js代码就能获取到这两点之间的直线距离: function (lat1, lng1, lat2, lng2) { ...

  5. (转)c# math 计算两点之间的角度公式

    计算两点之间的角度公式是: 假设点一(X1,Y1),点二(X2,Y2) double angleOfLine = Math.Atan2((Y2 - Y1), (X2 - X2)) * 180 / Ma ...

  6. js math atan2

    在双十二活动中,视觉要求实现一个鼠标跟随运动的的效果,就像“觉”的那个效果类似 其实原理很简单,看鼠标从哪个方向进的及从哪个方向出的,然后区块里绝对定位的浮层就可以根据鼠标方向 运动; 如:在鼠标进入 ...

  7. 获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等)

    如何获取经纬度之间两点间真实距离(适用于GoogleMap,BaiduMap,Amap等)  目标:使用百度定位sdk开发实时移动距离计算功能,根据经纬度的定位,计算行驶公里数并实时刷新界面显示.大家 ...

  8. js中的Math

    js中的Math Math.round 取最接近的整数 Math.round(-2.7) // -3 Math.ceil 向上取整 Math.ceil(1.1) // 2 Math.floor 向下取 ...

  9. 数学API Math.atan() 和Math.atan2() 三角函数复习

    今天在学习贝塞尔曲线看到需要结合三角函数 以及两个不认识的Api :API Math.atan() 和Math.atan2() 先看下三角函数 正切函数图:(180为一个周期 即45=45+180) ...

随机推荐

  1. 2016级算法第三次上机-D.双十一的抉择

    915 双十一的抉择 思路 中等题.简化题目:一共n个数,分成两组,使得两组的差最接近0,就是说要使两组数都尽可能的接近sum/2. 思路还是很混乱的,不知道如何下手,暴力也挺难的,还不能保证对.想一 ...

  2. maven项目报错

    [root@kube-master iff]# kubectl logs iff-dm-3029278244-9qrp6 -n iffjava.lang.IllegalArgumentExceptio ...

  3. Bad Smell (代码的坏味道)

    sourcemaking 如果一段代码是不稳定或者有一些潜在问题的,那么代码往往会包含一些明显的痕迹.正如食物要腐坏之前,经常会发出一些异味一样, 我们管这些痕迹叫做 "代码异味" ...

  4. eclipse 远程debug

    [环境参数] Eclipse:Version: Mars.2 Release (4.5.2) Linux:centOS 6.5 [简述] Java自身支持调试功能,并提供了一个简单的调试工具--JDB ...

  5. DB link的迁移

    我们在做某些Schema的迁移的时候,由于用到Public的db link,然而由于不知道db link中目标端账号的密码,因此无法在新环境重新创建DB link. 本次实验的思路是将视图dba_db ...

  6. Java_break与continue区别

    使用场合不同 break:可以在switch case中使用,也可以在循环中使用   continue:只能在循环中使用,除了switch case 作用不同 break:表示中断,当在switch ...

  7. Python学习-基础知识-2

    目录 Python基础知识2 一.二进制 二.文字编码-基础 为什么要有文字编码? 有哪些编码格式? 如何解决不同国家不兼容的编码格式? unicode编码格式的缺点 如何既能全球通用还可以规避uni ...

  8. (转)heartbeat原理及部署

    原文:http://yjy724.blog.51cto.com/10897133/1840794---------------------------------------------------h ...

  9. centos 7编译安装php7

    0.下载php源代码 http://www.php.net/releases/ 1.配置编译环境 yum install -y gcc gcc++ libxml2-devel openssl open ...

  10. 使用jquery处理数据时要注意的问题

    现在的网站越来越重视用户体验,网站必须即时反应,前端技术越来越重要了,以前我们都用javascript,后来出现了很多js的框架,调用起来也很方便,但是随着网页上加载的数据越来越多,使用jquery的 ...