@363045841yyt/klinechart-core 0.7.3 → 0.7.5-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (231) hide show
  1. package/README.md +201 -201
  2. package/README.zh-CN.md +201 -201
  3. package/dist/engine/renderers/webgl/candleSurface.js +47 -47
  4. package/dist/version.d.ts +1 -1
  5. package/dist/version.d.ts.map +1 -1
  6. package/dist/version.js +1 -2
  7. package/dist/version.js.map +1 -1
  8. package/package.json +129 -122
  9. package/src/__tests__/signal.test.ts +124 -124
  10. package/src/config/chartSettings.ts +66 -66
  11. package/src/controllers/__tests__/drawing.test.ts +214 -214
  12. package/src/controllers/__tests__/indicatorSelector.test.ts +481 -481
  13. package/src/controllers/__tests__/toolbar.test.ts +225 -225
  14. package/src/controllers/createChartController.ts +665 -665
  15. package/src/controllers/createDrawingController.ts +96 -96
  16. package/src/controllers/createIndicatorSelectorController.ts +307 -307
  17. package/src/controllers/createToolbarController.ts +146 -146
  18. package/src/controllers/index.ts +19 -19
  19. package/src/controllers/types.ts +284 -284
  20. package/src/engine/__tests__/chart.dpr.test.ts +401 -401
  21. package/src/engine/__tests__/paneRenderer.resize.test.ts +92 -92
  22. package/src/engine/chart-store.ts +121 -121
  23. package/src/engine/chart.d.ts +617 -617
  24. package/src/engine/chart.ts +2815 -2815
  25. package/src/engine/controller/__tests__/interaction.dpr.test.ts +259 -259
  26. package/src/engine/controller/interaction.ts +722 -722
  27. package/src/engine/controller/markerInteraction.ts +130 -130
  28. package/src/engine/controller/pinchTracker.ts +82 -82
  29. package/src/engine/controller/tooltipPosition.ts +48 -48
  30. package/src/engine/draw/__tests__/pixelAlign.spec.ts +176 -176
  31. package/src/engine/draw/pixelAlign.ts +259 -259
  32. package/src/engine/drawing/index.ts +655 -655
  33. package/src/engine/drawing/interaction.ts +842 -842
  34. package/src/engine/drawing/plugin.ts +343 -343
  35. package/src/engine/indicators/__tests__/__fixtures__/golden/atr.json +38 -38
  36. package/src/engine/indicators/__tests__/__fixtures__/golden/dema.json +14 -14
  37. package/src/engine/indicators/__tests__/__fixtures__/golden/hma.json +14 -14
  38. package/src/engine/indicators/__tests__/__fixtures__/golden/index.ts +55 -55
  39. package/src/engine/indicators/__tests__/__fixtures__/golden/kama.json +14 -14
  40. package/src/engine/indicators/__tests__/__fixtures__/golden/tema.json +14 -14
  41. package/src/engine/indicators/__tests__/__fixtures__/golden/wma.json +40 -40
  42. package/src/engine/indicators/__tests__/__fixtures__/synthetic.ts +65 -65
  43. package/src/engine/indicators/__tests__/_propertyAssertions.ts +76 -76
  44. package/src/engine/indicators/__tests__/atr.test.ts +153 -153
  45. package/src/engine/indicators/__tests__/calculators.test.ts +614 -614
  46. package/src/engine/indicators/__tests__/cmf-mfi.test.ts +100 -100
  47. package/src/engine/indicators/__tests__/dema.test.ts +73 -73
  48. package/src/engine/indicators/__tests__/donchian.test.ts +70 -70
  49. package/src/engine/indicators/__tests__/hma.test.ts +73 -73
  50. package/src/engine/indicators/__tests__/ichimoku.test.ts +105 -105
  51. package/src/engine/indicators/__tests__/kama.test.ts +80 -80
  52. package/src/engine/indicators/__tests__/keltner.test.ts +65 -65
  53. package/src/engine/indicators/__tests__/pivot-fib.test.ts +110 -110
  54. package/src/engine/indicators/__tests__/roc.test.ts +68 -68
  55. package/src/engine/indicators/__tests__/sar.test.ts +86 -86
  56. package/src/engine/indicators/__tests__/scheduler.test.ts +831 -831
  57. package/src/engine/indicators/__tests__/soa.test.ts +533 -533
  58. package/src/engine/indicators/__tests__/structure.test.ts +110 -110
  59. package/src/engine/indicators/__tests__/supertrend.test.ts +65 -65
  60. package/src/engine/indicators/__tests__/tema.test.ts +68 -68
  61. package/src/engine/indicators/__tests__/trix.test.ts +70 -70
  62. package/src/engine/indicators/__tests__/volatility.test.ts +117 -117
  63. package/src/engine/indicators/__tests__/volume.test.ts +115 -115
  64. package/src/engine/indicators/__tests__/volumeProfile.test.ts +74 -74
  65. package/src/engine/indicators/__tests__/vwap.test.ts +69 -69
  66. package/src/engine/indicators/__tests__/wma.test.ts +112 -112
  67. package/src/engine/indicators/__tests__/zones.test.ts +95 -95
  68. package/src/engine/indicators/atrState.ts +27 -27
  69. package/src/engine/indicators/bollState.ts +51 -51
  70. package/src/engine/indicators/calculators.ts +2593 -2593
  71. package/src/engine/indicators/cciState.ts +25 -25
  72. package/src/engine/indicators/chaikinVolState.ts +32 -32
  73. package/src/engine/indicators/cmfState.ts +27 -27
  74. package/src/engine/indicators/demaState.ts +27 -27
  75. package/src/engine/indicators/donchianState.ts +43 -43
  76. package/src/engine/indicators/eneState.ts +43 -43
  77. package/src/engine/indicators/expmaState.ts +43 -43
  78. package/src/engine/indicators/fastkState.ts +25 -25
  79. package/src/engine/indicators/fibState.ts +41 -41
  80. package/src/engine/indicators/hmaState.ts +27 -27
  81. package/src/engine/indicators/hvState.ts +28 -28
  82. package/src/engine/indicators/ichimokuState.ts +70 -70
  83. package/src/engine/indicators/indicator.worker.ts +169 -169
  84. package/src/engine/indicators/indicatorDefinitionRegistry.ts +62 -62
  85. package/src/engine/indicators/indicatorMetadata.ts +110 -110
  86. package/src/engine/indicators/indicatorRegistry.ts +106 -106
  87. package/src/engine/indicators/indicatorRuntime.ts +1548 -1548
  88. package/src/engine/indicators/kamaState.ts +34 -34
  89. package/src/engine/indicators/keltnerState.ts +49 -49
  90. package/src/engine/indicators/kstState.ts +42 -42
  91. package/src/engine/indicators/maState.ts +36 -36
  92. package/src/engine/indicators/macdState.ts +76 -76
  93. package/src/engine/indicators/mfiState.ts +27 -27
  94. package/src/engine/indicators/momState.ts +25 -25
  95. package/src/engine/indicators/obvState.ts +25 -25
  96. package/src/engine/indicators/parkinsonState.ts +28 -28
  97. package/src/engine/indicators/pivotState.ts +51 -51
  98. package/src/engine/indicators/pvtState.ts +25 -25
  99. package/src/engine/indicators/rocState.ts +27 -27
  100. package/src/engine/indicators/rsiState.ts +65 -65
  101. package/src/engine/indicators/sarState.ts +41 -41
  102. package/src/engine/indicators/scheduler.ts +1205 -1205
  103. package/src/engine/indicators/soa.ts +352 -352
  104. package/src/engine/indicators/stateComposer.ts +1262 -1262
  105. package/src/engine/indicators/stochState.ts +26 -26
  106. package/src/engine/indicators/structureState.ts +69 -69
  107. package/src/engine/indicators/supertrendState.ts +37 -37
  108. package/src/engine/indicators/temaState.ts +27 -27
  109. package/src/engine/indicators/trixState.ts +35 -35
  110. package/src/engine/indicators/vmaState.ts +27 -27
  111. package/src/engine/indicators/volumeProfileState.ts +63 -63
  112. package/src/engine/indicators/vwapState.ts +29 -29
  113. package/src/engine/indicators/wmaState.ts +27 -27
  114. package/src/engine/indicators/wmsrState.ts +25 -25
  115. package/src/engine/indicators/workerProtocol.ts +613 -613
  116. package/src/engine/indicators/zonesState.ts +47 -47
  117. package/src/engine/layout/pane.ts +161 -161
  118. package/src/engine/marker/registry.ts +265 -265
  119. package/src/engine/paneRenderer.ts +169 -169
  120. package/src/engine/renderers/Indicator/atr.ts +237 -237
  121. package/src/engine/renderers/Indicator/boll.ts +317 -317
  122. package/src/engine/renderers/Indicator/cci.ts +275 -275
  123. package/src/engine/renderers/Indicator/chaikinVol.ts +138 -138
  124. package/src/engine/renderers/Indicator/cmf.ts +137 -137
  125. package/src/engine/renderers/Indicator/dema.ts +136 -136
  126. package/src/engine/renderers/Indicator/donchian.ts +137 -137
  127. package/src/engine/renderers/Indicator/ene.ts +271 -271
  128. package/src/engine/renderers/Indicator/expma.ts +197 -197
  129. package/src/engine/renderers/Indicator/fastk.ts +316 -316
  130. package/src/engine/renderers/Indicator/fib.ts +141 -141
  131. package/src/engine/renderers/Indicator/hma.ts +136 -136
  132. package/src/engine/renderers/Indicator/hv.ts +124 -124
  133. package/src/engine/renderers/Indicator/ichimoku.ts +181 -181
  134. package/src/engine/renderers/Indicator/index.ts +241 -241
  135. package/src/engine/renderers/Indicator/indicatorData.ts +650 -650
  136. package/src/engine/renderers/Indicator/kama.ts +136 -136
  137. package/src/engine/renderers/Indicator/keltner.ts +137 -137
  138. package/src/engine/renderers/Indicator/kst.ts +302 -302
  139. package/src/engine/renderers/Indicator/ma.ts +200 -200
  140. package/src/engine/renderers/Indicator/macd.ts +477 -477
  141. package/src/engine/renderers/Indicator/macdLegend.ts +141 -141
  142. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +272 -272
  143. package/src/engine/renderers/Indicator/mfi.ts +142 -142
  144. package/src/engine/renderers/Indicator/mom.ts +311 -311
  145. package/src/engine/renderers/Indicator/obv.ts +123 -123
  146. package/src/engine/renderers/Indicator/parkinson.ts +124 -124
  147. package/src/engine/renderers/Indicator/pivot.ts +131 -131
  148. package/src/engine/renderers/Indicator/pvt.ts +123 -123
  149. package/src/engine/renderers/Indicator/roc.ts +143 -143
  150. package/src/engine/renderers/Indicator/rsi.ts +390 -390
  151. package/src/engine/renderers/Indicator/sar.ts +113 -113
  152. package/src/engine/renderers/Indicator/scale/atr_scale.ts +19 -19
  153. package/src/engine/renderers/Indicator/scale/cci_scale.ts +19 -19
  154. package/src/engine/renderers/Indicator/scale/fastk_scale.ts +19 -19
  155. package/src/engine/renderers/Indicator/scale/indicator_scale.ts +204 -204
  156. package/src/engine/renderers/Indicator/scale/kst_scale.ts +19 -19
  157. package/src/engine/renderers/Indicator/scale/macd_scale.ts +22 -22
  158. package/src/engine/renderers/Indicator/scale/mom_scale.ts +19 -19
  159. package/src/engine/renderers/Indicator/scale/rsi_scale.ts +19 -19
  160. package/src/engine/renderers/Indicator/scale/stoch_scale.ts +19 -19
  161. package/src/engine/renderers/Indicator/scale/volume_scale.ts +26 -26
  162. package/src/engine/renderers/Indicator/scale/wmsr_scale.ts +19 -19
  163. package/src/engine/renderers/Indicator/stoch.ts +359 -359
  164. package/src/engine/renderers/Indicator/structure.ts +126 -126
  165. package/src/engine/renderers/Indicator/subPaneConfig.ts +265 -265
  166. package/src/engine/renderers/Indicator/supertrend.ts +115 -115
  167. package/src/engine/renderers/Indicator/tema.ts +136 -136
  168. package/src/engine/renderers/Indicator/trix.ts +158 -158
  169. package/src/engine/renderers/Indicator/vma.ts +124 -124
  170. package/src/engine/renderers/Indicator/volumeProfile.ts +125 -125
  171. package/src/engine/renderers/Indicator/vwap.ts +123 -123
  172. package/src/engine/renderers/Indicator/wma.ts +136 -136
  173. package/src/engine/renderers/Indicator/wmsr.ts +328 -328
  174. package/src/engine/renderers/Indicator/zones.ts +104 -104
  175. package/src/engine/renderers/__tests__/boll.renderer.test.ts +314 -314
  176. package/src/engine/renderers/__tests__/ene.renderer.test.ts +305 -305
  177. package/src/engine/renderers/__tests__/expma.renderer.test.ts +279 -279
  178. package/src/engine/renderers/__tests__/ma.renderer.test.ts +426 -426
  179. package/src/engine/renderers/__tests__/mainIndicatorLegend.renderer.test.ts +502 -502
  180. package/src/engine/renderers/__tests__/yAxis.renderer.test.ts +173 -173
  181. package/src/engine/renderers/candle.ts +459 -459
  182. package/src/engine/renderers/crosshair.ts +69 -69
  183. package/src/engine/renderers/customMarkers.ts +162 -162
  184. package/src/engine/renderers/extremaMarkers.ts +246 -246
  185. package/src/engine/renderers/gridLines.ts +90 -90
  186. package/src/engine/renderers/lastPrice.ts +97 -97
  187. package/src/engine/renderers/paneTitle.ts +136 -136
  188. package/src/engine/renderers/subVolume.ts +236 -236
  189. package/src/engine/renderers/timeAxis.ts +121 -121
  190. package/src/engine/renderers/webgl/candleSurface.ts +955 -955
  191. package/src/engine/renderers/webgl/sharedWebGLSurface.ts +146 -146
  192. package/src/engine/renderers/yAxis.ts +105 -105
  193. package/src/engine/scale/__tests__/logFormula.spec.ts +148 -148
  194. package/src/engine/scale/logFormula.ts +130 -130
  195. package/src/engine/scale/price.ts +39 -39
  196. package/src/engine/scale/priceScale.ts +264 -264
  197. package/src/engine/subPaneManager.ts +427 -427
  198. package/src/engine/theme/colors.ts +642 -642
  199. package/src/engine/theme/fonts.ts +20 -20
  200. package/src/engine/utils/klineConfig.ts +49 -49
  201. package/src/engine/utils/tickCount.ts +11 -11
  202. package/src/engine/utils/tickPosition.ts +214 -214
  203. package/src/engine/utils/zoom.ts +83 -83
  204. package/src/engine/viewport/viewport.ts +67 -67
  205. package/src/index.ts +3 -3
  206. package/src/plugin/ConfigManager.ts +93 -93
  207. package/src/plugin/EventBus.ts +77 -77
  208. package/src/plugin/HookSystem.ts +106 -106
  209. package/src/plugin/PluginHost.ts +243 -243
  210. package/src/plugin/PluginRegistry.ts +92 -92
  211. package/src/plugin/StateStore.ts +73 -73
  212. package/src/plugin/index.ts +19 -19
  213. package/src/plugin/rendererPluginManager.ts +368 -368
  214. package/src/plugin/stateKeys.ts +8 -8
  215. package/src/plugin/types.ts +526 -526
  216. package/src/reactivity/index.ts +2 -2
  217. package/src/reactivity/signal.ts +119 -119
  218. package/src/semantic/controller.ts +251 -251
  219. package/src/semantic/drawShape.ts +260 -260
  220. package/src/semantic/index.ts +28 -28
  221. package/src/semantic/schema.json +256 -256
  222. package/src/semantic/types.ts +251 -251
  223. package/src/semantic/validator.ts +349 -349
  224. package/src/types/kLine.ts +13 -13
  225. package/src/types/price.ts +56 -56
  226. package/src/types/volumePrice.ts +33 -33
  227. package/src/utils/dateFormat.ts +208 -208
  228. package/src/utils/kLineDraw/axis.ts +562 -562
  229. package/src/utils/priceToY.ts +34 -34
  230. package/src/utils/volumePrice.ts +202 -202
  231. package/src/version.ts +1 -1
@@ -1,177 +1,177 @@
1
- import { describe, it, expect } from 'vitest'
2
- import {
3
- roundToPhysicalPixel,
4
- alignToPhysicalPixelCenter,
5
- alignRect,
6
- createVerticalLineRect,
7
- createHorizontalLineRect,
8
- } from '../pixelAlign'
9
-
10
- describe('roundToPhysicalPixel', () => {
11
- it('应该正确对齐到物理像素边界(dpr=1)', () => {
12
- expect(roundToPhysicalPixel(0.5, 1)).toBe(1) // 0.5 * 1 = 0.5 -> round(0.5) = 1
13
- expect(roundToPhysicalPixel(1.2, 1)).toBe(1) // 1.2 * 1 = 1.2 -> round(1.2) = 1
14
- expect(roundToPhysicalPixel(1.8, 1)).toBe(2) // 1.8 * 1 = 1.8 -> round(1.8) = 2
15
- })
16
-
17
- it('应该正确对齐到物理像素边界(dpr=2)', () => {
18
- expect(roundToPhysicalPixel(0.25, 2)).toBe(0.5) // 0.25 * 2 = 0.5 -> round(0.5) = 1 -> 1/2 = 0.5
19
- expect(roundToPhysicalPixel(1.25, 2)).toBe(1.5) // 1.25 * 2 = 2.5 -> round(2.5) = 3 -> 3/2 = 1.5
20
- expect(roundToPhysicalPixel(1.75, 2)).toBe(2) // 1.75 * 2 = 3.5 -> round(3.5) = 4 -> 4/2 = 2
21
- })
22
-
23
- it('应该正确处理整数', () => {
24
- expect(roundToPhysicalPixel(0, 1)).toBe(0)
25
- expect(roundToPhysicalPixel(10, 1)).toBe(10)
26
- expect(roundToPhysicalPixel(10, 2)).toBe(10)
27
- })
28
-
29
- it('应该正确处理负值', () => {
30
- expect(roundToPhysicalPixel(-0.5, 1)).toBe(-0) // -0.5 * 1 = -0.5 -> round(-0.5) = -0
31
- expect(roundToPhysicalPixel(-1.2, 1)).toBe(-1) // -1.2 * 1 = -1.2 -> round(-1.2) = -1
32
- expect(roundToPhysicalPixel(-1.8, 1)).toBe(-2) // -1.8 * 1 = -1.8 -> round(-1.8) = -2
33
- })
34
- })
35
-
36
- describe('alignToPhysicalPixelCenter', () => {
37
- it('应该正确对齐到物理像素中心(dpr=1)', () => {
38
- expect(alignToPhysicalPixelCenter(0, 1)).toBe(0.5) // 0 * 1 = 0 -> floor(0) = 0 -> (0 + 0.5) / 1 = 0.5
39
- expect(alignToPhysicalPixelCenter(1, 1)).toBe(1.5) // 1 * 1 = 1 -> floor(1) = 1 -> (1 + 0.5) / 1 = 1.5
40
- expect(alignToPhysicalPixelCenter(1.9, 1)).toBe(1.5) // 1.9 * 1 = 1.9 -> floor(1.9) = 1 -> (1 + 0.5) / 1 = 1.5
41
- })
42
-
43
- it('应该正确对齐到物理像素中心(dpr=2)', () => {
44
- expect(alignToPhysicalPixelCenter(0, 2)).toBe(0.25) // 0 * 2 = 0 -> floor(0) = 0 -> (0 + 0.5) / 2 = 0.25
45
- expect(alignToPhysicalPixelCenter(1, 2)).toBe(1.25) // 1 * 2 = 2 -> floor(2) = 2 -> (2 + 0.5) / 2 = 1.25
46
- expect(alignToPhysicalPixelCenter(1.9, 2)).toBe(1.75) // 1.9 * 2 = 3.8 -> floor(3.8) = 3 -> (3 + 0.5) / 2 = 1.75
47
- })
48
-
49
- it('应该正确处理负值', () => {
50
- expect(alignToPhysicalPixelCenter(0, 1)).toBe(0.5)
51
- expect(alignToPhysicalPixelCenter(-0.9, 1)).toBe(-0.5) // -0.9 * 1 = -0.9 -> floor(-0.9) = -1 -> (-1 + 0.5) / 1 = -0.5
52
- expect(alignToPhysicalPixelCenter(-1.9, 1)).toBe(-1.5) // -1.9 * 1 = -1.9 -> floor(-1.9) = -2 -> (-2 + 0.5) / 1 = -1.5
53
- })
54
- })
55
-
56
- describe('alignRect', () => {
57
- it('应该正确对齐矩形到物理像素边界(dpr=1)', () => {
58
- const result = alignRect(0.5, 0.5, 10.5, 10.5, 1)
59
- expect(result.x).toBe(1) // round(0.5) = 1
60
- expect(result.y).toBe(1) // round(0.5) = 1
61
- expect(result.width).toBe(10) // round(11) - 1 = 10
62
- expect(result.height).toBe(10) // round(11) - 1 = 10
63
- })
64
-
65
- it('应该正确对齐矩形到物理像素边界(dpr=2)', () => {
66
- const result = alignRect(0.25, 0.25, 5.25, 5.25, 2)
67
- expect(result.x).toBe(0.5)
68
- expect(result.y).toBe(0.5)
69
- expect(result.width).toBe(5)
70
- expect(result.height).toBe(5)
71
- })
72
-
73
- it('应该确保宽度和高度至少为 1/dpr', () => {
74
- const result = alignRect(0, 0, 0.1, 0.1, 2)
75
- expect(result.width).toBe(0.5) // 1/dpr = 1/2 = 0.5
76
- expect(result.height).toBe(0.5)
77
- })
78
-
79
- it('应该正确处理负坐标', () => {
80
- const result = alignRect(-0.5, -0.5, 10, 10, 1)
81
- expect(result.x).toBe(-0) // round(-0.5) = -0
82
- expect(result.y).toBe(-0) // round(-0.5) = -0
83
- expect(result.width).toBe(10) // round(9.5) - (-0) = 10
84
- expect(result.height).toBe(10) // round(9.5) - (-0) = 10
85
- })
86
- })
87
-
88
- describe('createVerticalLineRect', () => {
89
- it('应该创建1物理像素宽的垂直线矩形(dpr=1)', () => {
90
- const result = createVerticalLineRect(10, 0, 20, 1)
91
- expect(result).not.toBeNull()
92
- expect(result?.x).toBe(10)
93
- expect(result?.y).toBe(0)
94
- expect(result?.width).toBe(1) // 1/dpr = 1/1 = 1
95
- expect(result?.height).toBe(20)
96
- })
97
-
98
- it('应该创建1物理像素宽的垂直线矩形(dpr=2)', () => {
99
- const result = createVerticalLineRect(10, 0, 20, 2)
100
- expect(result).not.toBeNull()
101
- expect(result?.x).toBe(10)
102
- expect(result?.y).toBe(0)
103
- expect(result?.width).toBe(0.5) // 1/dpr = 1/2 = 0.5
104
- expect(result?.height).toBe(20)
105
- })
106
-
107
- it('应该正确处理反转的y坐标', () => {
108
- const result = createVerticalLineRect(10, 20, 0, 1)
109
- expect(result?.y).toBe(0)
110
- expect(result?.height).toBe(20)
111
- })
112
-
113
- it('应该返回null当y1等于y2时', () => {
114
- const result = createVerticalLineRect(10, 5, 5, 1)
115
- expect(result).toBeNull()
116
- })
117
-
118
- it('应该正确对齐到物理像素边界', () => {
119
- const result = createVerticalLineRect(10.25, 0, 20, 2)
120
- expect(result?.x).toBe(10.5) // 对齐到物理像素边界
121
- })
122
-
123
- it('应该确保高度至少为1', () => {
124
- const result = createVerticalLineRect(10, 0, 0.5, 1)
125
- expect(result?.height).toBe(1)
126
- })
127
- })
128
-
129
- describe('createHorizontalLineRect', () => {
130
- it('应该创建1物理像素高的水平线矩形(dpr=1)', () => {
131
- const result = createHorizontalLineRect(0, 20, 10, 1)
132
- expect(result).not.toBeNull()
133
- expect(result?.x).toBe(0)
134
- expect(result?.y).toBe(10)
135
- expect(result?.width).toBe(20)
136
- expect(result?.height).toBe(1) // 1/dpr = 1/1 = 1
137
- })
138
-
139
- it('应该创建1物理像素高的水平线矩形(dpr=2)', () => {
140
- const result = createHorizontalLineRect(0, 20, 10, 2)
141
- expect(result).not.toBeNull()
142
- expect(result?.x).toBe(0)
143
- expect(result?.y).toBe(10)
144
- expect(result?.width).toBe(20)
145
- expect(result?.height).toBe(0.5) // 1/dpr = 1/2 = 0.5
146
- })
147
-
148
- it('应该正确处理反转的x坐标', () => {
149
- const result = createHorizontalLineRect(20, 0, 10, 1)
150
- expect(result?.x).toBe(0)
151
- expect(result?.width).toBe(20)
152
- })
153
-
154
- it('应该返回null当x1等于x2时', () => {
155
- const result = createHorizontalLineRect(10, 10, 5, 1)
156
- expect(result).toBeNull()
157
- })
158
-
159
- it('应该正确对齐到物理像素边界', () => {
160
- const result = createHorizontalLineRect(0.25, 20.25, 10, 2)
161
- expect(result?.x).toBe(0.5) // 对齐到物理像素边界
162
- expect(result?.width).toBe(20)
163
- })
164
-
165
- it('应该确保宽度至少为1', () => {
166
- const result = createHorizontalLineRect(0, 0.5, 10, 1)
167
- expect(result?.width).toBe(1)
168
- })
169
-
170
- it('应该正确处理小数坐标(dpr=1)', () => {
171
- const result = createHorizontalLineRect(1.3, 5.7, 10.2, 1)
172
- expect(result?.x).toBe(1) // 1.3 * 1 = 1.3 -> round(1.3) = 1 -> 1/1 = 1
173
- expect(result?.width).toBe(5) // left=1.3 -> physLeft=1, right=5.7 -> physRight=6 -> (6-1)/1 = 5
174
- expect(result?.y).toBe(10) // 10.2 * 1 = 10.2 -> round(10.2) = 10 -> 10/1 = 10 (对齐到物理像素)
175
- expect(result?.height).toBe(1)
176
- })
1
+ import { describe, it, expect } from 'vitest'
2
+ import {
3
+ roundToPhysicalPixel,
4
+ alignToPhysicalPixelCenter,
5
+ alignRect,
6
+ createVerticalLineRect,
7
+ createHorizontalLineRect,
8
+ } from '../pixelAlign'
9
+
10
+ describe('roundToPhysicalPixel', () => {
11
+ it('应该正确对齐到物理像素边界(dpr=1)', () => {
12
+ expect(roundToPhysicalPixel(0.5, 1)).toBe(1) // 0.5 * 1 = 0.5 -> round(0.5) = 1
13
+ expect(roundToPhysicalPixel(1.2, 1)).toBe(1) // 1.2 * 1 = 1.2 -> round(1.2) = 1
14
+ expect(roundToPhysicalPixel(1.8, 1)).toBe(2) // 1.8 * 1 = 1.8 -> round(1.8) = 2
15
+ })
16
+
17
+ it('应该正确对齐到物理像素边界(dpr=2)', () => {
18
+ expect(roundToPhysicalPixel(0.25, 2)).toBe(0.5) // 0.25 * 2 = 0.5 -> round(0.5) = 1 -> 1/2 = 0.5
19
+ expect(roundToPhysicalPixel(1.25, 2)).toBe(1.5) // 1.25 * 2 = 2.5 -> round(2.5) = 3 -> 3/2 = 1.5
20
+ expect(roundToPhysicalPixel(1.75, 2)).toBe(2) // 1.75 * 2 = 3.5 -> round(3.5) = 4 -> 4/2 = 2
21
+ })
22
+
23
+ it('应该正确处理整数', () => {
24
+ expect(roundToPhysicalPixel(0, 1)).toBe(0)
25
+ expect(roundToPhysicalPixel(10, 1)).toBe(10)
26
+ expect(roundToPhysicalPixel(10, 2)).toBe(10)
27
+ })
28
+
29
+ it('应该正确处理负值', () => {
30
+ expect(roundToPhysicalPixel(-0.5, 1)).toBe(-0) // -0.5 * 1 = -0.5 -> round(-0.5) = -0
31
+ expect(roundToPhysicalPixel(-1.2, 1)).toBe(-1) // -1.2 * 1 = -1.2 -> round(-1.2) = -1
32
+ expect(roundToPhysicalPixel(-1.8, 1)).toBe(-2) // -1.8 * 1 = -1.8 -> round(-1.8) = -2
33
+ })
34
+ })
35
+
36
+ describe('alignToPhysicalPixelCenter', () => {
37
+ it('应该正确对齐到物理像素中心(dpr=1)', () => {
38
+ expect(alignToPhysicalPixelCenter(0, 1)).toBe(0.5) // 0 * 1 = 0 -> floor(0) = 0 -> (0 + 0.5) / 1 = 0.5
39
+ expect(alignToPhysicalPixelCenter(1, 1)).toBe(1.5) // 1 * 1 = 1 -> floor(1) = 1 -> (1 + 0.5) / 1 = 1.5
40
+ expect(alignToPhysicalPixelCenter(1.9, 1)).toBe(1.5) // 1.9 * 1 = 1.9 -> floor(1.9) = 1 -> (1 + 0.5) / 1 = 1.5
41
+ })
42
+
43
+ it('应该正确对齐到物理像素中心(dpr=2)', () => {
44
+ expect(alignToPhysicalPixelCenter(0, 2)).toBe(0.25) // 0 * 2 = 0 -> floor(0) = 0 -> (0 + 0.5) / 2 = 0.25
45
+ expect(alignToPhysicalPixelCenter(1, 2)).toBe(1.25) // 1 * 2 = 2 -> floor(2) = 2 -> (2 + 0.5) / 2 = 1.25
46
+ expect(alignToPhysicalPixelCenter(1.9, 2)).toBe(1.75) // 1.9 * 2 = 3.8 -> floor(3.8) = 3 -> (3 + 0.5) / 2 = 1.75
47
+ })
48
+
49
+ it('应该正确处理负值', () => {
50
+ expect(alignToPhysicalPixelCenter(0, 1)).toBe(0.5)
51
+ expect(alignToPhysicalPixelCenter(-0.9, 1)).toBe(-0.5) // -0.9 * 1 = -0.9 -> floor(-0.9) = -1 -> (-1 + 0.5) / 1 = -0.5
52
+ expect(alignToPhysicalPixelCenter(-1.9, 1)).toBe(-1.5) // -1.9 * 1 = -1.9 -> floor(-1.9) = -2 -> (-2 + 0.5) / 1 = -1.5
53
+ })
54
+ })
55
+
56
+ describe('alignRect', () => {
57
+ it('应该正确对齐矩形到物理像素边界(dpr=1)', () => {
58
+ const result = alignRect(0.5, 0.5, 10.5, 10.5, 1)
59
+ expect(result.x).toBe(1) // round(0.5) = 1
60
+ expect(result.y).toBe(1) // round(0.5) = 1
61
+ expect(result.width).toBe(10) // round(11) - 1 = 10
62
+ expect(result.height).toBe(10) // round(11) - 1 = 10
63
+ })
64
+
65
+ it('应该正确对齐矩形到物理像素边界(dpr=2)', () => {
66
+ const result = alignRect(0.25, 0.25, 5.25, 5.25, 2)
67
+ expect(result.x).toBe(0.5)
68
+ expect(result.y).toBe(0.5)
69
+ expect(result.width).toBe(5)
70
+ expect(result.height).toBe(5)
71
+ })
72
+
73
+ it('应该确保宽度和高度至少为 1/dpr', () => {
74
+ const result = alignRect(0, 0, 0.1, 0.1, 2)
75
+ expect(result.width).toBe(0.5) // 1/dpr = 1/2 = 0.5
76
+ expect(result.height).toBe(0.5)
77
+ })
78
+
79
+ it('应该正确处理负坐标', () => {
80
+ const result = alignRect(-0.5, -0.5, 10, 10, 1)
81
+ expect(result.x).toBe(-0) // round(-0.5) = -0
82
+ expect(result.y).toBe(-0) // round(-0.5) = -0
83
+ expect(result.width).toBe(10) // round(9.5) - (-0) = 10
84
+ expect(result.height).toBe(10) // round(9.5) - (-0) = 10
85
+ })
86
+ })
87
+
88
+ describe('createVerticalLineRect', () => {
89
+ it('应该创建1物理像素宽的垂直线矩形(dpr=1)', () => {
90
+ const result = createVerticalLineRect(10, 0, 20, 1)
91
+ expect(result).not.toBeNull()
92
+ expect(result?.x).toBe(10)
93
+ expect(result?.y).toBe(0)
94
+ expect(result?.width).toBe(1) // 1/dpr = 1/1 = 1
95
+ expect(result?.height).toBe(20)
96
+ })
97
+
98
+ it('应该创建1物理像素宽的垂直线矩形(dpr=2)', () => {
99
+ const result = createVerticalLineRect(10, 0, 20, 2)
100
+ expect(result).not.toBeNull()
101
+ expect(result?.x).toBe(10)
102
+ expect(result?.y).toBe(0)
103
+ expect(result?.width).toBe(0.5) // 1/dpr = 1/2 = 0.5
104
+ expect(result?.height).toBe(20)
105
+ })
106
+
107
+ it('应该正确处理反转的y坐标', () => {
108
+ const result = createVerticalLineRect(10, 20, 0, 1)
109
+ expect(result?.y).toBe(0)
110
+ expect(result?.height).toBe(20)
111
+ })
112
+
113
+ it('应该返回null当y1等于y2时', () => {
114
+ const result = createVerticalLineRect(10, 5, 5, 1)
115
+ expect(result).toBeNull()
116
+ })
117
+
118
+ it('应该正确对齐到物理像素边界', () => {
119
+ const result = createVerticalLineRect(10.25, 0, 20, 2)
120
+ expect(result?.x).toBe(10.5) // 对齐到物理像素边界
121
+ })
122
+
123
+ it('应该确保高度至少为1', () => {
124
+ const result = createVerticalLineRect(10, 0, 0.5, 1)
125
+ expect(result?.height).toBe(1)
126
+ })
127
+ })
128
+
129
+ describe('createHorizontalLineRect', () => {
130
+ it('应该创建1物理像素高的水平线矩形(dpr=1)', () => {
131
+ const result = createHorizontalLineRect(0, 20, 10, 1)
132
+ expect(result).not.toBeNull()
133
+ expect(result?.x).toBe(0)
134
+ expect(result?.y).toBe(10)
135
+ expect(result?.width).toBe(20)
136
+ expect(result?.height).toBe(1) // 1/dpr = 1/1 = 1
137
+ })
138
+
139
+ it('应该创建1物理像素高的水平线矩形(dpr=2)', () => {
140
+ const result = createHorizontalLineRect(0, 20, 10, 2)
141
+ expect(result).not.toBeNull()
142
+ expect(result?.x).toBe(0)
143
+ expect(result?.y).toBe(10)
144
+ expect(result?.width).toBe(20)
145
+ expect(result?.height).toBe(0.5) // 1/dpr = 1/2 = 0.5
146
+ })
147
+
148
+ it('应该正确处理反转的x坐标', () => {
149
+ const result = createHorizontalLineRect(20, 0, 10, 1)
150
+ expect(result?.x).toBe(0)
151
+ expect(result?.width).toBe(20)
152
+ })
153
+
154
+ it('应该返回null当x1等于x2时', () => {
155
+ const result = createHorizontalLineRect(10, 10, 5, 1)
156
+ expect(result).toBeNull()
157
+ })
158
+
159
+ it('应该正确对齐到物理像素边界', () => {
160
+ const result = createHorizontalLineRect(0.25, 20.25, 10, 2)
161
+ expect(result?.x).toBe(0.5) // 对齐到物理像素边界
162
+ expect(result?.width).toBe(20)
163
+ })
164
+
165
+ it('应该确保宽度至少为1', () => {
166
+ const result = createHorizontalLineRect(0, 0.5, 10, 1)
167
+ expect(result?.width).toBe(1)
168
+ })
169
+
170
+ it('应该正确处理小数坐标(dpr=1)', () => {
171
+ const result = createHorizontalLineRect(1.3, 5.7, 10.2, 1)
172
+ expect(result?.x).toBe(1) // 1.3 * 1 = 1.3 -> round(1.3) = 1 -> 1/1 = 1
173
+ expect(result?.width).toBe(5) // left=1.3 -> physLeft=1, right=5.7 -> physRight=6 -> (6-1)/1 = 5
174
+ expect(result?.y).toBe(10) // 10.2 * 1 = 10.2 -> round(10.2) = 10 -> 10/1 = 10 (对齐到物理像素)
175
+ expect(result?.height).toBe(1)
176
+ })
177
177
  })