| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485 |
- import { OPERATE_KEYS } from '@/types/edit'
- // 给定一个坐标,计算该坐标到(0, 0)点连线的弧度值
- // 注意,Math.atan2的一般用法是Math.atan2(y, x)返回的是原点(0,0)到(x,y)点的线段与X轴正方向之间的弧度值
- // 这里将使用时将x与y的传入顺序交换了,为的是获取原点(0,0)到(x,y)点的线段与Y轴正方向之间的弧度值
- export const getAngleFromCoordinate = (x: number, y: number) => {
- const radian = Math.atan2(x, y)
- const angle = 180 / Math.PI * radian
- return angle
- }
- // 计算元素被旋转一定角度后,八个操作点的新坐标
- interface RotateElementData {
- left: number;
- top: number;
- width: number;
- height: number;
- }
- export const getRotateElementPoints = (element: RotateElementData, angle: number) => {
- const { left, top, width, height } = element
- const radius = Math.sqrt( Math.pow(width, 2) + Math.pow(height, 2) ) / 2
- const auxiliaryAngle = Math.atan(height / width) * 180 / Math.PI
- const tlbraRadian = (180 - angle - auxiliaryAngle) * Math.PI / 180
- const trblaRadian = (auxiliaryAngle - angle) * Math.PI / 180
- const taRadian = (90 - angle) * Math.PI / 180
- const raRadian = angle * Math.PI / 180
- const halfWidth = width / 2
- const halfHeight = height / 2
- const middleLeft = left + halfWidth
- const middleTop = top + halfHeight
- const leftTopPoint = {
- left: middleLeft + radius * Math.cos(tlbraRadian),
- top: middleTop - radius * Math.sin(tlbraRadian),
- }
- const topPoint = {
- left: middleLeft + halfHeight * Math.cos(taRadian),
- top: middleTop - halfHeight * Math.sin(taRadian),
- }
- const rightTopPoint = {
- left: middleLeft + radius * Math.cos(trblaRadian),
- top: middleTop - radius * Math.sin(trblaRadian),
- }
- const rightPoint = {
- left: middleLeft + halfWidth * Math.cos(raRadian),
- top: middleTop + halfWidth * Math.sin(raRadian),
- }
- const rightBottomPoint = {
- left: middleLeft - radius * Math.cos(tlbraRadian),
- top: middleTop + radius * Math.sin(tlbraRadian),
- }
- const bottomPoint = {
- left: middleLeft - halfHeight * Math.sin(raRadian),
- top: middleTop + halfHeight * Math.cos(raRadian),
- }
- const leftBottomPoint = {
- left: middleLeft - radius * Math.cos(trblaRadian),
- top: middleTop + radius * Math.sin(trblaRadian),
- }
- const leftPoint = {
- left: middleLeft - halfWidth * Math.cos(raRadian),
- top: middleTop - halfWidth * Math.sin(raRadian),
- }
- return { leftTopPoint, topPoint, rightTopPoint, rightPoint, rightBottomPoint, bottomPoint, leftBottomPoint, leftPoint }
- }
- // 获取元素某个操作点对角线上另一端的操作点坐标(例如:左上 <-> 右下)
- export const getOppositePoint = (direction: number, points: ReturnType<typeof getRotateElementPoints>): { left: number; top: number } => {
- const oppositeMap = {
- [OPERATE_KEYS.RIGHT_BOTTOM]: points.leftTopPoint,
- [OPERATE_KEYS.LEFT_BOTTOM]: points.rightTopPoint,
- [OPERATE_KEYS.LEFT_TOP]: points.rightBottomPoint,
- [OPERATE_KEYS.RIGHT_TOP]: points.leftBottomPoint,
- [OPERATE_KEYS.TOP]: points.bottomPoint,
- [OPERATE_KEYS.BOTTOM]: points.topPoint,
- [OPERATE_KEYS.LEFT]: points.rightPoint,
- [OPERATE_KEYS.RIGHT]: points.leftPoint,
- }
- return oppositeMap[direction]
- }
|