wangrong
2026-08-30 4c949c0dc9bcae785c281c9d8125295f09810b15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import { divide, multiply, floor } from 'mathjs'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { storeToRefs } from 'pinia'
 
const dvMainStore = dvMainStoreWithOut()
const { canvasStyleData } = storeToRefs(dvMainStore)
 
// 角度转弧度
// Math.PI = 180 度
function angleToRadian(angle) {
  return (angle * Math.PI) / 180
}
 
/**
 * 计算根据圆心旋转后的点的坐标
 * @param   {Object}  point  旋转前的点坐标
 * @param   {Object}  center 旋转中心
 * @param   {Number}  rotate 旋转的角度
 * @return  {Object}         旋转后的坐标
 * https://www.zhihu.com/question/67425734/answer/252724399 旋转矩阵公式
 */
export function calculateRotatedPointCoordinate(point, center, rotate) {
  /**
   * 旋转公式:
   *  点a(x, y)
   *  旋转中心c(x, y)
   *  旋转后点n(x, y)
   *  旋转角度θ                tan ??
   * nx = cosθ * (ax - cx) - sinθ * (ay - cy) + cx
   * ny = sinθ * (ax - cx) + cosθ * (ay - cy) + cy
   */
 
  return {
    x:
      (point.x - center.x) * Math.cos(angleToRadian(rotate)) -
      (point.y - center.y) * Math.sin(angleToRadian(rotate)) +
      center.x,
    y:
      (point.x - center.x) * Math.sin(angleToRadian(rotate)) +
      (point.y - center.y) * Math.cos(angleToRadian(rotate)) +
      center.y
  }
}
 
/**
 * 获取旋转后的点坐标(八个点之一)
 * @param  {Object} style  样式
 * @param  {Object} center 组件中心点
 * @param  {String} name   点名称
 * @return {Object}        旋转后的点坐标
 */
export function getRotatedPointCoordinate(style, center, name) {
  let point // point 是未旋转前的坐标
  switch (name) {
    case 't':
      point = {
        x: style.left + style.width / 2,
        y: style.top
      }
 
      break
    case 'b':
      point = {
        x: style.left + style.width / 2,
        y: style.top + style.height
      }
 
      break
    case 'l':
      point = {
        x: style.left,
        y: style.top + style.height / 2
      }
 
      break
    case 'r':
      point = {
        x: style.left + style.width,
        y: style.top + style.height / 2
      }
 
      break
    case 'lt':
      point = {
        x: style.left,
        y: style.top
      }
 
      break
    case 'rt':
      point = {
        x: style.left + style.width,
        y: style.top
      }
 
      break
    case 'lb':
      point = {
        x: style.left,
        y: style.top + style.height
      }
 
      break
    default: // rb
      point = {
        x: style.left + style.width,
        y: style.top + style.height
      }
 
      break
  }
 
  return calculateRotatedPointCoordinate(point, center, style.rotate)
}
 
// 求两点之间的中点坐标
export function getCenterPoint(p1, p2) {
  return {
    x: p1.x + (p2.x - p1.x) / 2,
    y: p1.y + (p2.y - p1.y) / 2
  }
}
 
export function sin(rotate) {
  return Math.abs(Math.sin(angleToRadian(rotate)))
}
 
export function cos(rotate) {
  return Math.abs(Math.cos(angleToRadian(rotate)))
}
 
export function mod360(deg) {
  return (deg + 360) % 360
}
 
export function changeStyleWithScale(value, scale = canvasStyleData.value.scale) {
  return floor(multiply(value, divide(parseInt(scale + ''), 100)))
}
 
export function toPercent(val) {
  return val * 100 + '%'
}