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

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. 高阶篇:4.2.1)DFMEA框架搭建,填写项目与要求

    本章目的:明确DFMEA的数量及目标,搭建框架,填写项目与要求. 1.步骤: 1)明确DFMEA的数量及目标: 2)搭建框架(所有DFMEA的): 3)填写项目与要求: 2.1明确DFMEA的数量及目 ...

  2. flutter dup get

    有很多 flutter library 中有两种导入方式 with dup: dup get 这种导入方式是需要依赖于 Dart SDK 下载 Dart SDK 地址:http://www.gekor ...

  3. 移动APP的用户体验测试

    经常被问到用户体验测试,什么是用户体验测试,用户体验测试要关注的都有哪些呢,现在为大家来罗列一下: 1.横竖屏测试 在移动设备上做用户体验测试,最容易想到的就是对APP做横竖屏的测试来观察APP的显示 ...

  4. Which mb sdconnect c4 worth the money?

    MB SD connect C4 with laptop v2018.5 Version avaiable now ,It is ready to work after you get it ,wor ...

  5. 2.6 Go 读取CSV

    Go读取CSV文件,其内容被转换成字符串数组 package main import ( "encoding/csv" "fmt" "io/iouti ...

  6. 899. Orderly Queue

    A string S of lowercase letters is given.  Then, we may make any number of moves. In each move, we c ...

  7. 《大数据日知录》读书笔记-ch15机器学习:范型与架构

    机器学习算法特点:迭代运算 损失函数最小化训练过程中,在巨大参数空间中迭代寻找最优解 比如:主题模型.回归.矩阵分解.SVM.深度学习 分布式机器学习的挑战: - 网络通信效率 - 不同节点执行速度不 ...

  8. Sql数据库收缩 语句特别快

    数据库在收缩的时候..使用菜单 >> 任务 >> 收缩 >> 文件 >> 数据,  特别慢..还会报错失败.. 但使用脚本 USE [dbName] G ...

  9. (转)Apache和Nginx运行原理解析

    Apache和Nginx运行原理解析 原文:https://www.server110.com/nginx/201402/6543.html Web服务器 Web服务器也称为WWW(WORLD WID ...

  10. centos 7编译安装nginx

    一.安装nginx时必须先安装相应的编译工具yum -y install gcc gcc-c++ autoconf automakeyum -y install zlib zlib-devel ope ...