@363045841yyt/klinechart-core 0.8.12 → 0.8.13-alpha.1

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 (1136) hide show
  1. package/README.md +18 -12
  2. package/README.zh-CN.md +18 -12
  3. package/dist/alerts/createAlertController.d.ts.map +1 -1
  4. package/dist/alerts/createAlertController.js +2 -6
  5. package/dist/alerts/createAlertController.js.map +1 -1
  6. package/dist/alerts/index.d.ts +1 -1
  7. package/dist/alerts/index.d.ts.map +1 -1
  8. package/dist/alerts/index.js +1 -1
  9. package/dist/alerts/index.js.map +1 -1
  10. package/dist/alerts/predicates.d.ts.map +1 -1
  11. package/dist/alerts/predicates.js +1 -4
  12. package/dist/alerts/predicates.js.map +1 -1
  13. package/dist/alerts/ruleSchema.d.ts.map +1 -1
  14. package/dist/alerts/ruleSchema.js +1 -1
  15. package/dist/alerts/ruleSchema.js.map +1 -1
  16. package/dist/alerts/types.d.ts.map +1 -1
  17. package/dist/chartTypes/heikinAshi.d.ts.map +1 -1
  18. package/dist/chartTypes/heikinAshi.js.map +1 -1
  19. package/dist/chartTypes/pointAndFigure.d.ts.map +1 -1
  20. package/dist/chartTypes/pointAndFigure.js.map +1 -1
  21. package/dist/chartTypes/rangeBars.d.ts.map +1 -1
  22. package/dist/chartTypes/rangeBars.js.map +1 -1
  23. package/dist/chartTypes/renko.d.ts.map +1 -1
  24. package/dist/chartTypes/renko.js.map +1 -1
  25. package/dist/chartTypes/types.d.ts.map +1 -1
  26. package/dist/components/anchoredVwap/computeAnchoredVwap.d.ts.map +1 -1
  27. package/dist/components/anchoredVwap/computeAnchoredVwap.js.map +1 -1
  28. package/dist/components/anchoredVwap/createAnchoredVwapController.d.ts.map +1 -1
  29. package/dist/components/anchoredVwap/createAnchoredVwapController.js +6 -17
  30. package/dist/components/anchoredVwap/createAnchoredVwapController.js.map +1 -1
  31. package/dist/components/anchoredVwap/index.d.ts.map +1 -1
  32. package/dist/components/anchoredVwap/types.d.ts.map +1 -1
  33. package/dist/components/crosshairSync/createCrosshairSync.d.ts.map +1 -1
  34. package/dist/components/crosshairSync/createCrosshairSync.js.map +1 -1
  35. package/dist/components/crosshairSync/index.d.ts.map +1 -1
  36. package/dist/components/crosshairSync/index.js.map +1 -1
  37. package/dist/components/footprint/aggressor.d.ts.map +1 -1
  38. package/dist/components/footprint/aggressor.js.map +1 -1
  39. package/dist/components/footprint/createFootprintController.d.ts.map +1 -1
  40. package/dist/components/footprint/createFootprintController.js +2 -3
  41. package/dist/components/footprint/createFootprintController.js.map +1 -1
  42. package/dist/components/footprint/index.d.ts +2 -2
  43. package/dist/components/footprint/index.d.ts.map +1 -1
  44. package/dist/components/footprint/index.js +2 -2
  45. package/dist/components/footprint/index.js.map +1 -1
  46. package/dist/components/footprint/perBarStats.d.ts.map +1 -1
  47. package/dist/components/footprint/perBarStats.js.map +1 -1
  48. package/dist/components/footprint/types.d.ts.map +1 -1
  49. package/dist/components/mtfOverlay/alignToBaseIndex.d.ts.map +1 -1
  50. package/dist/components/mtfOverlay/alignToBaseIndex.js.map +1 -1
  51. package/dist/components/mtfOverlay/createMtfController.d.ts.map +1 -1
  52. package/dist/components/mtfOverlay/createMtfController.js.map +1 -1
  53. package/dist/components/mtfOverlay/index.d.ts.map +1 -1
  54. package/dist/components/mtfOverlay/resampleBars.d.ts.map +1 -1
  55. package/dist/components/mtfOverlay/resampleBars.js.map +1 -1
  56. package/dist/components/mtfOverlay/types.d.ts.map +1 -1
  57. package/dist/components/orderBookHeatmap/createHeatmapController.d.ts.map +1 -1
  58. package/dist/components/orderBookHeatmap/createHeatmapController.js +20 -3
  59. package/dist/components/orderBookHeatmap/createHeatmapController.js.map +1 -1
  60. package/dist/components/orderBookHeatmap/createOrderBookState.d.ts.map +1 -1
  61. package/dist/components/orderBookHeatmap/createOrderBookState.js +1 -3
  62. package/dist/components/orderBookHeatmap/createOrderBookState.js.map +1 -1
  63. package/dist/components/orderBookHeatmap/deltaArchive.d.ts.map +1 -1
  64. package/dist/components/orderBookHeatmap/deltaArchive.js.map +1 -1
  65. package/dist/components/orderBookHeatmap/index.d.ts.map +1 -1
  66. package/dist/components/orderBookHeatmap/logColorScale.d.ts.map +1 -1
  67. package/dist/components/orderBookHeatmap/logColorScale.js.map +1 -1
  68. package/dist/components/orderBookHeatmap/snapshotRing.d.ts.map +1 -1
  69. package/dist/components/orderBookHeatmap/snapshotRing.js.map +1 -1
  70. package/dist/components/orderBookHeatmap/types.d.ts +10 -0
  71. package/dist/components/orderBookHeatmap/types.d.ts.map +1 -1
  72. package/dist/components/volumeProfile/binning.d.ts.map +1 -1
  73. package/dist/components/volumeProfile/binning.js.map +1 -1
  74. package/dist/components/volumeProfile/createVolumeProfileController.d.ts.map +1 -1
  75. package/dist/components/volumeProfile/createVolumeProfileController.js.map +1 -1
  76. package/dist/components/volumeProfile/index.d.ts.map +1 -1
  77. package/dist/components/volumeProfile/poc.js.map +1 -1
  78. package/dist/components/volumeProfile/types.d.ts.map +1 -1
  79. package/dist/components/volumeProfile/valueArea.d.ts.map +1 -1
  80. package/dist/components/volumeProfile/valueArea.js.map +1 -1
  81. package/dist/config/chartSettings.d.ts.map +1 -1
  82. package/dist/config/chartSettings.js +56 -11
  83. package/dist/config/chartSettings.js.map +1 -1
  84. package/dist/controllers/createChartController.d.ts.map +1 -1
  85. package/dist/controllers/createChartController.js +40 -16
  86. package/dist/controllers/createChartController.js.map +1 -1
  87. package/dist/controllers/createDrawingController.d.ts.map +1 -1
  88. package/dist/controllers/createDrawingController.js.map +1 -1
  89. package/dist/controllers/createIndicatorSelectorController.d.ts.map +1 -1
  90. package/dist/controllers/createIndicatorSelectorController.js +1 -2
  91. package/dist/controllers/createIndicatorSelectorController.js.map +1 -1
  92. package/dist/controllers/createToolbarController.d.ts.map +1 -1
  93. package/dist/controllers/createToolbarController.js +1 -3
  94. package/dist/controllers/createToolbarController.js.map +1 -1
  95. package/dist/controllers/index.d.ts +7 -5
  96. package/dist/controllers/index.d.ts.map +1 -1
  97. package/dist/controllers/index.js +5 -3
  98. package/dist/controllers/index.js.map +1 -1
  99. package/dist/controllers/types.d.ts +24 -0
  100. package/dist/controllers/types.d.ts.map +1 -1
  101. package/dist/data-fetchers/baostock.d.ts.map +1 -1
  102. package/dist/data-fetchers/baostock.js.map +1 -1
  103. package/dist/data-fetchers/binance.d.ts +33 -0
  104. package/dist/data-fetchers/binance.d.ts.map +1 -0
  105. package/dist/data-fetchers/binance.js +115 -0
  106. package/dist/data-fetchers/binance.js.map +1 -0
  107. package/dist/data-fetchers/dataBuffer.d.ts.map +1 -1
  108. package/dist/data-fetchers/dataBuffer.effects.d.ts.map +1 -1
  109. package/dist/data-fetchers/dataBuffer.effects.js.map +1 -1
  110. package/dist/data-fetchers/dataBuffer.js +9 -7
  111. package/dist/data-fetchers/dataBuffer.js.map +1 -1
  112. package/dist/data-fetchers/depthConnector.d.ts +47 -0
  113. package/dist/data-fetchers/depthConnector.d.ts.map +1 -0
  114. package/dist/data-fetchers/depthConnector.js +88 -0
  115. package/dist/data-fetchers/depthConnector.js.map +1 -0
  116. package/dist/data-fetchers/depthTypes.d.ts +52 -0
  117. package/dist/data-fetchers/depthTypes.d.ts.map +1 -0
  118. package/dist/data-fetchers/depthTypes.js +9 -0
  119. package/dist/data-fetchers/depthTypes.js.map +1 -0
  120. package/dist/data-fetchers/fetcherDefinitionRegistry.d.ts +1 -0
  121. package/dist/data-fetchers/fetcherDefinitionRegistry.d.ts.map +1 -1
  122. package/dist/data-fetchers/fetcherDefinitionRegistry.js +3 -0
  123. package/dist/data-fetchers/fetcherDefinitionRegistry.js.map +1 -1
  124. package/dist/data-fetchers/gotdx.js +13 -3
  125. package/dist/data-fetchers/gotdx.js.map +1 -1
  126. package/dist/data-fetchers/index.d.ts +7 -1
  127. package/dist/data-fetchers/index.d.ts.map +1 -1
  128. package/dist/data-fetchers/index.js +6 -1
  129. package/dist/data-fetchers/index.js.map +1 -1
  130. package/dist/data-fetchers/router.d.ts.map +1 -1
  131. package/dist/data-fetchers/router.js +3 -8
  132. package/dist/data-fetchers/router.js.map +1 -1
  133. package/dist/data-fetchers/timeShareBuffer.d.ts.map +1 -1
  134. package/dist/data-fetchers/timeShareBuffer.js.map +1 -1
  135. package/dist/data-fetchers/tradingview.js.map +1 -1
  136. package/dist/engine/chart.d.ts +6 -2
  137. package/dist/engine/chart.d.ts.map +1 -1
  138. package/dist/engine/chart.js +48 -14
  139. package/dist/engine/chart.js.map +1 -1
  140. package/dist/engine/controller/interaction.d.ts.map +1 -1
  141. package/dist/engine/controller/interaction.js +30 -9
  142. package/dist/engine/controller/interaction.js.map +1 -1
  143. package/dist/engine/controller/markerInteraction.d.ts.map +1 -1
  144. package/dist/engine/controller/markerInteraction.js.map +1 -1
  145. package/dist/engine/data/chartDataManager.d.ts +11 -1
  146. package/dist/engine/data/chartDataManager.d.ts.map +1 -1
  147. package/dist/engine/data/chartDataManager.js +73 -23
  148. package/dist/engine/data/chartDataManager.js.map +1 -1
  149. package/dist/engine/draw/pixelAlign.d.ts.map +1 -1
  150. package/dist/engine/draw/pixelAlign.js.map +1 -1
  151. package/dist/engine/drawing/HitTester.d.ts.map +1 -1
  152. package/dist/engine/drawing/HitTester.js +3 -5
  153. package/dist/engine/drawing/HitTester.js.map +1 -1
  154. package/dist/engine/drawing/PreviewRenderer.d.ts.map +1 -1
  155. package/dist/engine/drawing/PreviewRenderer.js +25 -5
  156. package/dist/engine/drawing/PreviewRenderer.js.map +1 -1
  157. package/dist/engine/drawing/index.d.ts.map +1 -1
  158. package/dist/engine/drawing/index.js +88 -20
  159. package/dist/engine/drawing/index.js.map +1 -1
  160. package/dist/engine/drawing/interaction.d.ts.map +1 -1
  161. package/dist/engine/drawing/interaction.js.map +1 -1
  162. package/dist/engine/drawing/linearRegression.d.ts.map +1 -1
  163. package/dist/engine/drawing/linearRegression.js.map +1 -1
  164. package/dist/engine/drawing/plugin.d.ts.map +1 -1
  165. package/dist/engine/drawing/plugin.js +25 -10
  166. package/dist/engine/drawing/plugin.js.map +1 -1
  167. package/dist/engine/indicators/calculators/_shared.d.ts.map +1 -1
  168. package/dist/engine/indicators/calculators/_shared.js.map +1 -1
  169. package/dist/engine/indicators/calculators/bands.d.ts.map +1 -1
  170. package/dist/engine/indicators/calculators/bands.js +2 -2
  171. package/dist/engine/indicators/calculators/bands.js.map +1 -1
  172. package/dist/engine/indicators/calculators/index.d.ts +3 -3
  173. package/dist/engine/indicators/calculators/index.d.ts.map +1 -1
  174. package/dist/engine/indicators/calculators/index.js +2 -2
  175. package/dist/engine/indicators/calculators/index.js.map +1 -1
  176. package/dist/engine/indicators/calculators/movingAverages.d.ts.map +1 -1
  177. package/dist/engine/indicators/calculators/movingAverages.js.map +1 -1
  178. package/dist/engine/indicators/calculators/oscillators.d.ts.map +1 -1
  179. package/dist/engine/indicators/calculators/oscillators.js +3 -3
  180. package/dist/engine/indicators/calculators/oscillators.js.map +1 -1
  181. package/dist/engine/indicators/calculators/patterns.d.ts.map +1 -1
  182. package/dist/engine/indicators/calculators/patterns.js +3 -2
  183. package/dist/engine/indicators/calculators/patterns.js.map +1 -1
  184. package/dist/engine/indicators/calculators/volatility.d.ts.map +1 -1
  185. package/dist/engine/indicators/calculators/volatility.js +2 -2
  186. package/dist/engine/indicators/calculators/volatility.js.map +1 -1
  187. package/dist/engine/indicators/calculators/volume.d.ts.map +1 -1
  188. package/dist/engine/indicators/calculators/volume.js +1 -1
  189. package/dist/engine/indicators/calculators/volume.js.map +1 -1
  190. package/dist/engine/indicators/chartIndicatorManager.d.ts +7 -1
  191. package/dist/engine/indicators/chartIndicatorManager.d.ts.map +1 -1
  192. package/dist/engine/indicators/chartIndicatorManager.js +44 -11
  193. package/dist/engine/indicators/chartIndicatorManager.js.map +1 -1
  194. package/dist/engine/indicators/indicator.worker.js +1 -1
  195. package/dist/engine/indicators/indicator.worker.js.map +1 -1
  196. package/dist/engine/indicators/indicatorDefinitionRegistry.d.ts.map +1 -1
  197. package/dist/engine/indicators/indicatorDefinitionRegistry.js +16 -10
  198. package/dist/engine/indicators/indicatorDefinitionRegistry.js.map +1 -1
  199. package/dist/engine/indicators/indicatorMetadata.d.ts.map +1 -1
  200. package/dist/engine/indicators/indicatorMetadata.js.map +1 -1
  201. package/dist/engine/indicators/indicatorRegistry.d.ts.map +1 -1
  202. package/dist/engine/indicators/indicatorRegistry.js +6 -3
  203. package/dist/engine/indicators/indicatorRegistry.js.map +1 -1
  204. package/dist/engine/indicators/indicatorRuntime.d.ts.map +1 -1
  205. package/dist/engine/indicators/indicatorRuntime.js +8 -8
  206. package/dist/engine/indicators/indicatorRuntime.js.map +1 -1
  207. package/dist/engine/indicators/registerBuiltins.d.ts.map +1 -1
  208. package/dist/engine/indicators/registerBuiltins.js.map +1 -1
  209. package/dist/engine/indicators/scheduler.d.ts.map +1 -1
  210. package/dist/engine/indicators/scheduler.js +19 -15
  211. package/dist/engine/indicators/scheduler.js.map +1 -1
  212. package/dist/engine/indicators/soa.d.ts.map +1 -1
  213. package/dist/engine/indicators/soa.js +1 -3
  214. package/dist/engine/indicators/soa.js.map +1 -1
  215. package/dist/engine/indicators/state/atrState.d.ts.map +1 -1
  216. package/dist/engine/indicators/state/atrState.js.map +1 -1
  217. package/dist/engine/indicators/state/bollState.d.ts.map +1 -1
  218. package/dist/engine/indicators/state/bollState.js.map +1 -1
  219. package/dist/engine/indicators/state/cciState.d.ts.map +1 -1
  220. package/dist/engine/indicators/state/cciState.js.map +1 -1
  221. package/dist/engine/indicators/state/chaikinVolState.d.ts.map +1 -1
  222. package/dist/engine/indicators/state/chaikinVolState.js.map +1 -1
  223. package/dist/engine/indicators/state/cmfState.d.ts.map +1 -1
  224. package/dist/engine/indicators/state/cmfState.js.map +1 -1
  225. package/dist/engine/indicators/state/demaState.d.ts.map +1 -1
  226. package/dist/engine/indicators/state/demaState.js.map +1 -1
  227. package/dist/engine/indicators/state/donchianState.d.ts.map +1 -1
  228. package/dist/engine/indicators/state/donchianState.js.map +1 -1
  229. package/dist/engine/indicators/state/eneState.d.ts.map +1 -1
  230. package/dist/engine/indicators/state/eneState.js.map +1 -1
  231. package/dist/engine/indicators/state/expmaState.d.ts.map +1 -1
  232. package/dist/engine/indicators/state/expmaState.js.map +1 -1
  233. package/dist/engine/indicators/state/fastkState.d.ts.map +1 -1
  234. package/dist/engine/indicators/state/fastkState.js.map +1 -1
  235. package/dist/engine/indicators/state/fibState.d.ts.map +1 -1
  236. package/dist/engine/indicators/state/fibState.js.map +1 -1
  237. package/dist/engine/indicators/state/hmaState.d.ts.map +1 -1
  238. package/dist/engine/indicators/state/hmaState.js.map +1 -1
  239. package/dist/engine/indicators/state/hvState.d.ts.map +1 -1
  240. package/dist/engine/indicators/state/hvState.js +5 -1
  241. package/dist/engine/indicators/state/hvState.js.map +1 -1
  242. package/dist/engine/indicators/state/ichimokuState.d.ts.map +1 -1
  243. package/dist/engine/indicators/state/ichimokuState.js.map +1 -1
  244. package/dist/engine/indicators/state/kamaState.d.ts.map +1 -1
  245. package/dist/engine/indicators/state/kamaState.js.map +1 -1
  246. package/dist/engine/indicators/state/keltnerState.d.ts.map +1 -1
  247. package/dist/engine/indicators/state/keltnerState.js.map +1 -1
  248. package/dist/engine/indicators/state/kstState.d.ts.map +1 -1
  249. package/dist/engine/indicators/state/kstState.js.map +1 -1
  250. package/dist/engine/indicators/state/maState.d.ts.map +1 -1
  251. package/dist/engine/indicators/state/maState.js.map +1 -1
  252. package/dist/engine/indicators/state/mfiState.d.ts.map +1 -1
  253. package/dist/engine/indicators/state/mfiState.js.map +1 -1
  254. package/dist/engine/indicators/state/momState.d.ts.map +1 -1
  255. package/dist/engine/indicators/state/momState.js.map +1 -1
  256. package/dist/engine/indicators/state/obvState.d.ts.map +1 -1
  257. package/dist/engine/indicators/state/obvState.js.map +1 -1
  258. package/dist/engine/indicators/state/parkinsonState.d.ts.map +1 -1
  259. package/dist/engine/indicators/state/parkinsonState.js +5 -1
  260. package/dist/engine/indicators/state/parkinsonState.js.map +1 -1
  261. package/dist/engine/indicators/state/pivotState.d.ts.map +1 -1
  262. package/dist/engine/indicators/state/pivotState.js.map +1 -1
  263. package/dist/engine/indicators/state/pvtState.d.ts.map +1 -1
  264. package/dist/engine/indicators/state/pvtState.js.map +1 -1
  265. package/dist/engine/indicators/state/rocState.d.ts.map +1 -1
  266. package/dist/engine/indicators/state/rocState.js.map +1 -1
  267. package/dist/engine/indicators/state/rsiState.d.ts.map +1 -1
  268. package/dist/engine/indicators/state/rsiState.js.map +1 -1
  269. package/dist/engine/indicators/state/sarState.d.ts.map +1 -1
  270. package/dist/engine/indicators/state/sarState.js.map +1 -1
  271. package/dist/engine/indicators/state/stochState.d.ts.map +1 -1
  272. package/dist/engine/indicators/state/stochState.js.map +1 -1
  273. package/dist/engine/indicators/state/structureState.d.ts.map +1 -1
  274. package/dist/engine/indicators/state/structureState.js.map +1 -1
  275. package/dist/engine/indicators/state/supertrendState.d.ts.map +1 -1
  276. package/dist/engine/indicators/state/supertrendState.js.map +1 -1
  277. package/dist/engine/indicators/state/temaState.d.ts.map +1 -1
  278. package/dist/engine/indicators/state/temaState.js.map +1 -1
  279. package/dist/engine/indicators/state/trixState.d.ts.map +1 -1
  280. package/dist/engine/indicators/state/trixState.js.map +1 -1
  281. package/dist/engine/indicators/state/vmaState.d.ts.map +1 -1
  282. package/dist/engine/indicators/state/vmaState.js.map +1 -1
  283. package/dist/engine/indicators/state/volumeProfileState.d.ts.map +1 -1
  284. package/dist/engine/indicators/state/volumeProfileState.js.map +1 -1
  285. package/dist/engine/indicators/state/vwapState.d.ts.map +1 -1
  286. package/dist/engine/indicators/state/vwapState.js.map +1 -1
  287. package/dist/engine/indicators/state/wmaState.d.ts.map +1 -1
  288. package/dist/engine/indicators/state/wmaState.js.map +1 -1
  289. package/dist/engine/indicators/state/wmsrState.d.ts.map +1 -1
  290. package/dist/engine/indicators/state/wmsrState.js.map +1 -1
  291. package/dist/engine/indicators/state/zonesState.d.ts.map +1 -1
  292. package/dist/engine/indicators/state/zonesState.js.map +1 -1
  293. package/dist/engine/indicators/stateComposer.d.ts.map +1 -1
  294. package/dist/engine/indicators/stateComposer.js +1 -1
  295. package/dist/engine/indicators/stateComposer.js.map +1 -1
  296. package/dist/engine/indicators/visibleStateComposers.d.ts.map +1 -1
  297. package/dist/engine/indicators/visibleStateComposers.js +9 -11
  298. package/dist/engine/indicators/visibleStateComposers.js.map +1 -1
  299. package/dist/engine/indicators/workerProtocol.d.ts.map +1 -1
  300. package/dist/engine/indicators/workerProtocol.js.map +1 -1
  301. package/dist/engine/layout/chartPaneLayout.d.ts.map +1 -1
  302. package/dist/engine/layout/chartPaneLayout.js +2 -5
  303. package/dist/engine/layout/chartPaneLayout.js.map +1 -1
  304. package/dist/engine/layout/pane.d.ts.map +1 -1
  305. package/dist/engine/layout/pane.js +3 -1
  306. package/dist/engine/layout/pane.js.map +1 -1
  307. package/dist/engine/marker/registry.d.ts.map +1 -1
  308. package/dist/engine/marker/registry.js +8 -6
  309. package/dist/engine/marker/registry.js.map +1 -1
  310. package/dist/engine/modes/kLineMode.d.ts.map +1 -1
  311. package/dist/engine/modes/kLineMode.js +2 -4
  312. package/dist/engine/modes/kLineMode.js.map +1 -1
  313. package/dist/engine/modes/timeShareMode.d.ts.map +1 -1
  314. package/dist/engine/modes/timeShareMode.js.map +1 -1
  315. package/dist/engine/modes/types.d.ts.map +1 -1
  316. package/dist/engine/paneRenderer.d.ts.map +1 -1
  317. package/dist/engine/paneRenderer.js.map +1 -1
  318. package/dist/engine/render/chartRenderer.d.ts +11 -2
  319. package/dist/engine/render/chartRenderer.d.ts.map +1 -1
  320. package/dist/engine/render/chartRenderer.js +204 -96
  321. package/dist/engine/render/chartRenderer.js.map +1 -1
  322. package/dist/engine/render/layers/candleLayer.d.ts +4 -0
  323. package/dist/engine/render/layers/candleLayer.d.ts.map +1 -0
  324. package/dist/engine/render/layers/candleLayer.js +7 -0
  325. package/dist/engine/render/layers/candleLayer.js.map +1 -0
  326. package/dist/engine/render/layers/comparisonLineLayer.d.ts +4 -0
  327. package/dist/engine/render/layers/comparisonLineLayer.d.ts.map +1 -0
  328. package/dist/engine/render/layers/comparisonLineLayer.js +7 -0
  329. package/dist/engine/render/layers/comparisonLineLayer.js.map +1 -0
  330. package/dist/engine/render/layers/crosshairLayer.d.ts +14 -0
  331. package/dist/engine/render/layers/crosshairLayer.d.ts.map +1 -0
  332. package/dist/engine/render/layers/crosshairLayer.js +6 -0
  333. package/dist/engine/render/layers/crosshairLayer.js.map +1 -0
  334. package/dist/engine/render/layers/customMarkersLayer.d.ts +4 -0
  335. package/dist/engine/render/layers/customMarkersLayer.d.ts.map +1 -0
  336. package/dist/engine/render/layers/customMarkersLayer.js +6 -0
  337. package/dist/engine/render/layers/customMarkersLayer.js.map +1 -0
  338. package/dist/engine/render/layers/extremaMarkersLayer.d.ts +4 -0
  339. package/dist/engine/render/layers/extremaMarkersLayer.d.ts.map +1 -0
  340. package/dist/engine/render/layers/extremaMarkersLayer.js +6 -0
  341. package/dist/engine/render/layers/extremaMarkersLayer.js.map +1 -0
  342. package/dist/engine/render/layers/gridLinesLayer.d.ts +4 -0
  343. package/dist/engine/render/layers/gridLinesLayer.d.ts.map +1 -0
  344. package/dist/engine/render/layers/gridLinesLayer.js +6 -0
  345. package/dist/engine/render/layers/gridLinesLayer.js.map +1 -0
  346. package/dist/engine/render/layers/lastPriceLabelLayer.d.ts +4 -0
  347. package/dist/engine/render/layers/lastPriceLabelLayer.d.ts.map +1 -0
  348. package/dist/engine/render/layers/lastPriceLabelLayer.js +6 -0
  349. package/dist/engine/render/layers/lastPriceLabelLayer.js.map +1 -0
  350. package/dist/engine/render/layers/lastPriceLineLayer.d.ts +4 -0
  351. package/dist/engine/render/layers/lastPriceLineLayer.d.ts.map +1 -0
  352. package/dist/engine/render/layers/lastPriceLineLayer.js +7 -0
  353. package/dist/engine/render/layers/lastPriceLineLayer.js.map +1 -0
  354. package/dist/engine/render/layers/leftYAxisLayer.d.ts +12 -0
  355. package/dist/engine/render/layers/leftYAxisLayer.d.ts.map +1 -0
  356. package/dist/engine/render/layers/leftYAxisLayer.js +6 -0
  357. package/dist/engine/render/layers/leftYAxisLayer.js.map +1 -0
  358. package/dist/engine/render/layers/mainIndicatorLegendLayer.d.ts +6 -0
  359. package/dist/engine/render/layers/mainIndicatorLegendLayer.d.ts.map +1 -0
  360. package/dist/engine/render/layers/mainIndicatorLegendLayer.js +13 -0
  361. package/dist/engine/render/layers/mainIndicatorLegendLayer.js.map +1 -0
  362. package/dist/engine/render/layers/yAxisLayer.d.ts +12 -0
  363. package/dist/engine/render/layers/yAxisLayer.d.ts.map +1 -0
  364. package/dist/engine/render/layers/yAxisLayer.js +6 -0
  365. package/dist/engine/render/layers/yAxisLayer.js.map +1 -0
  366. package/dist/engine/renderers/Indicator/atr.js +8 -3
  367. package/dist/engine/renderers/Indicator/atr.js.map +1 -1
  368. package/dist/engine/renderers/Indicator/boll.d.ts.map +1 -1
  369. package/dist/engine/renderers/Indicator/boll.js +27 -6
  370. package/dist/engine/renderers/Indicator/boll.js.map +1 -1
  371. package/dist/engine/renderers/Indicator/cci.js +4 -4
  372. package/dist/engine/renderers/Indicator/cci.js.map +1 -1
  373. package/dist/engine/renderers/Indicator/chaikinVol.js +17 -5
  374. package/dist/engine/renderers/Indicator/chaikinVol.js.map +1 -1
  375. package/dist/engine/renderers/Indicator/cmf.js +13 -3
  376. package/dist/engine/renderers/Indicator/cmf.js.map +1 -1
  377. package/dist/engine/renderers/Indicator/dema.js +16 -4
  378. package/dist/engine/renderers/Indicator/dema.js.map +1 -1
  379. package/dist/engine/renderers/Indicator/donchian.js +26 -7
  380. package/dist/engine/renderers/Indicator/donchian.js.map +1 -1
  381. package/dist/engine/renderers/Indicator/ene.d.ts.map +1 -1
  382. package/dist/engine/renderers/Indicator/ene.js +7 -3
  383. package/dist/engine/renderers/Indicator/ene.js.map +1 -1
  384. package/dist/engine/renderers/Indicator/expma.d.ts.map +1 -1
  385. package/dist/engine/renderers/Indicator/expma.js +8 -5
  386. package/dist/engine/renderers/Indicator/expma.js.map +1 -1
  387. package/dist/engine/renderers/Indicator/fastk.js.map +1 -1
  388. package/dist/engine/renderers/Indicator/fib.js +26 -7
  389. package/dist/engine/renderers/Indicator/fib.js.map +1 -1
  390. package/dist/engine/renderers/Indicator/hma.js +16 -4
  391. package/dist/engine/renderers/Indicator/hma.js.map +1 -1
  392. package/dist/engine/renderers/Indicator/hv.js +18 -4
  393. package/dist/engine/renderers/Indicator/hv.js.map +1 -1
  394. package/dist/engine/renderers/Indicator/ichimoku.js +52 -8
  395. package/dist/engine/renderers/Indicator/ichimoku.js.map +1 -1
  396. package/dist/engine/renderers/Indicator/index.d.ts.map +1 -1
  397. package/dist/engine/renderers/Indicator/index.js.map +1 -1
  398. package/dist/engine/renderers/Indicator/indicatorCatalog.d.ts.map +1 -1
  399. package/dist/engine/renderers/Indicator/indicatorCatalog.js +661 -66
  400. package/dist/engine/renderers/Indicator/indicatorCatalog.js.map +1 -1
  401. package/dist/engine/renderers/Indicator/kama.js +16 -4
  402. package/dist/engine/renderers/Indicator/kama.js.map +1 -1
  403. package/dist/engine/renderers/Indicator/keltner.js +37 -7
  404. package/dist/engine/renderers/Indicator/keltner.js.map +1 -1
  405. package/dist/engine/renderers/Indicator/kst.js +22 -5
  406. package/dist/engine/renderers/Indicator/kst.js.map +1 -1
  407. package/dist/engine/renderers/Indicator/ma.d.ts.map +1 -1
  408. package/dist/engine/renderers/Indicator/ma.js +26 -10
  409. package/dist/engine/renderers/Indicator/ma.js.map +1 -1
  410. package/dist/engine/renderers/Indicator/macd.js +29 -10
  411. package/dist/engine/renderers/Indicator/macd.js.map +1 -1
  412. package/dist/engine/renderers/Indicator/mainIndicatorLegend.d.ts.map +1 -1
  413. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js +3 -2
  414. package/dist/engine/renderers/Indicator/mainIndicatorLegend.js.map +1 -1
  415. package/dist/engine/renderers/Indicator/mfi.js +13 -3
  416. package/dist/engine/renderers/Indicator/mfi.js.map +1 -1
  417. package/dist/engine/renderers/Indicator/mom.js +1 -1
  418. package/dist/engine/renderers/Indicator/mom.js.map +1 -1
  419. package/dist/engine/renderers/Indicator/obv.js +12 -3
  420. package/dist/engine/renderers/Indicator/obv.js.map +1 -1
  421. package/dist/engine/renderers/Indicator/parkinson.js +21 -5
  422. package/dist/engine/renderers/Indicator/parkinson.js.map +1 -1
  423. package/dist/engine/renderers/Indicator/pivot.js +42 -6
  424. package/dist/engine/renderers/Indicator/pivot.js.map +1 -1
  425. package/dist/engine/renderers/Indicator/pvt.js +12 -3
  426. package/dist/engine/renderers/Indicator/pvt.js.map +1 -1
  427. package/dist/engine/renderers/Indicator/roc.js +13 -3
  428. package/dist/engine/renderers/Indicator/roc.js.map +1 -1
  429. package/dist/engine/renderers/Indicator/rsi.js +30 -16
  430. package/dist/engine/renderers/Indicator/rsi.js.map +1 -1
  431. package/dist/engine/renderers/Indicator/sar.js +15 -8
  432. package/dist/engine/renderers/Indicator/sar.js.map +1 -1
  433. package/dist/engine/renderers/Indicator/scale/atr_scale.d.ts.map +1 -1
  434. package/dist/engine/renderers/Indicator/scale/atr_scale.js.map +1 -1
  435. package/dist/engine/renderers/Indicator/scale/cci_scale.d.ts.map +1 -1
  436. package/dist/engine/renderers/Indicator/scale/cci_scale.js.map +1 -1
  437. package/dist/engine/renderers/Indicator/scale/fastk_scale.d.ts.map +1 -1
  438. package/dist/engine/renderers/Indicator/scale/fastk_scale.js.map +1 -1
  439. package/dist/engine/renderers/Indicator/scale/indicator_scale.d.ts.map +1 -1
  440. package/dist/engine/renderers/Indicator/scale/indicator_scale.js +1 -1
  441. package/dist/engine/renderers/Indicator/scale/indicator_scale.js.map +1 -1
  442. package/dist/engine/renderers/Indicator/scale/kst_scale.d.ts.map +1 -1
  443. package/dist/engine/renderers/Indicator/scale/kst_scale.js.map +1 -1
  444. package/dist/engine/renderers/Indicator/scale/macd_scale.d.ts.map +1 -1
  445. package/dist/engine/renderers/Indicator/scale/macd_scale.js.map +1 -1
  446. package/dist/engine/renderers/Indicator/scale/mom_scale.d.ts.map +1 -1
  447. package/dist/engine/renderers/Indicator/scale/mom_scale.js.map +1 -1
  448. package/dist/engine/renderers/Indicator/scale/rsi_scale.d.ts.map +1 -1
  449. package/dist/engine/renderers/Indicator/scale/rsi_scale.js.map +1 -1
  450. package/dist/engine/renderers/Indicator/scale/stoch_scale.d.ts.map +1 -1
  451. package/dist/engine/renderers/Indicator/scale/stoch_scale.js.map +1 -1
  452. package/dist/engine/renderers/Indicator/scale/volume_scale.d.ts.map +1 -1
  453. package/dist/engine/renderers/Indicator/scale/volume_scale.js.map +1 -1
  454. package/dist/engine/renderers/Indicator/scale/wmsr_scale.d.ts.map +1 -1
  455. package/dist/engine/renderers/Indicator/scale/wmsr_scale.js.map +1 -1
  456. package/dist/engine/renderers/Indicator/shared/dashedLines.d.ts.map +1 -1
  457. package/dist/engine/renderers/Indicator/shared/dashedLines.js +2 -2
  458. package/dist/engine/renderers/Indicator/shared/dashedLines.js.map +1 -1
  459. package/dist/engine/renderers/Indicator/shared/titleInfo.d.ts.map +1 -1
  460. package/dist/engine/renderers/Indicator/shared/titleInfo.js +3 -1
  461. package/dist/engine/renderers/Indicator/shared/titleInfo.js.map +1 -1
  462. package/dist/engine/renderers/Indicator/stoch.js +11 -2
  463. package/dist/engine/renderers/Indicator/stoch.js.map +1 -1
  464. package/dist/engine/renderers/Indicator/structure.js +46 -8
  465. package/dist/engine/renderers/Indicator/structure.js.map +1 -1
  466. package/dist/engine/renderers/Indicator/supertrend.js +26 -8
  467. package/dist/engine/renderers/Indicator/supertrend.js.map +1 -1
  468. package/dist/engine/renderers/Indicator/tema.js +16 -4
  469. package/dist/engine/renderers/Indicator/tema.js.map +1 -1
  470. package/dist/engine/renderers/Indicator/trix.js +12 -3
  471. package/dist/engine/renderers/Indicator/trix.js.map +1 -1
  472. package/dist/engine/renderers/Indicator/vma.js +13 -3
  473. package/dist/engine/renderers/Indicator/vma.js.map +1 -1
  474. package/dist/engine/renderers/Indicator/volumeProfile.js +24 -7
  475. package/dist/engine/renderers/Indicator/volumeProfile.js.map +1 -1
  476. package/dist/engine/renderers/Indicator/vwap.js +12 -3
  477. package/dist/engine/renderers/Indicator/vwap.js.map +1 -1
  478. package/dist/engine/renderers/Indicator/wma.js +16 -4
  479. package/dist/engine/renderers/Indicator/wma.js.map +1 -1
  480. package/dist/engine/renderers/Indicator/wmsr.js +3 -3
  481. package/dist/engine/renderers/Indicator/wmsr.js.map +1 -1
  482. package/dist/engine/renderers/Indicator/zones.js +31 -11
  483. package/dist/engine/renderers/Indicator/zones.js.map +1 -1
  484. package/dist/engine/renderers/candle.d.ts.map +1 -1
  485. package/dist/engine/renderers/candle.js +27 -21
  486. package/dist/engine/renderers/candle.js.map +1 -1
  487. package/dist/engine/renderers/comparisonLine.d.ts.map +1 -1
  488. package/dist/engine/renderers/comparisonLine.js +3 -1
  489. package/dist/engine/renderers/comparisonLine.js.map +1 -1
  490. package/dist/engine/renderers/crosshair.d.ts.map +1 -1
  491. package/dist/engine/renderers/crosshair.js.map +1 -1
  492. package/dist/engine/renderers/customMarkers.d.ts.map +1 -1
  493. package/dist/engine/renderers/customMarkers.js +2 -2
  494. package/dist/engine/renderers/customMarkers.js.map +1 -1
  495. package/dist/engine/renderers/extremaMarkers.d.ts.map +1 -1
  496. package/dist/engine/renderers/extremaMarkers.js +6 -2
  497. package/dist/engine/renderers/extremaMarkers.js.map +1 -1
  498. package/dist/engine/renderers/gridLines.d.ts.map +1 -1
  499. package/dist/engine/renderers/gridLines.js.map +1 -1
  500. package/dist/engine/renderers/lastPrice.d.ts.map +1 -1
  501. package/dist/engine/renderers/lastPrice.js +6 -2
  502. package/dist/engine/renderers/lastPrice.js.map +1 -1
  503. package/dist/engine/renderers/leftYAxis.d.ts.map +1 -1
  504. package/dist/engine/renderers/leftYAxis.js +7 -3
  505. package/dist/engine/renderers/leftYAxis.js.map +1 -1
  506. package/dist/engine/renderers/paneTitle.d.ts.map +1 -1
  507. package/dist/engine/renderers/paneTitle.js.map +1 -1
  508. package/dist/engine/renderers/subVolume.js +8 -5
  509. package/dist/engine/renderers/subVolume.js.map +1 -1
  510. package/dist/engine/renderers/timeAxis.d.ts.map +1 -1
  511. package/dist/engine/renderers/timeAxis.js.map +1 -1
  512. package/dist/engine/renderers/timeShare.d.ts.map +1 -1
  513. package/dist/engine/renderers/timeShare.js +2 -5
  514. package/dist/engine/renderers/timeShare.js.map +1 -1
  515. package/dist/engine/renderers/webgl/candleSurface.d.ts.map +1 -1
  516. package/dist/engine/renderers/webgl/candleSurface.js +13 -14
  517. package/dist/engine/renderers/webgl/candleSurface.js.map +1 -1
  518. package/dist/engine/renderers/webgl/sharedWebGLSurface.d.ts +20 -0
  519. package/dist/engine/renderers/webgl/sharedWebGLSurface.d.ts.map +1 -1
  520. package/dist/engine/renderers/webgl/sharedWebGLSurface.js.map +1 -1
  521. package/dist/engine/renderers/yAxis.d.ts.map +1 -1
  522. package/dist/engine/renderers/yAxis.js +1 -1
  523. package/dist/engine/renderers/yAxis.js.map +1 -1
  524. package/dist/engine/scale/logFormula.d.ts.map +1 -1
  525. package/dist/engine/scale/logFormula.js.map +1 -1
  526. package/dist/engine/scale/price.js.map +1 -1
  527. package/dist/engine/scale/priceScale.d.ts.map +1 -1
  528. package/dist/engine/scale/priceScale.js +1 -1
  529. package/dist/engine/scale/priceScale.js.map +1 -1
  530. package/dist/engine/subPaneManager.d.ts +11 -1
  531. package/dist/engine/subPaneManager.d.ts.map +1 -1
  532. package/dist/engine/subPaneManager.js +59 -6
  533. package/dist/engine/subPaneManager.js.map +1 -1
  534. package/dist/engine/theme/fonts.js.map +1 -1
  535. package/dist/engine/utils/chartZoomController.d.ts.map +1 -1
  536. package/dist/engine/utils/chartZoomController.js.map +1 -1
  537. package/dist/engine/utils/klineConfig.js.map +1 -1
  538. package/dist/engine/utils/tickCount.js.map +1 -1
  539. package/dist/engine/utils/tickPosition.d.ts.map +1 -1
  540. package/dist/engine/utils/tickPosition.js.map +1 -1
  541. package/dist/engine/viewport/chartViewportManager.d.ts.map +1 -1
  542. package/dist/engine/viewport/chartViewportManager.js +16 -13
  543. package/dist/engine/viewport/chartViewportManager.js.map +1 -1
  544. package/dist/engine/viewport/viewport.d.ts.map +1 -1
  545. package/dist/engine/viewport/viewport.js.map +1 -1
  546. package/dist/errors-help.d.ts.map +1 -1
  547. package/dist/errors-help.js +1 -0
  548. package/dist/errors-help.js.map +1 -1
  549. package/dist/errors.d.ts +1 -1
  550. package/dist/errors.d.ts.map +1 -1
  551. package/dist/errors.js.map +1 -1
  552. package/dist/index.d.ts +1 -1
  553. package/dist/index.d.ts.map +1 -1
  554. package/dist/index.js +1 -1
  555. package/dist/index.js.map +1 -1
  556. package/dist/indicators/alma.d.ts.map +1 -1
  557. package/dist/indicators/alma.js.map +1 -1
  558. package/dist/indicators/awesomeOscillator.d.ts.map +1 -1
  559. package/dist/indicators/awesomeOscillator.js.map +1 -1
  560. package/dist/indicators/dpo.d.ts.map +1 -1
  561. package/dist/indicators/dpo.js.map +1 -1
  562. package/dist/indicators/fisherTransform.d.ts.map +1 -1
  563. package/dist/indicators/fisherTransform.js.map +1 -1
  564. package/dist/indicators/frama.d.ts.map +1 -1
  565. package/dist/indicators/frama.js.map +1 -1
  566. package/dist/indicators/index.d.ts +4 -4
  567. package/dist/indicators/index.d.ts.map +1 -1
  568. package/dist/indicators/index.js +4 -4
  569. package/dist/indicators/index.js.map +1 -1
  570. package/dist/indicators/lsma.d.ts.map +1 -1
  571. package/dist/indicators/lsma.js.map +1 -1
  572. package/dist/indicators/schaffTrendCycle.d.ts.map +1 -1
  573. package/dist/indicators/schaffTrendCycle.js.map +1 -1
  574. package/dist/indicators/stochRSI.d.ts.map +1 -1
  575. package/dist/indicators/stochRSI.js.map +1 -1
  576. package/dist/indicators/t3.d.ts.map +1 -1
  577. package/dist/indicators/t3.js +1 -4
  578. package/dist/indicators/t3.js.map +1 -1
  579. package/dist/indicators/ultimateOscillator.d.ts.map +1 -1
  580. package/dist/indicators/ultimateOscillator.js.map +1 -1
  581. package/dist/indicators/vidya.d.ts.map +1 -1
  582. package/dist/indicators/vidya.js.map +1 -1
  583. package/dist/indicators/zlema.d.ts.map +1 -1
  584. package/dist/indicators/zlema.js.map +1 -1
  585. package/dist/input/gesture.d.ts.map +1 -1
  586. package/dist/input/gesture.js +2 -6
  587. package/dist/input/gesture.js.map +1 -1
  588. package/dist/input/index.d.ts.map +1 -1
  589. package/dist/input/index.js.map +1 -1
  590. package/dist/input/keyboard.d.ts.map +1 -1
  591. package/dist/input/keyboard.js.map +1 -1
  592. package/dist/mcp/chartBridge.d.ts.map +1 -1
  593. package/dist/mcp/chartBridge.js.map +1 -1
  594. package/dist/plugin/HookSystem.d.ts.map +1 -1
  595. package/dist/plugin/HookSystem.js.map +1 -1
  596. package/dist/plugin/PluginHost.d.ts.map +1 -1
  597. package/dist/plugin/PluginHost.js.map +1 -1
  598. package/dist/plugin/StateStore.js +1 -1
  599. package/dist/plugin/StateStore.js.map +1 -1
  600. package/dist/plugin/rendererPluginManager.d.ts.map +1 -1
  601. package/dist/plugin/rendererPluginManager.js.map +1 -1
  602. package/dist/plugin/types.d.ts.map +1 -1
  603. package/dist/plugin/types.js.map +1 -1
  604. package/dist/reactivity/signal.d.ts.map +1 -1
  605. package/dist/reactivity/signal.js.map +1 -1
  606. package/dist/render/Renderer.d.ts.map +1 -1
  607. package/dist/render/SurfaceBackend.d.ts.map +1 -1
  608. package/dist/render/createWebGLRenderer.d.ts +5 -0
  609. package/dist/render/createWebGLRenderer.d.ts.map +1 -0
  610. package/dist/render/createWebGLRenderer.js +233 -0
  611. package/dist/render/createWebGLRenderer.js.map +1 -0
  612. package/dist/render/createWebGLSurfaceBackend.d.ts +4 -0
  613. package/dist/render/createWebGLSurfaceBackend.d.ts.map +1 -0
  614. package/dist/render/createWebGLSurfaceBackend.js +37 -0
  615. package/dist/render/createWebGLSurfaceBackend.js.map +1 -0
  616. package/dist/render/index.d.ts +5 -6
  617. package/dist/render/index.d.ts.map +1 -1
  618. package/dist/render/index.js +4 -6
  619. package/dist/render/index.js.map +1 -1
  620. package/dist/renderer-tier/detectRendererTier.d.ts.map +1 -1
  621. package/dist/renderer-tier/detectRendererTier.js.map +1 -1
  622. package/dist/renderer-tier/index.d.ts.map +1 -1
  623. package/dist/renderer-tier/index.js.map +1 -1
  624. package/dist/renderer-tier/selectBackend.d.ts.map +1 -1
  625. package/dist/renderer-tier/selectBackend.js +1 -5
  626. package/dist/renderer-tier/selectBackend.js.map +1 -1
  627. package/dist/renderer-tier/types.d.ts.map +1 -1
  628. package/dist/renderer-tier/types.js.map +1 -1
  629. package/dist/replay/createReplayController.d.ts.map +1 -1
  630. package/dist/replay/createReplayController.js +3 -5
  631. package/dist/replay/createReplayController.js.map +1 -1
  632. package/dist/replay/index.d.ts +1 -1
  633. package/dist/replay/index.d.ts.map +1 -1
  634. package/dist/replay/index.js +1 -1
  635. package/dist/replay/index.js.map +1 -1
  636. package/dist/replay/timeline.d.ts.map +1 -1
  637. package/dist/replay/timeline.js.map +1 -1
  638. package/dist/replay/types.d.ts.map +1 -1
  639. package/dist/scale/anchoredZoom.d.ts.map +1 -1
  640. package/dist/scale/anchoredZoom.js.map +1 -1
  641. package/dist/scale/createPriceScale.d.ts.map +1 -1
  642. package/dist/scale/createPriceScale.js.map +1 -1
  643. package/dist/scale/createTimeScale.d.ts.map +1 -1
  644. package/dist/scale/createTimeScale.js.map +1 -1
  645. package/dist/scale/index.d.ts.map +1 -1
  646. package/dist/scale/index.js.map +1 -1
  647. package/dist/scale/originShift.d.ts.map +1 -1
  648. package/dist/scale/originShift.js.map +1 -1
  649. package/dist/scale/types.d.ts.map +1 -1
  650. package/dist/scene/createLayerFromPlugin.d.ts +4 -0
  651. package/dist/scene/createLayerFromPlugin.d.ts.map +1 -0
  652. package/dist/scene/createLayerFromPlugin.js +45 -0
  653. package/dist/scene/createLayerFromPlugin.js.map +1 -0
  654. package/dist/scene/createScene.d.ts.map +1 -1
  655. package/dist/scene/createScene.js +6 -3
  656. package/dist/scene/createScene.js.map +1 -1
  657. package/dist/scene/index.d.ts +4 -3
  658. package/dist/scene/index.d.ts.map +1 -1
  659. package/dist/scene/index.js +2 -1
  660. package/dist/scene/index.js.map +1 -1
  661. package/dist/scene/layerRegistry.d.ts.map +1 -1
  662. package/dist/scene/layerRegistry.js.map +1 -1
  663. package/dist/scene/types.d.ts +8 -3
  664. package/dist/scene/types.d.ts.map +1 -1
  665. package/dist/scheduler/createFrameBudget.d.ts.map +1 -1
  666. package/dist/scheduler/createFrameBudget.js.map +1 -1
  667. package/dist/scheduler/index.d.ts.map +1 -1
  668. package/dist/scheduler/index.js.map +1 -1
  669. package/dist/semantic/controller.d.ts.map +1 -1
  670. package/dist/semantic/controller.js +8 -3
  671. package/dist/semantic/controller.js.map +1 -1
  672. package/dist/semantic/index.d.ts +1 -1
  673. package/dist/semantic/index.d.ts.map +1 -1
  674. package/dist/semantic/index.js +1 -1
  675. package/dist/semantic/index.js.map +1 -1
  676. package/dist/semantic/schema.json +16 -4
  677. package/dist/semantic/validator.d.ts.map +1 -1
  678. package/dist/semantic/validator.js +4 -4
  679. package/dist/semantic/validator.js.map +1 -1
  680. package/dist/tokens/colorPresetSettings.d.ts.map +1 -1
  681. package/dist/tokens/colorPresetSettings.js +3 -1
  682. package/dist/tokens/colorPresetSettings.js.map +1 -1
  683. package/dist/tokens/index.d.ts.map +1 -1
  684. package/dist/tokens/index.js.map +1 -1
  685. package/dist/tokens/mergeTheme.js.map +1 -1
  686. package/dist/tokens/theme-base.d.ts.map +1 -1
  687. package/dist/tokens/theme-base.js.map +1 -1
  688. package/dist/tokens/theme-china.d.ts.map +1 -1
  689. package/dist/tokens/theme-china.js.map +1 -1
  690. package/dist/tokens/theme-dark.js.map +1 -1
  691. package/dist/tokens/theme-light.js.map +1 -1
  692. package/dist/tokens/themeToCssVars.d.ts.map +1 -1
  693. package/dist/tokens/themeToCssVars.js.map +1 -1
  694. package/dist/tokens/types.d.ts.map +1 -1
  695. package/dist/types/price.d.ts.map +1 -1
  696. package/dist/types/price.js +5 -1
  697. package/dist/types/price.js.map +1 -1
  698. package/dist/utils/dateFormat.d.ts.map +1 -1
  699. package/dist/utils/dateFormat.js.map +1 -1
  700. package/dist/utils/kLineDraw/axis.d.ts.map +1 -1
  701. package/dist/utils/kLineDraw/axis.js +3 -3
  702. package/dist/utils/kLineDraw/axis.js.map +1 -1
  703. package/dist/utils/priceToY.d.ts.map +1 -1
  704. package/dist/utils/priceToY.js.map +1 -1
  705. package/dist/utils/volumePrice.d.ts.map +1 -1
  706. package/dist/utils/volumePrice.js +1 -1
  707. package/dist/utils/volumePrice.js.map +1 -1
  708. package/dist/version.d.ts +1 -1
  709. package/dist/version.d.ts.map +1 -1
  710. package/dist/version.js +1 -1
  711. package/dist/version.js.map +1 -1
  712. package/package.json +1 -1
  713. package/src/__bench__/indicators.bench.ts +129 -129
  714. package/src/__bench__/orderBookHeatmap.bench.ts +32 -32
  715. package/src/__bench__/scale.bench.ts +56 -56
  716. package/src/__bench__/signal.bench.ts +23 -23
  717. package/src/__bench__/volumeProfile.bench.ts +35 -35
  718. package/src/__tests__/depthPipeline.test.ts +315 -0
  719. package/src/__tests__/errors-help.test.ts +132 -135
  720. package/src/__tests__/errors.test.ts +140 -144
  721. package/src/__tests__/signal.test.ts +100 -100
  722. package/src/alerts/__tests__/controller.test.ts +173 -173
  723. package/src/alerts/__tests__/predicates.test.ts +287 -287
  724. package/src/alerts/__tests__/ruleSchema.test.ts +145 -148
  725. package/src/alerts/createAlertController.ts +236 -255
  726. package/src/alerts/index.ts +10 -14
  727. package/src/alerts/predicates.ts +152 -158
  728. package/src/alerts/ruleSchema.ts +181 -186
  729. package/src/alerts/types.ts +103 -103
  730. package/src/chartTypes/__tests__/heikinAshi.test.ts +105 -105
  731. package/src/chartTypes/__tests__/pointAndFigure.test.ts +147 -147
  732. package/src/chartTypes/__tests__/rangeBars.test.ts +127 -127
  733. package/src/chartTypes/__tests__/renko.test.ts +144 -138
  734. package/src/chartTypes/heikinAshi.ts +59 -55
  735. package/src/chartTypes/pointAndFigure.ts +171 -165
  736. package/src/chartTypes/rangeBars.ts +213 -213
  737. package/src/chartTypes/renko.ts +199 -193
  738. package/src/chartTypes/types.ts +29 -29
  739. package/src/components/anchoredVwap/__tests__/computeAnchoredVwap.test.ts +261 -268
  740. package/src/components/anchoredVwap/__tests__/controller.test.ts +324 -343
  741. package/src/components/anchoredVwap/computeAnchoredVwap.ts +81 -81
  742. package/src/components/anchoredVwap/createAnchoredVwapController.ts +246 -279
  743. package/src/components/anchoredVwap/index.ts +5 -5
  744. package/src/components/anchoredVwap/types.ts +88 -91
  745. package/src/components/crosshairSync/__tests__/crosshairSync.test.ts +174 -174
  746. package/src/components/crosshairSync/createCrosshairSync.ts +113 -113
  747. package/src/components/crosshairSync/index.ts +3 -3
  748. package/src/components/footprint/__tests__/aggressor.test.ts +110 -106
  749. package/src/components/footprint/__tests__/controller.test.ts +97 -97
  750. package/src/components/footprint/__tests__/perBarStats.test.ts +92 -92
  751. package/src/components/footprint/aggressor.ts +55 -60
  752. package/src/components/footprint/createFootprintController.ts +262 -269
  753. package/src/components/footprint/index.ts +8 -16
  754. package/src/components/footprint/perBarStats.ts +50 -52
  755. package/src/components/footprint/types.ts +92 -92
  756. package/src/components/mtfOverlay/__tests__/alignToBaseIndex.test.ts +70 -70
  757. package/src/components/mtfOverlay/__tests__/controller.test.ts +134 -134
  758. package/src/components/mtfOverlay/__tests__/resampleBars.test.ts +80 -80
  759. package/src/components/mtfOverlay/alignToBaseIndex.ts +55 -55
  760. package/src/components/mtfOverlay/createMtfController.ts +149 -148
  761. package/src/components/mtfOverlay/index.ts +5 -5
  762. package/src/components/mtfOverlay/resampleBars.ts +88 -82
  763. package/src/components/mtfOverlay/types.ts +70 -73
  764. package/src/components/orderBookHeatmap/__tests__/controller.test.ts +337 -204
  765. package/src/components/orderBookHeatmap/__tests__/deltaArchive.test.ts +71 -71
  766. package/src/components/orderBookHeatmap/__tests__/logColorScale.test.ts +56 -56
  767. package/src/components/orderBookHeatmap/__tests__/orderBookState.test.ts +97 -97
  768. package/src/components/orderBookHeatmap/__tests__/snapshotRing.test.ts +39 -39
  769. package/src/components/orderBookHeatmap/computeShader.wgsl.md +3 -3
  770. package/src/components/orderBookHeatmap/createHeatmapController.ts +239 -213
  771. package/src/components/orderBookHeatmap/createOrderBookState.ts +77 -83
  772. package/src/components/orderBookHeatmap/deltaArchive.ts +70 -73
  773. package/src/components/orderBookHeatmap/index.ts +11 -11
  774. package/src/components/orderBookHeatmap/logColorScale.ts +52 -46
  775. package/src/components/orderBookHeatmap/snapshotRing.ts +43 -40
  776. package/src/components/orderBookHeatmap/types.ts +86 -76
  777. package/src/components/volumeProfile/__tests__/binning.test.ts +98 -98
  778. package/src/components/volumeProfile/__tests__/poc.test.ts +21 -21
  779. package/src/components/volumeProfile/__tests__/valueArea.test.ts +140 -140
  780. package/src/components/volumeProfile/binning.ts +67 -67
  781. package/src/components/volumeProfile/createVolumeProfileController.ts +143 -156
  782. package/src/components/volumeProfile/index.ts +6 -6
  783. package/src/components/volumeProfile/poc.ts +13 -13
  784. package/src/components/volumeProfile/types.ts +67 -67
  785. package/src/components/volumeProfile/valueArea.ts +119 -119
  786. package/src/config/chartSettings.ts +60 -14
  787. package/src/controllers/__tests__/drawing.test.ts +164 -170
  788. package/src/controllers/__tests__/indicatorSelector.test.ts +418 -405
  789. package/src/controllers/__tests__/toolbar.test.ts +174 -174
  790. package/src/controllers/createChartController.ts +911 -881
  791. package/src/controllers/createDrawingController.ts +54 -60
  792. package/src/controllers/createIndicatorSelectorController.ts +212 -228
  793. package/src/controllers/createToolbarController.ts +99 -103
  794. package/src/controllers/index.ts +65 -39
  795. package/src/controllers/types.ts +318 -285
  796. package/src/data-fetchers/__tests__/binance.test.ts +297 -0
  797. package/src/data-fetchers/__tests__/dataBuffer.test.ts +409 -412
  798. package/src/data-fetchers/__tests__/depthConnector.test.ts +259 -0
  799. package/src/data-fetchers/__tests__/fetcherRegistry.test.ts +79 -34
  800. package/src/data-fetchers/baostock.ts +4 -1
  801. package/src/data-fetchers/binance.ts +130 -0
  802. package/src/data-fetchers/dataBuffer.effects.ts +8 -11
  803. package/src/data-fetchers/dataBuffer.ts +247 -231
  804. package/src/data-fetchers/dataBufferTypes.ts +1 -1
  805. package/src/data-fetchers/depthConnector.ts +103 -0
  806. package/src/data-fetchers/depthTypes.ts +69 -0
  807. package/src/data-fetchers/fetcherDefinitionRegistry.ts +15 -7
  808. package/src/data-fetchers/gotdx.ts +35 -13
  809. package/src/data-fetchers/index.ts +13 -2
  810. package/src/data-fetchers/router.ts +16 -16
  811. package/src/data-fetchers/timeShareBuffer.ts +5 -2
  812. package/src/data-fetchers/tradingview.ts +4 -1
  813. package/src/data-fetchers/types.ts +1 -1
  814. package/src/engine/__tests__/chart.dpr.test.ts +6 -2
  815. package/src/engine/__tests__/subPaneManager.test.ts +23 -10
  816. package/src/engine/chart.ts +1290 -1213
  817. package/src/engine/controller/interaction.ts +921 -896
  818. package/src/engine/controller/markerInteraction.ts +4 -1
  819. package/src/engine/data/chartDataManager.ts +111 -46
  820. package/src/engine/draw/__tests__/pixelAlign.spec.ts +1 -1
  821. package/src/engine/draw/pixelAlign.ts +170 -166
  822. package/src/engine/drawing/AnchorCollector.ts +1 -1
  823. package/src/engine/drawing/DragHandler.ts +1 -1
  824. package/src/engine/drawing/DrawingState.ts +2 -2
  825. package/src/engine/drawing/HitTester.ts +34 -17
  826. package/src/engine/drawing/PreviewRenderer.ts +46 -19
  827. package/src/engine/drawing/coordinateUtils.ts +5 -5
  828. package/src/engine/drawing/index.ts +107 -28
  829. package/src/engine/drawing/interaction.ts +9 -7
  830. package/src/engine/drawing/linearRegression.ts +3 -1
  831. package/src/engine/drawing/plugin.ts +100 -30
  832. package/src/engine/drawing/toolConfig.ts +1 -1
  833. package/src/engine/indicators/__tests__/__fixtures__/golden/atr.json +104 -36
  834. package/src/engine/indicators/__tests__/__fixtures__/golden/dema.json +11 -12
  835. package/src/engine/indicators/__tests__/__fixtures__/golden/hma.json +39 -12
  836. package/src/engine/indicators/__tests__/__fixtures__/golden/index.ts +28 -28
  837. package/src/engine/indicators/__tests__/__fixtures__/golden/kama.json +39 -12
  838. package/src/engine/indicators/__tests__/__fixtures__/golden/tema.json +11 -12
  839. package/src/engine/indicators/__tests__/__fixtures__/golden/wma.json +73 -38
  840. package/src/engine/indicators/__tests__/__fixtures__/synthetic.ts +36 -29
  841. package/src/engine/indicators/__tests__/_propertyAssertions.ts +55 -54
  842. package/src/engine/indicators/__tests__/atr.test.ts +141 -144
  843. package/src/engine/indicators/__tests__/calculators.test.ts +4 -17
  844. package/src/engine/indicators/__tests__/chartIndicatorManager.test.ts +12 -1
  845. package/src/engine/indicators/__tests__/cmf-mfi.test.ts +77 -77
  846. package/src/engine/indicators/__tests__/dema.test.ts +54 -56
  847. package/src/engine/indicators/__tests__/donchian.test.ts +52 -58
  848. package/src/engine/indicators/__tests__/hma.test.ts +53 -55
  849. package/src/engine/indicators/__tests__/ichimoku.test.ts +91 -91
  850. package/src/engine/indicators/__tests__/indicatorRegistry.test.ts +6 -2
  851. package/src/engine/indicators/__tests__/kama.test.ts +60 -62
  852. package/src/engine/indicators/__tests__/keltner.test.ts +49 -55
  853. package/src/engine/indicators/__tests__/pivot-fib.test.ts +89 -89
  854. package/src/engine/indicators/__tests__/registerBuiltins.test.ts +199 -51
  855. package/src/engine/indicators/__tests__/roc.test.ts +56 -53
  856. package/src/engine/indicators/__tests__/sar.test.ts +70 -70
  857. package/src/engine/indicators/__tests__/scheduler.test.ts +58 -15
  858. package/src/engine/indicators/__tests__/soa.test.ts +27 -7
  859. package/src/engine/indicators/__tests__/stateComposer.test.ts +227 -45
  860. package/src/engine/indicators/__tests__/structure.test.ts +109 -93
  861. package/src/engine/indicators/__tests__/supertrend.test.ts +47 -53
  862. package/src/engine/indicators/__tests__/tema.test.ts +49 -51
  863. package/src/engine/indicators/__tests__/trix.test.ts +56 -56
  864. package/src/engine/indicators/__tests__/volatility.test.ts +88 -94
  865. package/src/engine/indicators/__tests__/volume.test.ts +102 -102
  866. package/src/engine/indicators/__tests__/volumeProfile.test.ts +55 -61
  867. package/src/engine/indicators/__tests__/vwap.test.ts +56 -56
  868. package/src/engine/indicators/__tests__/wma.test.ts +86 -89
  869. package/src/engine/indicators/__tests__/zones.test.ts +88 -79
  870. package/src/engine/indicators/calculators/_shared.ts +41 -35
  871. package/src/engine/indicators/calculators/bands.ts +271 -282
  872. package/src/engine/indicators/calculators/index.ts +26 -3
  873. package/src/engine/indicators/calculators/movingAverages.ts +134 -134
  874. package/src/engine/indicators/calculators/oscillators.ts +302 -306
  875. package/src/engine/indicators/calculators/patterns.ts +233 -225
  876. package/src/engine/indicators/calculators/volatility.ts +119 -119
  877. package/src/engine/indicators/calculators/volume.ts +217 -220
  878. package/src/engine/indicators/calculators.ts +0 -2
  879. package/src/engine/indicators/chartIndicatorManager.ts +576 -484
  880. package/src/engine/indicators/indicator.worker.ts +134 -132
  881. package/src/engine/indicators/indicatorDefinitionRegistry.ts +111 -96
  882. package/src/engine/indicators/indicatorMetadata.ts +183 -175
  883. package/src/engine/indicators/indicatorRegistry.ts +146 -137
  884. package/src/engine/indicators/indicatorRuntime.ts +206 -196
  885. package/src/engine/indicators/registerBuiltins.ts +2 -1
  886. package/src/engine/indicators/scheduler.ts +725 -674
  887. package/src/engine/indicators/soa.ts +29 -19
  888. package/src/engine/indicators/state/atrState.ts +15 -16
  889. package/src/engine/indicators/state/bollState.ts +28 -28
  890. package/src/engine/indicators/state/cciState.ts +15 -16
  891. package/src/engine/indicators/state/chaikinVolState.ts +19 -19
  892. package/src/engine/indicators/state/cmfState.ts +15 -16
  893. package/src/engine/indicators/state/demaState.ts +15 -16
  894. package/src/engine/indicators/state/donchianState.ts +28 -28
  895. package/src/engine/indicators/state/eneState.ts +20 -20
  896. package/src/engine/indicators/state/expmaState.ts +20 -20
  897. package/src/engine/indicators/state/fastkState.ts +15 -16
  898. package/src/engine/indicators/state/fibState.ts +26 -27
  899. package/src/engine/indicators/state/hmaState.ts +15 -16
  900. package/src/engine/indicators/state/hvState.ts +19 -16
  901. package/src/engine/indicators/state/ichimokuState.ts +42 -42
  902. package/src/engine/indicators/state/kamaState.ts +20 -21
  903. package/src/engine/indicators/state/keltnerState.ts +32 -33
  904. package/src/engine/indicators/state/kstState.ts +31 -32
  905. package/src/engine/indicators/state/maState.ts +14 -14
  906. package/src/engine/indicators/state/mfiState.ts +15 -16
  907. package/src/engine/indicators/state/momState.ts +15 -16
  908. package/src/engine/indicators/state/obvState.ts +15 -16
  909. package/src/engine/indicators/state/parkinsonState.ts +19 -15
  910. package/src/engine/indicators/state/pivotState.ts +38 -39
  911. package/src/engine/indicators/state/pvtState.ts +15 -16
  912. package/src/engine/indicators/state/rocState.ts +15 -16
  913. package/src/engine/indicators/state/rsiState.ts +38 -39
  914. package/src/engine/indicators/state/sarState.ts +21 -22
  915. package/src/engine/indicators/state/stochState.ts +15 -16
  916. package/src/engine/indicators/state/structureState.ts +45 -45
  917. package/src/engine/indicators/state/supertrendState.ts +21 -21
  918. package/src/engine/indicators/state/temaState.ts +15 -16
  919. package/src/engine/indicators/state/trixState.ts +22 -23
  920. package/src/engine/indicators/state/vmaState.ts +15 -16
  921. package/src/engine/indicators/state/volumeProfileState.ts +41 -41
  922. package/src/engine/indicators/state/vwapState.ts +15 -16
  923. package/src/engine/indicators/state/wmaState.ts +15 -16
  924. package/src/engine/indicators/state/wmsrState.ts +15 -16
  925. package/src/engine/indicators/state/zonesState.ts +30 -31
  926. package/src/engine/indicators/stateComposer.ts +185 -190
  927. package/src/engine/indicators/visibleStateComposers.ts +785 -748
  928. package/src/engine/indicators/workerProtocol.ts +394 -397
  929. package/src/engine/layout/chartPaneLayout.ts +25 -16
  930. package/src/engine/layout/pane.ts +11 -3
  931. package/src/engine/marker/registry.ts +208 -190
  932. package/src/engine/modes/kLineMode.ts +26 -16
  933. package/src/engine/modes/timeShareMode.ts +26 -14
  934. package/src/engine/modes/types.ts +26 -14
  935. package/src/engine/paneRenderer.ts +130 -125
  936. package/src/engine/render/chartRenderer.ts +291 -118
  937. package/src/engine/render/layers/candleLayer.ts +9 -0
  938. package/src/engine/render/layers/comparisonLineLayer.ts +9 -0
  939. package/src/engine/render/layers/crosshairLayer.ts +18 -0
  940. package/src/engine/render/layers/customMarkersLayer.ts +8 -0
  941. package/src/engine/render/layers/extremaMarkersLayer.ts +8 -0
  942. package/src/engine/render/layers/gridLinesLayer.ts +8 -0
  943. package/src/engine/render/layers/lastPriceLabelLayer.ts +8 -0
  944. package/src/engine/render/layers/lastPriceLineLayer.ts +9 -0
  945. package/src/engine/render/layers/leftYAxisLayer.ts +15 -0
  946. package/src/engine/render/layers/mainIndicatorLegendLayer.ts +18 -0
  947. package/src/engine/render/layers/yAxisLayer.ts +15 -0
  948. package/src/engine/renderers/Indicator/__tests__/createSubIndicatorRenderer.test.ts +4 -1
  949. package/src/engine/renderers/Indicator/atr.ts +197 -188
  950. package/src/engine/renderers/Indicator/boll.ts +364 -309
  951. package/src/engine/renderers/Indicator/cci.ts +223 -219
  952. package/src/engine/renderers/Indicator/chaikinVol.ts +129 -112
  953. package/src/engine/renderers/Indicator/cmf.ts +121 -111
  954. package/src/engine/renderers/Indicator/dema.ts +124 -112
  955. package/src/engine/renderers/Indicator/donchian.ts +162 -132
  956. package/src/engine/renderers/Indicator/ene.ts +286 -264
  957. package/src/engine/renderers/Indicator/expma.ts +237 -220
  958. package/src/engine/renderers/Indicator/fastk.ts +201 -197
  959. package/src/engine/renderers/Indicator/fib.ts +162 -138
  960. package/src/engine/renderers/Indicator/hma.ts +124 -112
  961. package/src/engine/renderers/Indicator/hv.ts +108 -94
  962. package/src/engine/renderers/Indicator/ichimoku.ts +183 -112
  963. package/src/engine/renderers/Indicator/index.ts +10 -10
  964. package/src/engine/renderers/Indicator/indicatorCatalog.ts +685 -78
  965. package/src/engine/renderers/Indicator/kama.ts +124 -112
  966. package/src/engine/renderers/Indicator/keltner.ts +170 -131
  967. package/src/engine/renderers/Indicator/kst.ts +290 -255
  968. package/src/engine/renderers/Indicator/ma.ts +292 -254
  969. package/src/engine/renderers/Indicator/macd.ts +174 -38
  970. package/src/engine/renderers/Indicator/mainIndicatorLegend.ts +30 -8
  971. package/src/engine/renderers/Indicator/mfi.ts +126 -116
  972. package/src/engine/renderers/Indicator/mom.ts +268 -250
  973. package/src/engine/renderers/Indicator/obv.ts +107 -98
  974. package/src/engine/renderers/Indicator/parkinson.ts +110 -94
  975. package/src/engine/renderers/Indicator/pivot.ts +187 -145
  976. package/src/engine/renderers/Indicator/pvt.ts +107 -98
  977. package/src/engine/renderers/Indicator/roc.ts +136 -124
  978. package/src/engine/renderers/Indicator/rsi.ts +395 -346
  979. package/src/engine/renderers/Indicator/sar.ts +121 -106
  980. package/src/engine/renderers/Indicator/scale/atr_scale.ts +13 -13
  981. package/src/engine/renderers/Indicator/scale/cci_scale.ts +13 -13
  982. package/src/engine/renderers/Indicator/scale/fastk_scale.ts +13 -13
  983. package/src/engine/renderers/Indicator/scale/indicator_scale.ts +193 -174
  984. package/src/engine/renderers/Indicator/scale/kst_scale.ts +13 -13
  985. package/src/engine/renderers/Indicator/scale/macd_scale.ts +13 -13
  986. package/src/engine/renderers/Indicator/scale/mom_scale.ts +13 -13
  987. package/src/engine/renderers/Indicator/scale/rsi_scale.ts +13 -13
  988. package/src/engine/renderers/Indicator/scale/stoch_scale.ts +13 -13
  989. package/src/engine/renderers/Indicator/scale/volume_scale.ts +15 -15
  990. package/src/engine/renderers/Indicator/scale/wmsr_scale.ts +13 -13
  991. package/src/engine/renderers/Indicator/shared/dashedLines.ts +16 -7
  992. package/src/engine/renderers/Indicator/shared/titleInfo.ts +3 -1
  993. package/src/engine/renderers/Indicator/shared/webglBand.ts +1 -1
  994. package/src/engine/renderers/Indicator/stoch.ts +263 -246
  995. package/src/engine/renderers/Indicator/structure.ts +165 -120
  996. package/src/engine/renderers/Indicator/supertrend.ts +145 -112
  997. package/src/engine/renderers/Indicator/tema.ts +124 -112
  998. package/src/engine/renderers/Indicator/trix.ts +170 -159
  999. package/src/engine/renderers/Indicator/vma.ts +108 -98
  1000. package/src/engine/renderers/Indicator/volumeProfile.ts +150 -126
  1001. package/src/engine/renderers/Indicator/vwap.ts +107 -98
  1002. package/src/engine/renderers/Indicator/wma.ts +124 -112
  1003. package/src/engine/renderers/Indicator/wmsr.ts +289 -265
  1004. package/src/engine/renderers/Indicator/zones.ts +139 -109
  1005. package/src/engine/renderers/__tests__/boll.renderer.test.ts +20 -9
  1006. package/src/engine/renderers/__tests__/ene.renderer.test.ts +3 -5
  1007. package/src/engine/renderers/__tests__/expma.renderer.test.ts +1 -1
  1008. package/src/engine/renderers/__tests__/ma.renderer.test.ts +14 -5
  1009. package/src/engine/renderers/__tests__/mainIndicatorLegend.renderer.test.ts +36 -49
  1010. package/src/engine/renderers/__tests__/yAxis.renderer.test.ts +7 -1
  1011. package/src/engine/renderers/candle.ts +556 -437
  1012. package/src/engine/renderers/comparisonLine.ts +96 -91
  1013. package/src/engine/renderers/crosshair.ts +5 -1
  1014. package/src/engine/renderers/customMarkers.ts +144 -118
  1015. package/src/engine/renderers/extremaMarkers.ts +191 -180
  1016. package/src/engine/renderers/gridLines.ts +51 -48
  1017. package/src/engine/renderers/lastPrice.ts +81 -70
  1018. package/src/engine/renderers/leftYAxis.ts +47 -26
  1019. package/src/engine/renderers/paneTitle.ts +140 -124
  1020. package/src/engine/renderers/subVolume.ts +264 -194
  1021. package/src/engine/renderers/timeAxis.ts +70 -48
  1022. package/src/engine/renderers/timeShare.ts +42 -13
  1023. package/src/engine/renderers/webgl/candleSurface.ts +943 -850
  1024. package/src/engine/renderers/webgl/sharedWebGLSurface.ts +146 -122
  1025. package/src/engine/renderers/yAxis.ts +45 -29
  1026. package/src/engine/scale/__tests__/logFormula.spec.ts +141 -141
  1027. package/src/engine/scale/logFormula.ts +40 -40
  1028. package/src/engine/scale/price.ts +21 -22
  1029. package/src/engine/scale/priceScale.ts +269 -269
  1030. package/src/engine/subPaneManager.ts +291 -200
  1031. package/src/engine/theme/fonts.ts +5 -5
  1032. package/src/engine/utils/__tests__/tickPosition.test.ts +43 -43
  1033. package/src/engine/utils/chartZoomController.ts +10 -3
  1034. package/src/engine/utils/klineConfig.ts +22 -22
  1035. package/src/engine/utils/tickCount.ts +2 -2
  1036. package/src/engine/utils/tickPosition.ts +205 -207
  1037. package/src/engine/viewport/chartViewportManager.ts +33 -22
  1038. package/src/engine/viewport/viewport.ts +35 -28
  1039. package/src/errors-help.ts +134 -135
  1040. package/src/errors.ts +65 -62
  1041. package/src/index.ts +5 -9
  1042. package/src/indicators/__tests__/maFamily.test.ts +114 -114
  1043. package/src/indicators/__tests__/oscillators.test.ts +108 -104
  1044. package/src/indicators/alma.ts +36 -33
  1045. package/src/indicators/awesomeOscillator.ts +36 -33
  1046. package/src/indicators/dpo.ts +18 -17
  1047. package/src/indicators/fisherTransform.ts +40 -37
  1048. package/src/indicators/frama.ts +60 -53
  1049. package/src/indicators/index.ts +4 -16
  1050. package/src/indicators/lsma.ts +32 -31
  1051. package/src/indicators/schaffTrendCycle.ts +61 -59
  1052. package/src/indicators/stochRSI.ts +74 -74
  1053. package/src/indicators/t3.ts +55 -56
  1054. package/src/indicators/ultimateOscillator.ts +57 -54
  1055. package/src/indicators/vidya.ts +49 -48
  1056. package/src/indicators/zlema.ts +21 -20
  1057. package/src/input/__tests__/gesture.test.ts +182 -182
  1058. package/src/input/__tests__/keyboard.test.ts +228 -235
  1059. package/src/input/gesture.ts +262 -268
  1060. package/src/input/index.ts +15 -15
  1061. package/src/input/keyboard.ts +235 -237
  1062. package/src/mcp/chartBridge.ts +3 -11
  1063. package/src/plugin/HookSystem.ts +2 -6
  1064. package/src/plugin/PluginHost.ts +26 -6
  1065. package/src/plugin/StateStore.ts +1 -1
  1066. package/src/plugin/rendererPluginManager.ts +4 -8
  1067. package/src/plugin/types.ts +10 -7
  1068. package/src/reactivity/signal.ts +69 -69
  1069. package/src/render/Renderer.ts +57 -57
  1070. package/src/render/SurfaceBackend.ts +51 -51
  1071. package/src/render/__tests__/contract.test.ts +134 -134
  1072. package/src/render/__tests__/webglRenderer.fallback.test.ts +226 -0
  1073. package/src/render/__tests__/webglRenderer.test.ts +363 -0
  1074. package/src/render/__tests__/webglSurfaceBackend.test.ts +125 -0
  1075. package/src/render/createWebGLRenderer.ts +288 -0
  1076. package/src/render/createWebGLSurfaceBackend.ts +43 -0
  1077. package/src/render/index.ts +15 -19
  1078. package/src/renderer-tier/__tests__/detectRendererTier.test.ts +116 -119
  1079. package/src/renderer-tier/__tests__/selectBackend.test.ts +168 -172
  1080. package/src/renderer-tier/detectRendererTier.ts +65 -74
  1081. package/src/renderer-tier/index.ts +15 -15
  1082. package/src/renderer-tier/selectBackend.ts +89 -98
  1083. package/src/renderer-tier/types.ts +11 -11
  1084. package/src/replay/__tests__/controller.test.ts +268 -268
  1085. package/src/replay/__tests__/timeline.test.ts +77 -77
  1086. package/src/replay/createReplayController.ts +224 -232
  1087. package/src/replay/index.ts +7 -11
  1088. package/src/replay/timeline.ts +44 -50
  1089. package/src/replay/types.ts +63 -65
  1090. package/src/scale/__tests__/anchoredZoom.test.ts +121 -110
  1091. package/src/scale/__tests__/originShift.test.ts +80 -80
  1092. package/src/scale/__tests__/priceScale.test.ts +205 -205
  1093. package/src/scale/__tests__/timeScale.test.ts +104 -98
  1094. package/src/scale/anchoredZoom.ts +44 -44
  1095. package/src/scale/createPriceScale.ts +178 -175
  1096. package/src/scale/createTimeScale.ts +130 -124
  1097. package/src/scale/index.ts +3 -3
  1098. package/src/scale/originShift.ts +49 -43
  1099. package/src/scale/types.ts +43 -43
  1100. package/src/scene/__tests__/layerFromPlugin.test.ts +243 -0
  1101. package/src/scene/__tests__/layerRegistry.test.ts +154 -170
  1102. package/src/scene/__tests__/scene.test.ts +341 -345
  1103. package/src/scene/createLayerFromPlugin.ts +47 -0
  1104. package/src/scene/createScene.ts +85 -82
  1105. package/src/scene/index.ts +5 -16
  1106. package/src/scene/layerRegistry.ts +52 -54
  1107. package/src/scene/types.ts +37 -32
  1108. package/src/scheduler/__tests__/createFrameBudget.test.ts +227 -223
  1109. package/src/scheduler/createFrameBudget.ts +224 -224
  1110. package/src/scheduler/index.ts +5 -5
  1111. package/src/semantic/__tests__/controller.test.ts +11 -9
  1112. package/src/semantic/controller.ts +42 -18
  1113. package/src/semantic/drawShape.ts +3 -3
  1114. package/src/semantic/index.ts +7 -1
  1115. package/src/semantic/schema.json +16 -4
  1116. package/src/semantic/validator.ts +22 -8
  1117. package/src/tokens/__tests__/baseline.test.ts +99 -102
  1118. package/src/tokens/__tests__/themeToCssVars.test.ts +117 -128
  1119. package/src/tokens/__tests__/tokens.test.ts +119 -130
  1120. package/src/tokens/colorPresetSettings.ts +103 -99
  1121. package/src/tokens/index.ts +44 -44
  1122. package/src/tokens/mergeTheme.ts +20 -20
  1123. package/src/tokens/theme-base.ts +1 -2
  1124. package/src/tokens/theme-china.ts +70 -70
  1125. package/src/tokens/theme-dark.ts +182 -182
  1126. package/src/tokens/theme-light.ts +186 -186
  1127. package/src/tokens/themeToCssVars.ts +53 -54
  1128. package/src/tokens/types.ts +215 -215
  1129. package/src/types/price.ts +7 -2
  1130. package/src/types/volumePrice.ts +1 -2
  1131. package/src/utils/__tests__/dateFormat.test.ts +137 -142
  1132. package/src/utils/dateFormat.ts +115 -110
  1133. package/src/utils/kLineDraw/axis.ts +486 -453
  1134. package/src/utils/priceToY.ts +21 -21
  1135. package/src/utils/volumePrice.ts +8 -4
  1136. package/src/version.ts +1 -1
@@ -1,59 +1,64 @@
1
- import { SharedWebGLSurface, type PhysicalRegion, type WebGLCompositeOptions, type WebGLRegion } from './sharedWebGLSurface'
1
+ import {
2
+ SharedWebGLSurface,
3
+ type PhysicalRegion,
4
+ type WebGLCompositeOptions,
5
+ type WebGLRegion,
6
+ } from './sharedWebGLSurface'
2
7
 
3
8
  type Rect = {
4
- x: number
5
- y: number
6
- width: number
7
- height: number
9
+ x: number
10
+ y: number
11
+ width: number
12
+ height: number
8
13
  }
9
14
 
10
15
  type LineStrip = {
11
- points: Array<{ x: number; y: number }>
12
- width: number
16
+ points: Array<{ x: number; y: number }>
17
+ width: number
13
18
  }
14
19
 
15
20
  type ColoredLineStrip = LineStrip & {
16
- color: string
21
+ color: string
17
22
  }
18
23
 
19
24
  type FilledBand = {
20
- upperPoints: Array<{ x: number; y: number }>
21
- lowerPoints: Array<{ x: number; y: number }>
25
+ upperPoints: Array<{ x: number; y: number }>
26
+ lowerPoints: Array<{ x: number; y: number }>
22
27
  }
23
28
 
24
29
  type FloatColor = readonly [number, number, number, number]
25
30
 
26
31
  type RectWebGLHandles = {
27
- program: WebGLProgram
28
- vao: WebGLVertexArrayObject
29
- unitBuffer: WebGLBuffer
30
- rectBuffer: WebGLBuffer
31
- resolutionLocation: WebGLUniformLocation
32
- scrollXLocation: WebGLUniformLocation
33
- colorLocation: WebGLUniformLocation
32
+ program: WebGLProgram
33
+ vao: WebGLVertexArrayObject
34
+ unitBuffer: WebGLBuffer
35
+ rectBuffer: WebGLBuffer
36
+ resolutionLocation: WebGLUniformLocation
37
+ scrollXLocation: WebGLUniformLocation
38
+ colorLocation: WebGLUniformLocation
34
39
  }
35
40
 
36
41
  type BasicLineWebGLHandles = {
37
- program: WebGLProgram
38
- vao: WebGLVertexArrayObject
39
- vertexBuffer: WebGLBuffer
40
- resolutionLocation: WebGLUniformLocation
41
- scrollXLocation: WebGLUniformLocation
42
- colorLocation: WebGLUniformLocation
42
+ program: WebGLProgram
43
+ vao: WebGLVertexArrayObject
44
+ vertexBuffer: WebGLBuffer
45
+ resolutionLocation: WebGLUniformLocation
46
+ scrollXLocation: WebGLUniformLocation
47
+ colorLocation: WebGLUniformLocation
43
48
  }
44
49
 
45
50
  type LineWebGLHandles = {
46
- basic: BasicLineWebGLHandles
51
+ basic: BasicLineWebGLHandles
47
52
  }
48
53
 
49
54
  type MsaaTargets = {
50
- samples: number
51
- widthPx: number
52
- heightPx: number
53
- msaaFramebuffer: WebGLFramebuffer
54
- msaaColorRenderbuffer: WebGLRenderbuffer
55
- resolveFramebuffer: WebGLFramebuffer
56
- resolveTexture: WebGLTexture
55
+ samples: number
56
+ widthPx: number
57
+ heightPx: number
58
+ msaaFramebuffer: WebGLFramebuffer
59
+ msaaColorRenderbuffer: WebGLRenderbuffer
60
+ resolveFramebuffer: WebGLFramebuffer
61
+ resolveTexture: WebGLTexture
57
62
  }
58
63
 
59
64
  const RECT_VERTEX_SHADER_SOURCE = `#version 300 es
@@ -109,867 +114,955 @@ void main() {
109
114
  outColor = u_color;
110
115
  }`
111
116
 
112
- const UNIT_QUAD = new Float32Array([
113
- 0, 0,
114
- 1, 0,
115
- 0, 1,
116
- 0, 1,
117
- 1, 0,
118
- 1, 1,
119
- ])
117
+ const UNIT_QUAD = new Float32Array([0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1])
120
118
 
121
119
  const MITER_DOT_MIN = 0.5
122
120
 
123
121
  export class CandleWebGLSurface {
124
- private shared: SharedWebGLSurface
125
- private handles: RectWebGLHandles | null = null
126
- private logicalWidth = 0
127
- private logicalHeight = 0
128
- private available = false
129
- private rectCapacity = 0
130
- private rectScratch = new Float32Array(0)
131
- private region: WebGLRegion | null = null
122
+ private shared: SharedWebGLSurface
123
+ private handles: RectWebGLHandles | null = null
124
+ private logicalWidth = 0
125
+ private logicalHeight = 0
126
+ private available = false
127
+ private rectCapacity = 0
128
+ private rectScratch = new Float32Array(0)
129
+ private region: WebGLRegion | null = null
130
+
131
+ constructor(shared: SharedWebGLSurface) {
132
+ this.shared = shared
133
+ this.handles = this.initRectHandles()
134
+ this.available = this.handles !== null
135
+ }
136
+
137
+ isAvailable(): boolean {
138
+ return this.available
139
+ }
140
+
141
+ getCanvas(): HTMLCanvasElement {
142
+ return this.shared.getCanvas()
143
+ }
144
+
145
+ setRegion(region: WebGLRegion): void {
146
+ this.region = region
147
+ }
148
+
149
+ resize(width: number, height: number, _dpr: number): void {
150
+ this.logicalWidth = width
151
+ this.logicalHeight = height
152
+ }
153
+
154
+ clear(): void {
155
+ if (!this.region || this.logicalWidth <= 0 || this.logicalHeight <= 0) return
156
+ this.shared.clearRegion(this.region)
157
+ }
158
+
159
+ compositeTo(ctx: CanvasRenderingContext2D, options: WebGLCompositeOptions = {}): void {
160
+ if (!this.region) return
161
+ this.shared.compositeRegionTo(ctx, this.region, options)
162
+ }
163
+
164
+ /** 直接传入已打包的 Float32Array:每 4 个元素为一组 (x, y, width, height) */
165
+ drawRectBuffer(
166
+ rectData: Float32Array,
167
+ rectCount: number,
168
+ color: string,
169
+ scrollLeft: number,
170
+ ): boolean {
171
+ const handles = this.handles
172
+ if (!handles || rectCount === 0 || this.logicalWidth <= 0 || this.logicalHeight <= 0) {
173
+ return false
174
+ }
175
+
176
+ const colorValue = parseColor(color)
177
+ if (!colorValue) return false
178
+
179
+ const floatCount = rectCount * 4
180
+ const gl = this.shared.getGL()
181
+ if (!gl || !this.region || !this.shared.bindRegion(this.region)) return false
182
+
183
+ gl.useProgram(handles.program)
184
+ gl.bindVertexArray(handles.vao)
185
+ gl.bindBuffer(gl.ARRAY_BUFFER, handles.rectBuffer)
186
+
187
+ if (this.rectCapacity < floatCount) {
188
+ this.rectCapacity = nextBufferFloatCapacity(floatCount)
189
+ gl.bufferData(
190
+ gl.ARRAY_BUFFER,
191
+ this.rectCapacity * Float32Array.BYTES_PER_ELEMENT,
192
+ gl.DYNAMIC_DRAW,
193
+ )
194
+ }
195
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, rectData)
132
196
 
133
- constructor(shared: SharedWebGLSurface) {
134
- this.shared = shared
135
- this.handles = this.initRectHandles()
136
- this.available = this.handles !== null
197
+ if (colorValue[3] === 1) {
198
+ gl.disable(gl.BLEND)
199
+ } else {
200
+ gl.enable(gl.BLEND)
201
+ }
202
+ gl.uniform2f(handles.resolutionLocation, this.logicalWidth, this.logicalHeight)
203
+ gl.uniform1f(handles.scrollXLocation, scrollLeft)
204
+ gl.uniform4f(handles.colorLocation, colorValue[0], colorValue[1], colorValue[2], colorValue[3])
205
+ gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, rectCount)
206
+ gl.bindVertexArray(null)
207
+ return true
208
+ }
209
+
210
+ drawRects(rects: Rect[], color: string, scrollLeft: number): boolean {
211
+ const handles = this.handles
212
+ if (!handles || !rects.length || this.logicalWidth <= 0 || this.logicalHeight <= 0) {
213
+ return false
214
+ }
215
+
216
+ const floatCount = rects.length * 4
217
+ if (this.rectScratch.length < floatCount) {
218
+ this.rectScratch = new Float32Array(nextBufferFloatCapacity(floatCount))
137
219
  }
138
220
 
139
- isAvailable(): boolean {
140
- return this.available
221
+ for (let i = 0; i < rects.length; i++) {
222
+ const rect = rects[i]!
223
+ const offset = i * 4
224
+ this.rectScratch[offset] = rect.x
225
+ this.rectScratch[offset + 1] = rect.y
226
+ this.rectScratch[offset + 2] = rect.width
227
+ this.rectScratch[offset + 3] = rect.height
228
+ }
229
+
230
+ return this.drawRectBuffer(
231
+ this.rectScratch.subarray(0, floatCount),
232
+ rects.length,
233
+ color,
234
+ scrollLeft,
235
+ )
236
+ }
237
+
238
+ destroy(): void {
239
+ const handles = this.handles
240
+ if (!handles) return
241
+
242
+ const gl = this.shared.getGL()
243
+ if (gl) {
244
+ const { program, vao, unitBuffer, rectBuffer } = handles
245
+ gl.deleteBuffer(unitBuffer)
246
+ gl.deleteBuffer(rectBuffer)
247
+ gl.deleteVertexArray(vao)
248
+ gl.deleteProgram(program)
249
+ }
250
+ this.handles = null
251
+ this.available = false
252
+ }
253
+
254
+ private initRectHandles(): RectWebGLHandles | null {
255
+ const gl = this.shared.getGL()
256
+ if (!gl) return null
257
+
258
+ const vertexShader = createShader(gl, gl.VERTEX_SHADER, RECT_VERTEX_SHADER_SOURCE)
259
+ const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE)
260
+ if (!vertexShader || !fragmentShader) {
261
+ if (vertexShader) gl.deleteShader(vertexShader)
262
+ if (fragmentShader) gl.deleteShader(fragmentShader)
263
+ return null
141
264
  }
142
265
 
143
- getCanvas(): HTMLCanvasElement {
144
- return this.shared.getCanvas()
266
+ const program = createProgram(gl, vertexShader, fragmentShader)
267
+ gl.deleteShader(vertexShader)
268
+ gl.deleteShader(fragmentShader)
269
+ if (!program) return null
270
+
271
+ const vao = gl.createVertexArray()
272
+ const unitBuffer = gl.createBuffer()
273
+ const rectBuffer = gl.createBuffer()
274
+ if (!vao || !unitBuffer || !rectBuffer) {
275
+ if (vao) gl.deleteVertexArray(vao)
276
+ if (unitBuffer) gl.deleteBuffer(unitBuffer)
277
+ if (rectBuffer) gl.deleteBuffer(rectBuffer)
278
+ gl.deleteProgram(program)
279
+ return null
145
280
  }
146
281
 
147
- setRegion(region: WebGLRegion): void {
148
- this.region = region
282
+ const resolutionLocation = gl.getUniformLocation(program, 'u_resolution')
283
+ const scrollXLocation = gl.getUniformLocation(program, 'u_scrollX')
284
+ const colorLocation = gl.getUniformLocation(program, 'u_color')
285
+ if (!resolutionLocation || !scrollXLocation || !colorLocation) {
286
+ gl.deleteBuffer(unitBuffer)
287
+ gl.deleteBuffer(rectBuffer)
288
+ gl.deleteVertexArray(vao)
289
+ gl.deleteProgram(program)
290
+ return null
149
291
  }
150
292
 
151
- resize(width: number, height: number, _dpr: number): void {
152
- this.logicalWidth = width
153
- this.logicalHeight = height
293
+ const unitLocation = gl.getAttribLocation(program, 'a_unit')
294
+ const rectLocation = gl.getAttribLocation(program, 'a_rect')
295
+ if (unitLocation < 0 || rectLocation < 0) {
296
+ gl.deleteBuffer(unitBuffer)
297
+ gl.deleteBuffer(rectBuffer)
298
+ gl.deleteVertexArray(vao)
299
+ gl.deleteProgram(program)
300
+ return null
154
301
  }
155
-
156
- clear(): void {
157
- if (!this.region || this.logicalWidth <= 0 || this.logicalHeight <= 0) return
158
- this.shared.clearRegion(this.region)
159
- }
160
-
161
- compositeTo(ctx: CanvasRenderingContext2D, options: WebGLCompositeOptions = {}): void {
162
- if (!this.region) return
163
- this.shared.compositeRegionTo(ctx, this.region, options)
164
- }
165
-
166
- /** 直接传入已打包的 Float32Array:每 4 个元素为一组 (x, y, width, height) */
167
- drawRectBuffer(rectData: Float32Array, rectCount: number, color: string, scrollLeft: number): boolean {
168
- const handles = this.handles
169
- if (!handles || rectCount === 0 || this.logicalWidth <= 0 || this.logicalHeight <= 0) {
170
- return false
171
- }
172
-
173
- const colorValue = parseColor(color)
174
- if (!colorValue) return false
175
-
176
- const floatCount = rectCount * 4
177
- const gl = this.shared.getGL()
178
- if (!gl || !this.region || !this.shared.bindRegion(this.region)) return false
179
-
180
- gl.useProgram(handles.program)
181
- gl.bindVertexArray(handles.vao)
182
- gl.bindBuffer(gl.ARRAY_BUFFER, handles.rectBuffer)
183
-
184
- if (this.rectCapacity < floatCount) {
185
- this.rectCapacity = nextBufferFloatCapacity(floatCount)
186
- gl.bufferData(gl.ARRAY_BUFFER, this.rectCapacity * Float32Array.BYTES_PER_ELEMENT, gl.DYNAMIC_DRAW)
187
- }
188
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, rectData)
189
-
190
- if (colorValue[3] === 1) {
191
- gl.disable(gl.BLEND)
192
- } else {
193
- gl.enable(gl.BLEND)
194
- }
195
- gl.uniform2f(handles.resolutionLocation, this.logicalWidth, this.logicalHeight)
196
- gl.uniform1f(handles.scrollXLocation, scrollLeft)
197
- gl.uniform4f(handles.colorLocation, colorValue[0], colorValue[1], colorValue[2], colorValue[3])
198
- gl.drawArraysInstanced(gl.TRIANGLES, 0, 6, rectCount)
199
- gl.bindVertexArray(null)
200
- return true
201
- }
202
-
203
- drawRects(rects: Rect[], color: string, scrollLeft: number): boolean {
204
- const handles = this.handles
205
- if (!handles || !rects.length || this.logicalWidth <= 0 || this.logicalHeight <= 0) {
206
- return false
207
- }
208
-
209
- const floatCount = rects.length * 4
210
- if (this.rectScratch.length < floatCount) {
211
- this.rectScratch = new Float32Array(nextBufferFloatCapacity(floatCount))
212
- }
213
-
214
- for (let i = 0; i < rects.length; i++) {
215
- const rect = rects[i]!
216
- const offset = i * 4
217
- this.rectScratch[offset] = rect.x
218
- this.rectScratch[offset + 1] = rect.y
219
- this.rectScratch[offset + 2] = rect.width
220
- this.rectScratch[offset + 3] = rect.height
221
- }
222
-
223
- return this.drawRectBuffer(this.rectScratch.subarray(0, floatCount), rects.length, color, scrollLeft)
224
- }
225
-
226
- destroy(): void {
227
- const handles = this.handles
228
- if (!handles) return
229
-
230
- const gl = this.shared.getGL()
231
- if (gl) {
232
- const { program, vao, unitBuffer, rectBuffer } = handles
233
- gl.deleteBuffer(unitBuffer)
234
- gl.deleteBuffer(rectBuffer)
235
- gl.deleteVertexArray(vao)
236
- gl.deleteProgram(program)
237
- }
238
- this.handles = null
239
- this.available = false
240
- }
241
-
242
- private initRectHandles(): RectWebGLHandles | null {
243
- const gl = this.shared.getGL()
244
- if (!gl) return null
245
-
246
- const vertexShader = createShader(gl, gl.VERTEX_SHADER, RECT_VERTEX_SHADER_SOURCE)
247
- const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE)
248
- if (!vertexShader || !fragmentShader) {
249
- if (vertexShader) gl.deleteShader(vertexShader)
250
- if (fragmentShader) gl.deleteShader(fragmentShader)
251
- return null
252
- }
253
-
254
- const program = createProgram(gl, vertexShader, fragmentShader)
255
- gl.deleteShader(vertexShader)
256
- gl.deleteShader(fragmentShader)
257
- if (!program) return null
258
-
259
- const vao = gl.createVertexArray()
260
- const unitBuffer = gl.createBuffer()
261
- const rectBuffer = gl.createBuffer()
262
- if (!vao || !unitBuffer || !rectBuffer) {
263
- if (vao) gl.deleteVertexArray(vao)
264
- if (unitBuffer) gl.deleteBuffer(unitBuffer)
265
- if (rectBuffer) gl.deleteBuffer(rectBuffer)
266
- gl.deleteProgram(program)
267
- return null
268
- }
269
-
270
- const resolutionLocation = gl.getUniformLocation(program, 'u_resolution')
271
- const scrollXLocation = gl.getUniformLocation(program, 'u_scrollX')
272
- const colorLocation = gl.getUniformLocation(program, 'u_color')
273
- if (!resolutionLocation || !scrollXLocation || !colorLocation) {
274
- gl.deleteBuffer(unitBuffer)
275
- gl.deleteBuffer(rectBuffer)
276
- gl.deleteVertexArray(vao)
277
- gl.deleteProgram(program)
278
- return null
279
- }
280
-
281
- const unitLocation = gl.getAttribLocation(program, 'a_unit')
282
- const rectLocation = gl.getAttribLocation(program, 'a_rect')
283
- if (unitLocation < 0 || rectLocation < 0) {
284
- gl.deleteBuffer(unitBuffer)
285
- gl.deleteBuffer(rectBuffer)
286
- gl.deleteVertexArray(vao)
287
- gl.deleteProgram(program)
288
- return null
289
- }
290
-
291
- gl.bindVertexArray(vao)
292
- gl.bindBuffer(gl.ARRAY_BUFFER, unitBuffer)
293
- gl.bufferData(gl.ARRAY_BUFFER, UNIT_QUAD, gl.STATIC_DRAW)
294
- gl.enableVertexAttribArray(unitLocation)
295
- gl.vertexAttribPointer(unitLocation, 2, gl.FLOAT, false, 0, 0)
296
- gl.vertexAttribDivisor(unitLocation, 0)
297
-
298
- gl.bindBuffer(gl.ARRAY_BUFFER, rectBuffer)
299
- gl.enableVertexAttribArray(rectLocation)
300
- gl.vertexAttribPointer(rectLocation, 4, gl.FLOAT, false, 16, 0)
301
- gl.vertexAttribDivisor(rectLocation, 1)
302
- gl.bindVertexArray(null)
303
-
304
- gl.enable(gl.BLEND)
305
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
306
-
307
- return {
308
- program,
309
- vao,
310
- unitBuffer,
311
- rectBuffer,
312
- resolutionLocation,
313
- scrollXLocation,
314
- colorLocation,
315
- }
302
+
303
+ gl.bindVertexArray(vao)
304
+ gl.bindBuffer(gl.ARRAY_BUFFER, unitBuffer)
305
+ gl.bufferData(gl.ARRAY_BUFFER, UNIT_QUAD, gl.STATIC_DRAW)
306
+ gl.enableVertexAttribArray(unitLocation)
307
+ gl.vertexAttribPointer(unitLocation, 2, gl.FLOAT, false, 0, 0)
308
+ gl.vertexAttribDivisor(unitLocation, 0)
309
+
310
+ gl.bindBuffer(gl.ARRAY_BUFFER, rectBuffer)
311
+ gl.enableVertexAttribArray(rectLocation)
312
+ gl.vertexAttribPointer(rectLocation, 4, gl.FLOAT, false, 16, 0)
313
+ gl.vertexAttribDivisor(rectLocation, 1)
314
+ gl.bindVertexArray(null)
315
+
316
+ gl.enable(gl.BLEND)
317
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
318
+
319
+ return {
320
+ program,
321
+ vao,
322
+ unitBuffer,
323
+ rectBuffer,
324
+ resolutionLocation,
325
+ scrollXLocation,
326
+ colorLocation,
316
327
  }
328
+ }
317
329
  }
318
330
 
319
331
  export class LineWebGLSurface {
320
- private shared: SharedWebGLSurface
321
- private handles: LineWebGLHandles | null = null
322
- private logicalWidth = 0
323
- private logicalHeight = 0
324
- private dpr = 1
325
- private available = false
326
- private vertexCapacity = 0
327
- private fillScratch = new Float32Array(0)
328
- private lineScratch = new Float32Array(0)
329
- private region: WebGLRegion | null = null
330
- private msaaTargets: MsaaTargets | null = null
331
-
332
- // Geometry cache: 以 points 数组引用 + halfWidth 为 key,避免每帧重算法线/miter
333
- private geoCache = new WeakMap<Array<{ x: number; y: number }>, Map<number, { vertices: Float32Array; vertexCount: number }>>()
334
-
335
- constructor(shared: SharedWebGLSurface) {
336
- this.shared = shared
337
- this.handles = this.initLineHandles()
338
- this.available = this.handles !== null
339
- }
340
-
341
- isAvailable(): boolean {
342
- return this.available
343
- }
344
-
345
- getCanvas(): HTMLCanvasElement {
346
- return this.shared.getCanvas()
347
- }
348
-
349
- setRegion(region: WebGLRegion): void {
350
- this.region = region
351
- }
352
-
353
- resize(width: number, height: number, dpr: number): void {
354
- this.logicalWidth = width
355
- this.logicalHeight = height
356
- this.dpr = dpr
357
- }
358
-
359
- clear(): void {
360
- if (!this.region || this.logicalWidth <= 0 || this.logicalHeight <= 0) return
361
- this.shared.clearRegion(this.region)
362
- }
363
-
364
- compositeTo(ctx: CanvasRenderingContext2D, options: WebGLCompositeOptions = {}): void {
365
- if (!this.region) return
366
- this.shared.compositeRegionTo(ctx, this.region, options)
367
- }
368
-
369
- drawLineStrips(lines: ColoredLineStrip[], scrollLeft: number): boolean {
370
- const handles = this.handles
371
- if (!handles || lines.length === 0 || this.logicalWidth <= 0 || this.logicalHeight <= 0) {
372
- return false
373
- }
374
-
375
- type DrawCmd = {
376
- colorValue: FloatColor
377
- mode: number
378
- firstVertex: number
379
- pointCount: number
380
- vertices?: Float32Array
381
- points?: Array<{ x: number; y: number }>
382
- }
383
-
384
- const gl = this.shared.getGL()
385
- const region = this.region
386
- if (!gl || !region) return false
387
-
388
- const drawCmds: DrawCmd[] = []
389
- let totalFloats = 0
390
- let hasNativeLines = false
391
-
392
- for (const line of lines) {
393
- if (line.points.length < 2) return false
394
-
395
- const colorValue = parseColor(line.color)
396
- if (!colorValue) return false
397
-
398
- if (line.width <= 1) {
399
- hasNativeLines = true
400
- drawCmds.push({
401
- colorValue,
402
- mode: gl.LINE_STRIP,
403
- firstVertex: totalFloats / 2,
404
- pointCount: line.points.length,
405
- points: line.points,
406
- })
407
- totalFloats += line.points.length * 2
408
- continue
409
- }
410
-
411
- const geometry = this.getLineGeometry(line)
412
- if (!geometry) return false
413
- drawCmds.push({
414
- colorValue,
415
- mode: gl.TRIANGLES,
416
- firstVertex: totalFloats / 2,
417
- pointCount: geometry.vertexCount,
418
- vertices: geometry.vertices,
419
- })
420
- totalFloats += geometry.vertices.length
421
- }
422
-
423
- if (this.lineScratch.length < totalFloats) {
424
- this.lineScratch = new Float32Array(nextBufferFloatCapacity(totalFloats))
425
- }
426
- let floatOffset = 0
427
- for (const cmd of drawCmds) {
428
- if (cmd.vertices) {
429
- this.lineScratch.set(cmd.vertices, floatOffset)
430
- floatOffset += cmd.vertices.length
431
- continue
432
- }
433
-
434
- const points = cmd.points
435
- if (!points) return false
436
- for (const point of points) {
437
- this.lineScratch[floatOffset++] = point.x
438
- this.lineScratch[floatOffset++] = point.y
439
- }
440
- }
441
-
442
- const msaaRender = this.beginMsaaRender(gl, region)
443
- if (!msaaRender && !this.shared.bindRegion(region)) {
444
- return false
445
- }
446
-
447
- gl.useProgram(handles.basic.program)
448
- gl.bindVertexArray(handles.basic.vao)
449
- gl.bindBuffer(gl.ARRAY_BUFFER, handles.basic.vertexBuffer)
450
-
451
- if (this.vertexCapacity < totalFloats) {
452
- this.vertexCapacity = nextBufferFloatCapacity(totalFloats)
453
- gl.bufferData(gl.ARRAY_BUFFER, this.vertexCapacity * Float32Array.BYTES_PER_ELEMENT, gl.DYNAMIC_DRAW)
454
- }
455
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.lineScratch.subarray(0, totalFloats))
456
-
457
- gl.uniform2f(handles.basic.resolutionLocation, this.logicalWidth, this.logicalHeight)
458
- gl.uniform1f(handles.basic.scrollXLocation, scrollLeft)
459
- if (hasNativeLines) {
460
- gl.lineWidth(1)
461
- }
462
-
463
- for (const cmd of drawCmds) {
464
- gl.uniform4f(handles.basic.colorLocation, cmd.colorValue[0], cmd.colorValue[1], cmd.colorValue[2], cmd.colorValue[3])
465
- gl.drawArrays(cmd.mode, cmd.firstVertex, cmd.pointCount)
466
- }
467
-
468
- gl.bindVertexArray(null)
469
-
470
- if (msaaRender) {
471
- this.resolveMsaaToSharedRegion(gl, msaaRender.targets, msaaRender.physical)
472
- }
473
-
474
- gl.bindFramebuffer(gl.FRAMEBUFFER, null)
475
- return true
476
- }
477
-
478
- private getLineGeometry(line: LineStrip): { vertices: Float32Array; vertexCount: number } | null {
479
- const halfWidth = line.width / 2
480
- let widthMap = this.geoCache.get(line.points)
481
- if (widthMap) {
482
- const cached = widthMap.get(halfWidth)
483
- if (cached) return cached
484
- } else {
485
- widthMap = new Map()
486
- this.geoCache.set(line.points, widthMap)
487
- }
488
-
489
- const geometry = buildJoinedPolylineGeometry(line.points, halfWidth)
490
- if (geometry) widthMap.set(halfWidth, geometry)
491
- return geometry
492
- }
493
-
494
- drawFilledBand(band: FilledBand, color: string, scrollLeft: number): boolean {
495
- const handles = this.handles
496
- const pointCount = Math.min(band.upperPoints.length, band.lowerPoints.length)
497
- if (!handles || pointCount < 2 || this.logicalWidth <= 0 || this.logicalHeight <= 0) {
498
- return false
499
- }
500
-
501
- const colorValue = parseColor(color)
502
- if (!colorValue) return false
503
-
504
- const vertexCount = pointCount * 2
505
- const floatCount = vertexCount * 2
506
- if (this.fillScratch.length < floatCount) {
507
- this.fillScratch = new Float32Array(nextBufferFloatCapacity(floatCount))
508
- }
509
-
510
- let writeIndex = 0
511
- for (let i = 0; i < pointCount; i++) {
512
- const upper = band.upperPoints[i]!
513
- const lower = band.lowerPoints[i]!
514
- this.fillScratch[writeIndex++] = upper.x
515
- this.fillScratch[writeIndex++] = upper.y
516
- this.fillScratch[writeIndex++] = lower.x
517
- this.fillScratch[writeIndex++] = lower.y
518
- }
519
-
520
- const gl = this.shared.getGL()
521
- const region = this.region
522
- if (!gl || !region) return false
523
-
524
- const msaaRender = this.beginMsaaRender(gl, region)
525
- if (!msaaRender && !this.shared.bindRegion(region)) return false
526
-
527
- gl.useProgram(handles.basic.program)
528
- gl.bindVertexArray(handles.basic.vao)
529
- gl.bindBuffer(gl.ARRAY_BUFFER, handles.basic.vertexBuffer)
530
-
531
- if (this.vertexCapacity < floatCount) {
532
- this.vertexCapacity = nextBufferFloatCapacity(floatCount)
533
- gl.bufferData(gl.ARRAY_BUFFER, this.vertexCapacity * Float32Array.BYTES_PER_ELEMENT, gl.DYNAMIC_DRAW)
534
- }
535
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.fillScratch.subarray(0, floatCount))
536
-
537
- gl.uniform2f(handles.basic.resolutionLocation, this.logicalWidth, this.logicalHeight)
538
- gl.uniform1f(handles.basic.scrollXLocation, scrollLeft)
539
- gl.uniform4f(handles.basic.colorLocation, colorValue[0], colorValue[1], colorValue[2], colorValue[3])
540
- gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertexCount)
541
- gl.bindVertexArray(null)
542
-
543
- if (msaaRender) {
544
- this.resolveMsaaToSharedRegion(gl, msaaRender.targets, msaaRender.physical)
545
- }
546
-
547
- gl.bindFramebuffer(gl.FRAMEBUFFER, null)
548
- return true
549
- }
550
-
551
- destroy(): void {
552
- const handles = this.handles
553
- const gl = this.shared.getGL()
554
- if (gl) {
555
- this.destroyMsaaTargets(gl)
556
- }
557
- if (!handles) {
558
- this.vertexCapacity = 0
559
- return
560
- }
561
-
562
- if (gl) {
563
- const { basic } = handles
564
- gl.deleteBuffer(basic.vertexBuffer)
565
- gl.deleteVertexArray(basic.vao)
566
- gl.deleteProgram(basic.program)
567
- }
568
- this.handles = null
569
- this.available = false
570
- this.vertexCapacity = 0
571
- }
572
-
573
- private beginMsaaRender(gl: WebGL2RenderingContext, region: WebGLRegion): { targets: MsaaTargets; physical: PhysicalRegion } | null {
574
- const physical = this.shared.getPhysicalRegion(region)
575
- const targets = physical ? this.ensureMsaaTargets(gl, physical) : null
576
- if (!physical || !targets) return null
577
-
578
- gl.bindFramebuffer(gl.FRAMEBUFFER, targets.msaaFramebuffer)
579
- gl.viewport(0, 0, targets.widthPx, targets.heightPx)
580
- gl.disable(gl.SCISSOR_TEST)
581
- gl.clearColor(0, 0, 0, 0)
582
- gl.clear(gl.COLOR_BUFFER_BIT)
583
- return { targets, physical }
584
- }
585
-
586
- private ensureMsaaTargets(gl: WebGL2RenderingContext, physical: PhysicalRegion): MsaaTargets | null {
587
- const preferredSamples = 4
588
- const maxSamples = Number(gl.getParameter(gl.MAX_SAMPLES)) || 0
589
- const samples = Math.max(1, Math.min(preferredSamples, maxSamples))
590
- if (samples <= 1) return null
591
-
592
- const existing = this.msaaTargets
593
- if (
594
- existing
595
- && existing.widthPx === physical.widthPx
596
- && existing.heightPx === physical.heightPx
597
- && existing.samples === samples
598
- ) {
599
- return existing
600
- }
601
-
602
- this.destroyMsaaTargets(gl)
603
-
604
- const msaaFramebuffer = gl.createFramebuffer()
605
- const msaaColorRenderbuffer = gl.createRenderbuffer()
606
- const resolveFramebuffer = gl.createFramebuffer()
607
- const resolveTexture = gl.createTexture()
608
- if (!msaaFramebuffer || !msaaColorRenderbuffer || !resolveFramebuffer || !resolveTexture) {
609
- if (msaaFramebuffer) gl.deleteFramebuffer(msaaFramebuffer)
610
- if (msaaColorRenderbuffer) gl.deleteRenderbuffer(msaaColorRenderbuffer)
611
- if (resolveFramebuffer) gl.deleteFramebuffer(resolveFramebuffer)
612
- if (resolveTexture) gl.deleteTexture(resolveTexture)
613
- return null
614
- }
615
-
616
- gl.bindFramebuffer(gl.FRAMEBUFFER, msaaFramebuffer)
617
- gl.bindRenderbuffer(gl.RENDERBUFFER, msaaColorRenderbuffer)
618
- gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, gl.RGBA8, physical.widthPx, physical.heightPx)
619
- gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msaaColorRenderbuffer)
620
- if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
621
- gl.bindFramebuffer(gl.FRAMEBUFFER, null)
622
- gl.bindRenderbuffer(gl.RENDERBUFFER, null)
623
- gl.deleteFramebuffer(msaaFramebuffer)
624
- gl.deleteRenderbuffer(msaaColorRenderbuffer)
625
- gl.deleteFramebuffer(resolveFramebuffer)
626
- gl.deleteTexture(resolveTexture)
627
- return null
628
- }
629
-
630
- gl.bindFramebuffer(gl.FRAMEBUFFER, resolveFramebuffer)
631
- gl.bindTexture(gl.TEXTURE_2D, resolveTexture)
632
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
633
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
634
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
635
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
636
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, physical.widthPx, physical.heightPx, 0, gl.RGBA, gl.UNSIGNED_BYTE, null)
637
- gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, resolveTexture, 0)
638
- if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
639
- gl.bindFramebuffer(gl.FRAMEBUFFER, null)
640
- gl.bindTexture(gl.TEXTURE_2D, null)
641
- gl.bindRenderbuffer(gl.RENDERBUFFER, null)
642
- gl.deleteFramebuffer(msaaFramebuffer)
643
- gl.deleteRenderbuffer(msaaColorRenderbuffer)
644
- gl.deleteFramebuffer(resolveFramebuffer)
645
- gl.deleteTexture(resolveTexture)
646
- return null
647
- }
648
-
649
- gl.bindFramebuffer(gl.FRAMEBUFFER, null)
650
- gl.bindTexture(gl.TEXTURE_2D, null)
651
- gl.bindRenderbuffer(gl.RENDERBUFFER, null)
652
-
653
- const targets = {
654
- samples,
655
- widthPx: physical.widthPx,
656
- heightPx: physical.heightPx,
657
- msaaFramebuffer,
658
- msaaColorRenderbuffer,
659
- resolveFramebuffer,
660
- resolveTexture,
661
- }
662
- this.msaaTargets = targets
663
- return targets
664
- }
665
-
666
- private destroyMsaaTargets(gl: WebGL2RenderingContext): void {
667
- const targets = this.msaaTargets
668
- if (!targets) return
669
- gl.deleteFramebuffer(targets.msaaFramebuffer)
670
- gl.deleteRenderbuffer(targets.msaaColorRenderbuffer)
671
- gl.deleteFramebuffer(targets.resolveFramebuffer)
672
- gl.deleteTexture(targets.resolveTexture)
673
- this.msaaTargets = null
674
- }
675
-
676
- private resolveMsaaToSharedRegion(gl: WebGL2RenderingContext, targets: MsaaTargets, physical: PhysicalRegion): void {
677
- gl.bindFramebuffer(gl.READ_FRAMEBUFFER, targets.msaaFramebuffer)
678
- gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, targets.resolveFramebuffer)
679
- gl.blitFramebuffer(
680
- 0, 0, targets.widthPx, targets.heightPx,
681
- 0, 0, targets.widthPx, targets.heightPx,
682
- gl.COLOR_BUFFER_BIT,
683
- gl.NEAREST,
684
- )
685
-
686
- gl.bindFramebuffer(gl.READ_FRAMEBUFFER, targets.resolveFramebuffer)
687
- gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null)
688
- const destY = this.shared.getCanvas().height - physical.sourceY - physical.heightPx
689
- gl.disable(gl.SCISSOR_TEST)
690
- gl.blitFramebuffer(
691
- 0, 0, targets.widthPx, targets.heightPx,
692
- physical.sourceX, destY, physical.sourceX + physical.widthPx, destY + physical.heightPx,
693
- gl.COLOR_BUFFER_BIT,
694
- gl.NEAREST,
695
- )
696
- gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null)
697
- gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null)
698
- }
699
-
700
- private initLineHandles(): LineWebGLHandles | null {
701
- const gl = this.shared.getGL()
702
- if (!gl) return null
703
-
704
- const vertexShader = createShader(gl, gl.VERTEX_SHADER, LINE_VERTEX_SHADER_SOURCE)
705
- const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE)
706
- if (!vertexShader || !fragmentShader) {
707
- if (vertexShader) gl.deleteShader(vertexShader)
708
- if (fragmentShader) gl.deleteShader(fragmentShader)
709
- return null
710
- }
711
-
712
- const program = createProgram(gl, vertexShader, fragmentShader)
713
- gl.deleteShader(vertexShader)
714
- gl.deleteShader(fragmentShader)
715
- if (!program) return null
716
-
717
- const vao = gl.createVertexArray()
718
- const vertexBuffer = gl.createBuffer()
719
- if (!vao || !vertexBuffer) {
720
- if (vao) gl.deleteVertexArray(vao)
721
- if (vertexBuffer) gl.deleteBuffer(vertexBuffer)
722
- gl.deleteProgram(program)
723
- return null
724
- }
725
-
726
- const resolutionLocation = gl.getUniformLocation(program, 'u_resolution')
727
- const scrollXLocation = gl.getUniformLocation(program, 'u_scrollX')
728
- const colorLocation = gl.getUniformLocation(program, 'u_color')
729
- if (!resolutionLocation || !scrollXLocation || !colorLocation) {
730
- gl.deleteBuffer(vertexBuffer)
731
- gl.deleteVertexArray(vao)
732
- gl.deleteProgram(program)
733
- return null
734
- }
735
-
736
- const positionLocation = gl.getAttribLocation(program, 'a_position')
737
- if (positionLocation < 0) {
738
- gl.deleteBuffer(vertexBuffer)
739
- gl.deleteVertexArray(vao)
740
- gl.deleteProgram(program)
741
- return null
742
- }
743
-
744
- gl.bindVertexArray(vao)
745
- gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
746
- gl.enableVertexAttribArray(positionLocation)
747
- gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0)
748
- gl.bindVertexArray(null)
749
-
750
- gl.enable(gl.BLEND)
751
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
752
-
753
- return {
754
- basic: {
755
- program,
756
- vao,
757
- vertexBuffer,
758
- resolutionLocation,
759
- scrollXLocation,
760
- colorLocation,
761
- },
762
- }
332
+ private shared: SharedWebGLSurface
333
+ private handles: LineWebGLHandles | null = null
334
+ private logicalWidth = 0
335
+ private logicalHeight = 0
336
+ private dpr = 1
337
+ private available = false
338
+ private vertexCapacity = 0
339
+ private fillScratch = new Float32Array(0)
340
+ private lineScratch = new Float32Array(0)
341
+ private region: WebGLRegion | null = null
342
+ private msaaTargets: MsaaTargets | null = null
343
+
344
+ // Geometry cache: 以 points 数组引用 + halfWidth 为 key,避免每帧重算法线/miter
345
+ private geoCache = new WeakMap<
346
+ Array<{ x: number; y: number }>,
347
+ Map<number, { vertices: Float32Array; vertexCount: number }>
348
+ >()
349
+
350
+ constructor(shared: SharedWebGLSurface) {
351
+ this.shared = shared
352
+ this.handles = this.initLineHandles()
353
+ this.available = this.handles !== null
354
+ }
355
+
356
+ isAvailable(): boolean {
357
+ return this.available
358
+ }
359
+
360
+ getCanvas(): HTMLCanvasElement {
361
+ return this.shared.getCanvas()
362
+ }
363
+
364
+ setRegion(region: WebGLRegion): void {
365
+ this.region = region
366
+ }
367
+
368
+ resize(width: number, height: number, dpr: number): void {
369
+ this.logicalWidth = width
370
+ this.logicalHeight = height
371
+ this.dpr = dpr
372
+ }
373
+
374
+ clear(): void {
375
+ if (!this.region || this.logicalWidth <= 0 || this.logicalHeight <= 0) return
376
+ this.shared.clearRegion(this.region)
377
+ }
378
+
379
+ compositeTo(ctx: CanvasRenderingContext2D, options: WebGLCompositeOptions = {}): void {
380
+ if (!this.region) return
381
+ this.shared.compositeRegionTo(ctx, this.region, options)
382
+ }
383
+
384
+ drawLineStrips(lines: ColoredLineStrip[], scrollLeft: number): boolean {
385
+ const handles = this.handles
386
+ if (!handles || lines.length === 0 || this.logicalWidth <= 0 || this.logicalHeight <= 0) {
387
+ return false
388
+ }
389
+
390
+ type DrawCmd = {
391
+ colorValue: FloatColor
392
+ mode: number
393
+ firstVertex: number
394
+ pointCount: number
395
+ vertices?: Float32Array
396
+ points?: Array<{ x: number; y: number }>
397
+ }
398
+
399
+ const gl = this.shared.getGL()
400
+ const region = this.region
401
+ if (!gl || !region) return false
402
+
403
+ const drawCmds: DrawCmd[] = []
404
+ let totalFloats = 0
405
+ let hasNativeLines = false
406
+
407
+ for (const line of lines) {
408
+ if (line.points.length < 2) return false
409
+
410
+ const colorValue = parseColor(line.color)
411
+ if (!colorValue) return false
412
+
413
+ if (line.width <= 1) {
414
+ hasNativeLines = true
415
+ drawCmds.push({
416
+ colorValue,
417
+ mode: gl.LINE_STRIP,
418
+ firstVertex: totalFloats / 2,
419
+ pointCount: line.points.length,
420
+ points: line.points,
421
+ })
422
+ totalFloats += line.points.length * 2
423
+ continue
424
+ }
425
+
426
+ const geometry = this.getLineGeometry(line)
427
+ if (!geometry) return false
428
+ drawCmds.push({
429
+ colorValue,
430
+ mode: gl.TRIANGLES,
431
+ firstVertex: totalFloats / 2,
432
+ pointCount: geometry.vertexCount,
433
+ vertices: geometry.vertices,
434
+ })
435
+ totalFloats += geometry.vertices.length
436
+ }
437
+
438
+ if (this.lineScratch.length < totalFloats) {
439
+ this.lineScratch = new Float32Array(nextBufferFloatCapacity(totalFloats))
440
+ }
441
+ let floatOffset = 0
442
+ for (const cmd of drawCmds) {
443
+ if (cmd.vertices) {
444
+ this.lineScratch.set(cmd.vertices, floatOffset)
445
+ floatOffset += cmd.vertices.length
446
+ continue
447
+ }
448
+
449
+ const points = cmd.points
450
+ if (!points) return false
451
+ for (const point of points) {
452
+ this.lineScratch[floatOffset++] = point.x
453
+ this.lineScratch[floatOffset++] = point.y
454
+ }
455
+ }
456
+
457
+ const msaaRender = this.beginMsaaRender(gl, region)
458
+ if (!msaaRender && !this.shared.bindRegion(region)) {
459
+ return false
460
+ }
461
+
462
+ gl.useProgram(handles.basic.program)
463
+ gl.bindVertexArray(handles.basic.vao)
464
+ gl.bindBuffer(gl.ARRAY_BUFFER, handles.basic.vertexBuffer)
465
+
466
+ if (this.vertexCapacity < totalFloats) {
467
+ this.vertexCapacity = nextBufferFloatCapacity(totalFloats)
468
+ gl.bufferData(
469
+ gl.ARRAY_BUFFER,
470
+ this.vertexCapacity * Float32Array.BYTES_PER_ELEMENT,
471
+ gl.DYNAMIC_DRAW,
472
+ )
473
+ }
474
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.lineScratch.subarray(0, totalFloats))
475
+
476
+ gl.uniform2f(handles.basic.resolutionLocation, this.logicalWidth, this.logicalHeight)
477
+ gl.uniform1f(handles.basic.scrollXLocation, scrollLeft)
478
+ if (hasNativeLines) {
479
+ gl.lineWidth(1)
480
+ }
481
+
482
+ for (const cmd of drawCmds) {
483
+ gl.uniform4f(
484
+ handles.basic.colorLocation,
485
+ cmd.colorValue[0],
486
+ cmd.colorValue[1],
487
+ cmd.colorValue[2],
488
+ cmd.colorValue[3],
489
+ )
490
+ gl.drawArrays(cmd.mode, cmd.firstVertex, cmd.pointCount)
491
+ }
492
+
493
+ gl.bindVertexArray(null)
494
+
495
+ if (msaaRender) {
496
+ this.resolveMsaaToSharedRegion(gl, msaaRender.targets, msaaRender.physical)
497
+ }
498
+
499
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null)
500
+ return true
501
+ }
502
+
503
+ private getLineGeometry(line: LineStrip): { vertices: Float32Array; vertexCount: number } | null {
504
+ const halfWidth = line.width / 2
505
+ let widthMap = this.geoCache.get(line.points)
506
+ if (widthMap) {
507
+ const cached = widthMap.get(halfWidth)
508
+ if (cached) return cached
509
+ } else {
510
+ widthMap = new Map()
511
+ this.geoCache.set(line.points, widthMap)
512
+ }
513
+
514
+ const geometry = buildJoinedPolylineGeometry(line.points, halfWidth)
515
+ if (geometry) widthMap.set(halfWidth, geometry)
516
+ return geometry
517
+ }
518
+
519
+ drawFilledBand(band: FilledBand, color: string, scrollLeft: number): boolean {
520
+ const handles = this.handles
521
+ const pointCount = Math.min(band.upperPoints.length, band.lowerPoints.length)
522
+ if (!handles || pointCount < 2 || this.logicalWidth <= 0 || this.logicalHeight <= 0) {
523
+ return false
524
+ }
525
+
526
+ const colorValue = parseColor(color)
527
+ if (!colorValue) return false
528
+
529
+ const vertexCount = pointCount * 2
530
+ const floatCount = vertexCount * 2
531
+ if (this.fillScratch.length < floatCount) {
532
+ this.fillScratch = new Float32Array(nextBufferFloatCapacity(floatCount))
533
+ }
534
+
535
+ let writeIndex = 0
536
+ for (let i = 0; i < pointCount; i++) {
537
+ const upper = band.upperPoints[i]!
538
+ const lower = band.lowerPoints[i]!
539
+ this.fillScratch[writeIndex++] = upper.x
540
+ this.fillScratch[writeIndex++] = upper.y
541
+ this.fillScratch[writeIndex++] = lower.x
542
+ this.fillScratch[writeIndex++] = lower.y
763
543
  }
544
+
545
+ const gl = this.shared.getGL()
546
+ const region = this.region
547
+ if (!gl || !region) return false
548
+
549
+ const msaaRender = this.beginMsaaRender(gl, region)
550
+ if (!msaaRender && !this.shared.bindRegion(region)) return false
551
+
552
+ gl.useProgram(handles.basic.program)
553
+ gl.bindVertexArray(handles.basic.vao)
554
+ gl.bindBuffer(gl.ARRAY_BUFFER, handles.basic.vertexBuffer)
555
+
556
+ if (this.vertexCapacity < floatCount) {
557
+ this.vertexCapacity = nextBufferFloatCapacity(floatCount)
558
+ gl.bufferData(
559
+ gl.ARRAY_BUFFER,
560
+ this.vertexCapacity * Float32Array.BYTES_PER_ELEMENT,
561
+ gl.DYNAMIC_DRAW,
562
+ )
563
+ }
564
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.fillScratch.subarray(0, floatCount))
565
+
566
+ gl.uniform2f(handles.basic.resolutionLocation, this.logicalWidth, this.logicalHeight)
567
+ gl.uniform1f(handles.basic.scrollXLocation, scrollLeft)
568
+ gl.uniform4f(
569
+ handles.basic.colorLocation,
570
+ colorValue[0],
571
+ colorValue[1],
572
+ colorValue[2],
573
+ colorValue[3],
574
+ )
575
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, vertexCount)
576
+ gl.bindVertexArray(null)
577
+
578
+ if (msaaRender) {
579
+ this.resolveMsaaToSharedRegion(gl, msaaRender.targets, msaaRender.physical)
580
+ }
581
+
582
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null)
583
+ return true
584
+ }
585
+
586
+ destroy(): void {
587
+ const handles = this.handles
588
+ const gl = this.shared.getGL()
589
+ if (gl) {
590
+ this.destroyMsaaTargets(gl)
591
+ }
592
+ if (!handles) {
593
+ this.vertexCapacity = 0
594
+ return
595
+ }
596
+
597
+ if (gl) {
598
+ const { basic } = handles
599
+ gl.deleteBuffer(basic.vertexBuffer)
600
+ gl.deleteVertexArray(basic.vao)
601
+ gl.deleteProgram(basic.program)
602
+ }
603
+ this.handles = null
604
+ this.available = false
605
+ this.vertexCapacity = 0
606
+ }
607
+
608
+ private beginMsaaRender(
609
+ gl: WebGL2RenderingContext,
610
+ region: WebGLRegion,
611
+ ): { targets: MsaaTargets; physical: PhysicalRegion } | null {
612
+ const physical = this.shared.getPhysicalRegion(region)
613
+ const targets = physical ? this.ensureMsaaTargets(gl, physical) : null
614
+ if (!physical || !targets) return null
615
+
616
+ gl.bindFramebuffer(gl.FRAMEBUFFER, targets.msaaFramebuffer)
617
+ gl.viewport(0, 0, targets.widthPx, targets.heightPx)
618
+ gl.disable(gl.SCISSOR_TEST)
619
+ gl.clearColor(0, 0, 0, 0)
620
+ gl.clear(gl.COLOR_BUFFER_BIT)
621
+ return { targets, physical }
622
+ }
623
+
624
+ private ensureMsaaTargets(
625
+ gl: WebGL2RenderingContext,
626
+ physical: PhysicalRegion,
627
+ ): MsaaTargets | null {
628
+ const preferredSamples = 4
629
+ const maxSamples = Number(gl.getParameter(gl.MAX_SAMPLES)) || 0
630
+ const samples = Math.max(1, Math.min(preferredSamples, maxSamples))
631
+ if (samples <= 1) return null
632
+
633
+ const existing = this.msaaTargets
634
+ if (
635
+ existing &&
636
+ existing.widthPx === physical.widthPx &&
637
+ existing.heightPx === physical.heightPx &&
638
+ existing.samples === samples
639
+ ) {
640
+ return existing
641
+ }
642
+
643
+ this.destroyMsaaTargets(gl)
644
+
645
+ const msaaFramebuffer = gl.createFramebuffer()
646
+ const msaaColorRenderbuffer = gl.createRenderbuffer()
647
+ const resolveFramebuffer = gl.createFramebuffer()
648
+ const resolveTexture = gl.createTexture()
649
+ if (!msaaFramebuffer || !msaaColorRenderbuffer || !resolveFramebuffer || !resolveTexture) {
650
+ if (msaaFramebuffer) gl.deleteFramebuffer(msaaFramebuffer)
651
+ if (msaaColorRenderbuffer) gl.deleteRenderbuffer(msaaColorRenderbuffer)
652
+ if (resolveFramebuffer) gl.deleteFramebuffer(resolveFramebuffer)
653
+ if (resolveTexture) gl.deleteTexture(resolveTexture)
654
+ return null
655
+ }
656
+
657
+ gl.bindFramebuffer(gl.FRAMEBUFFER, msaaFramebuffer)
658
+ gl.bindRenderbuffer(gl.RENDERBUFFER, msaaColorRenderbuffer)
659
+ gl.renderbufferStorageMultisample(
660
+ gl.RENDERBUFFER,
661
+ samples,
662
+ gl.RGBA8,
663
+ physical.widthPx,
664
+ physical.heightPx,
665
+ )
666
+ gl.framebufferRenderbuffer(
667
+ gl.FRAMEBUFFER,
668
+ gl.COLOR_ATTACHMENT0,
669
+ gl.RENDERBUFFER,
670
+ msaaColorRenderbuffer,
671
+ )
672
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
673
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null)
674
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null)
675
+ gl.deleteFramebuffer(msaaFramebuffer)
676
+ gl.deleteRenderbuffer(msaaColorRenderbuffer)
677
+ gl.deleteFramebuffer(resolveFramebuffer)
678
+ gl.deleteTexture(resolveTexture)
679
+ return null
680
+ }
681
+
682
+ gl.bindFramebuffer(gl.FRAMEBUFFER, resolveFramebuffer)
683
+ gl.bindTexture(gl.TEXTURE_2D, resolveTexture)
684
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
685
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
686
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE)
687
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE)
688
+ gl.texImage2D(
689
+ gl.TEXTURE_2D,
690
+ 0,
691
+ gl.RGBA,
692
+ physical.widthPx,
693
+ physical.heightPx,
694
+ 0,
695
+ gl.RGBA,
696
+ gl.UNSIGNED_BYTE,
697
+ null,
698
+ )
699
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, resolveTexture, 0)
700
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) {
701
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null)
702
+ gl.bindTexture(gl.TEXTURE_2D, null)
703
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null)
704
+ gl.deleteFramebuffer(msaaFramebuffer)
705
+ gl.deleteRenderbuffer(msaaColorRenderbuffer)
706
+ gl.deleteFramebuffer(resolveFramebuffer)
707
+ gl.deleteTexture(resolveTexture)
708
+ return null
709
+ }
710
+
711
+ gl.bindFramebuffer(gl.FRAMEBUFFER, null)
712
+ gl.bindTexture(gl.TEXTURE_2D, null)
713
+ gl.bindRenderbuffer(gl.RENDERBUFFER, null)
714
+
715
+ const targets = {
716
+ samples,
717
+ widthPx: physical.widthPx,
718
+ heightPx: physical.heightPx,
719
+ msaaFramebuffer,
720
+ msaaColorRenderbuffer,
721
+ resolveFramebuffer,
722
+ resolveTexture,
723
+ }
724
+ this.msaaTargets = targets
725
+ return targets
726
+ }
727
+
728
+ private destroyMsaaTargets(gl: WebGL2RenderingContext): void {
729
+ const targets = this.msaaTargets
730
+ if (!targets) return
731
+ gl.deleteFramebuffer(targets.msaaFramebuffer)
732
+ gl.deleteRenderbuffer(targets.msaaColorRenderbuffer)
733
+ gl.deleteFramebuffer(targets.resolveFramebuffer)
734
+ gl.deleteTexture(targets.resolveTexture)
735
+ this.msaaTargets = null
736
+ }
737
+
738
+ private resolveMsaaToSharedRegion(
739
+ gl: WebGL2RenderingContext,
740
+ targets: MsaaTargets,
741
+ physical: PhysicalRegion,
742
+ ): void {
743
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, targets.msaaFramebuffer)
744
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, targets.resolveFramebuffer)
745
+ gl.blitFramebuffer(
746
+ 0,
747
+ 0,
748
+ targets.widthPx,
749
+ targets.heightPx,
750
+ 0,
751
+ 0,
752
+ targets.widthPx,
753
+ targets.heightPx,
754
+ gl.COLOR_BUFFER_BIT,
755
+ gl.NEAREST,
756
+ )
757
+
758
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, targets.resolveFramebuffer)
759
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null)
760
+ const destY = this.shared.getCanvas().height - physical.sourceY - physical.heightPx
761
+ gl.disable(gl.SCISSOR_TEST)
762
+ gl.blitFramebuffer(
763
+ 0,
764
+ 0,
765
+ targets.widthPx,
766
+ targets.heightPx,
767
+ physical.sourceX,
768
+ destY,
769
+ physical.sourceX + physical.widthPx,
770
+ destY + physical.heightPx,
771
+ gl.COLOR_BUFFER_BIT,
772
+ gl.NEAREST,
773
+ )
774
+ gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null)
775
+ gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null)
776
+ }
777
+
778
+ private initLineHandles(): LineWebGLHandles | null {
779
+ const gl = this.shared.getGL()
780
+ if (!gl) return null
781
+
782
+ const vertexShader = createShader(gl, gl.VERTEX_SHADER, LINE_VERTEX_SHADER_SOURCE)
783
+ const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE)
784
+ if (!vertexShader || !fragmentShader) {
785
+ if (vertexShader) gl.deleteShader(vertexShader)
786
+ if (fragmentShader) gl.deleteShader(fragmentShader)
787
+ return null
788
+ }
789
+
790
+ const program = createProgram(gl, vertexShader, fragmentShader)
791
+ gl.deleteShader(vertexShader)
792
+ gl.deleteShader(fragmentShader)
793
+ if (!program) return null
794
+
795
+ const vao = gl.createVertexArray()
796
+ const vertexBuffer = gl.createBuffer()
797
+ if (!vao || !vertexBuffer) {
798
+ if (vao) gl.deleteVertexArray(vao)
799
+ if (vertexBuffer) gl.deleteBuffer(vertexBuffer)
800
+ gl.deleteProgram(program)
801
+ return null
802
+ }
803
+
804
+ const resolutionLocation = gl.getUniformLocation(program, 'u_resolution')
805
+ const scrollXLocation = gl.getUniformLocation(program, 'u_scrollX')
806
+ const colorLocation = gl.getUniformLocation(program, 'u_color')
807
+ if (!resolutionLocation || !scrollXLocation || !colorLocation) {
808
+ gl.deleteBuffer(vertexBuffer)
809
+ gl.deleteVertexArray(vao)
810
+ gl.deleteProgram(program)
811
+ return null
812
+ }
813
+
814
+ const positionLocation = gl.getAttribLocation(program, 'a_position')
815
+ if (positionLocation < 0) {
816
+ gl.deleteBuffer(vertexBuffer)
817
+ gl.deleteVertexArray(vao)
818
+ gl.deleteProgram(program)
819
+ return null
820
+ }
821
+
822
+ gl.bindVertexArray(vao)
823
+ gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer)
824
+ gl.enableVertexAttribArray(positionLocation)
825
+ gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0)
826
+ gl.bindVertexArray(null)
827
+
828
+ gl.enable(gl.BLEND)
829
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
830
+
831
+ return {
832
+ basic: {
833
+ program,
834
+ vao,
835
+ vertexBuffer,
836
+ resolutionLocation,
837
+ scrollXLocation,
838
+ colorLocation,
839
+ },
840
+ }
841
+ }
764
842
  }
765
843
  function nextBufferFloatCapacity(required: number): number {
766
- let capacity = 1
767
- while (capacity < required) {
768
- capacity <<= 1
769
- }
770
- return capacity
844
+ let capacity = 1
845
+ while (capacity < required) {
846
+ capacity <<= 1
847
+ }
848
+ return capacity
771
849
  }
772
850
 
773
851
  interface PolylineNormal {
774
- nx: number
775
- ny: number
776
- valid: boolean
852
+ nx: number
853
+ ny: number
854
+ valid: boolean
777
855
  }
778
856
 
779
857
  function buildJoinedPolylineGeometry(points: Array<{ x: number; y: number }>, halfWidth: number) {
780
- if (points.length < 2) return null
781
-
782
- // 使用固定结构数组,避免动态对象分配
783
- const normals: PolylineNormal[] = new Array(points.length - 1)
784
- let validSegmentCount = 0
785
-
786
- // 第一遍:计算所有法线(用 sqrt 替代 hypot,缓存逆长度)
787
- for (let i = 0; i < points.length - 1; i++) {
788
- const start = points[i]!
789
- const end = points[i + 1]!
790
- const dx = end.x - start.x
791
- const dy = end.y - start.y
792
- const lenSq = dx * dx + dy * dy
793
- if (lenSq <= 0) {
794
- normals[i] = { nx: 0, ny: 0, valid: false }
795
- continue
796
- }
797
- const invLen = 1 / Math.sqrt(lenSq)
798
- normals[i] = { nx: -dy * invLen, ny: dx * invLen, valid: true }
799
- validSegmentCount++
800
- }
801
-
802
- if (validSegmentCount === 0) return null
803
-
804
- // 预分配顶点数组:每对有效相邻点生成12个float(6个顶点 * 2个坐标)
805
- const maxVerticesFloats = (points.length - 1) * 12
806
- const vertices = new Float32Array(maxVerticesFloats)
807
- let vertexWriteIndex = 0
808
-
809
- // 计算 miter 并直接写入顶点
810
- for (let i = 0; i < points.length - 1; i++) {
811
- const curr = points[i]!
812
- const next = points[i + 1]!
813
-
814
- const prevNormal = i > 0 ? normals[i - 1] : null
815
- const currNormal = normals[i]!
816
-
817
- if (!currNormal.valid) continue
818
- if (!prevNormal && !currNormal.valid) continue
819
-
820
- // 计算 curr 点的 miter 法线
821
- let miterNX = 0
822
- let miterNY = 0
823
- if (prevNormal?.valid && currNormal.valid) {
824
- miterNX = prevNormal.nx + currNormal.nx
825
- miterNY = prevNormal.ny + currNormal.ny
826
- const miterLenSq = miterNX * miterNX + miterNY * miterNY
827
- if (miterLenSq > 1e-12) {
828
- const invMiter = 1 / Math.sqrt(miterLenSq)
829
- miterNX *= invMiter
830
- miterNY *= invMiter
831
- const dot = miterNX * currNormal.nx + miterNY * currNormal.ny
832
- const scale = 1 / Math.max(MITER_DOT_MIN, Math.abs(dot))
833
- miterNX *= scale
834
- miterNY *= scale
835
- } else {
836
- miterNX = currNormal.nx
837
- miterNY = currNormal.ny
838
- }
839
- } else if (currNormal.valid) {
840
- miterNX = currNormal.nx
841
- miterNY = currNormal.ny
842
- } else if (prevNormal?.valid) {
843
- miterNX = prevNormal.nx
844
- miterNY = prevNormal.ny
845
- } else {
846
- continue
847
- }
848
-
849
- // 计算 next 点的法线(用于下一对点)
850
- let nextMiterNX = currNormal.nx
851
- let nextMiterNY = currNormal.ny
852
- const nextNormal = i < points.length - 2 ? normals[i + 1] : null
853
- if (nextNormal?.valid && currNormal.valid) {
854
- nextMiterNX = currNormal.nx + nextNormal.nx
855
- nextMiterNY = currNormal.ny + nextNormal.ny
856
- const miterLenSq = nextMiterNX * nextMiterNX + nextMiterNY * nextMiterNY
857
- if (miterLenSq > 1e-12) {
858
- const invMiter = 1 / Math.sqrt(miterLenSq)
859
- nextMiterNX *= invMiter
860
- nextMiterNY *= invMiter
861
- const dot = nextMiterNX * nextNormal.nx + nextMiterNY * nextNormal.ny
862
- const scale = 1 / Math.max(MITER_DOT_MIN, Math.abs(dot))
863
- nextMiterNX *= scale
864
- nextMiterNY *= scale
865
- } else {
866
- nextMiterNX = currNormal.nx
867
- nextMiterNY = currNormal.ny
868
- }
869
- }
870
-
871
- // 计算四个角点
872
- const leftAX = curr.x + miterNX * halfWidth
873
- const leftAY = curr.y + miterNY * halfWidth
874
- const rightAX = curr.x - miterNX * halfWidth
875
- const rightAY = curr.y - miterNY * halfWidth
876
- const leftBX = next.x + nextMiterNX * halfWidth
877
- const leftBY = next.y + nextMiterNY * halfWidth
878
- const rightBX = next.x - nextMiterNX * halfWidth
879
- const rightBY = next.y - nextMiterNY * halfWidth
880
-
881
- // 写入两个三角形(6个顶点)
882
- vertices[vertexWriteIndex++] = leftAX
883
- vertices[vertexWriteIndex++] = leftAY
884
- vertices[vertexWriteIndex++] = rightAX
885
- vertices[vertexWriteIndex++] = rightAY
886
- vertices[vertexWriteIndex++] = leftBX
887
- vertices[vertexWriteIndex++] = leftBY
888
- vertices[vertexWriteIndex++] = leftBX
889
- vertices[vertexWriteIndex++] = leftBY
890
- vertices[vertexWriteIndex++] = rightAX
891
- vertices[vertexWriteIndex++] = rightAY
892
- vertices[vertexWriteIndex++] = rightBX
893
- vertices[vertexWriteIndex++] = rightBY
894
- }
895
-
896
- if (vertexWriteIndex === 0) return null
858
+ if (points.length < 2) return null
859
+
860
+ // 使用固定结构数组,避免动态对象分配
861
+ const normals: PolylineNormal[] = new Array(points.length - 1)
862
+ let validSegmentCount = 0
863
+
864
+ // 第一遍:计算所有法线(用 sqrt 替代 hypot,缓存逆长度)
865
+ for (let i = 0; i < points.length - 1; i++) {
866
+ const start = points[i]!
867
+ const end = points[i + 1]!
868
+ const dx = end.x - start.x
869
+ const dy = end.y - start.y
870
+ const lenSq = dx * dx + dy * dy
871
+ if (lenSq <= 0) {
872
+ normals[i] = { nx: 0, ny: 0, valid: false }
873
+ continue
874
+ }
875
+ const invLen = 1 / Math.sqrt(lenSq)
876
+ normals[i] = { nx: -dy * invLen, ny: dx * invLen, valid: true }
877
+ validSegmentCount++
878
+ }
879
+
880
+ if (validSegmentCount === 0) return null
881
+
882
+ // 预分配顶点数组:每对有效相邻点生成12个float(6个顶点 * 2个坐标)
883
+ const maxVerticesFloats = (points.length - 1) * 12
884
+ const vertices = new Float32Array(maxVerticesFloats)
885
+ let vertexWriteIndex = 0
886
+
887
+ // 计算 miter 并直接写入顶点
888
+ for (let i = 0; i < points.length - 1; i++) {
889
+ const curr = points[i]!
890
+ const next = points[i + 1]!
891
+
892
+ const prevNormal = i > 0 ? normals[i - 1] : null
893
+ const currNormal = normals[i]!
894
+
895
+ if (!currNormal.valid) continue
896
+ if (!prevNormal && !currNormal.valid) continue
897
+
898
+ // 计算 curr 点的 miter 法线
899
+ let miterNX = 0
900
+ let miterNY = 0
901
+ if (prevNormal?.valid && currNormal.valid) {
902
+ miterNX = prevNormal.nx + currNormal.nx
903
+ miterNY = prevNormal.ny + currNormal.ny
904
+ const miterLenSq = miterNX * miterNX + miterNY * miterNY
905
+ if (miterLenSq > 1e-12) {
906
+ const invMiter = 1 / Math.sqrt(miterLenSq)
907
+ miterNX *= invMiter
908
+ miterNY *= invMiter
909
+ const dot = miterNX * currNormal.nx + miterNY * currNormal.ny
910
+ const scale = 1 / Math.max(MITER_DOT_MIN, Math.abs(dot))
911
+ miterNX *= scale
912
+ miterNY *= scale
913
+ } else {
914
+ miterNX = currNormal.nx
915
+ miterNY = currNormal.ny
916
+ }
917
+ } else if (currNormal.valid) {
918
+ miterNX = currNormal.nx
919
+ miterNY = currNormal.ny
920
+ } else if (prevNormal?.valid) {
921
+ miterNX = prevNormal.nx
922
+ miterNY = prevNormal.ny
923
+ } else {
924
+ continue
925
+ }
897
926
 
898
- return {
899
- vertices: vertexWriteIndex === maxVerticesFloats ? vertices : vertices.subarray(0, vertexWriteIndex),
900
- vertexCount: vertexWriteIndex / 2,
927
+ // 计算 next 点的法线(用于下一对点)
928
+ let nextMiterNX = currNormal.nx
929
+ let nextMiterNY = currNormal.ny
930
+ const nextNormal = i < points.length - 2 ? normals[i + 1] : null
931
+ if (nextNormal?.valid && currNormal.valid) {
932
+ nextMiterNX = currNormal.nx + nextNormal.nx
933
+ nextMiterNY = currNormal.ny + nextNormal.ny
934
+ const miterLenSq = nextMiterNX * nextMiterNX + nextMiterNY * nextMiterNY
935
+ if (miterLenSq > 1e-12) {
936
+ const invMiter = 1 / Math.sqrt(miterLenSq)
937
+ nextMiterNX *= invMiter
938
+ nextMiterNY *= invMiter
939
+ const dot = nextMiterNX * nextNormal.nx + nextMiterNY * nextNormal.ny
940
+ const scale = 1 / Math.max(MITER_DOT_MIN, Math.abs(dot))
941
+ nextMiterNX *= scale
942
+ nextMiterNY *= scale
943
+ } else {
944
+ nextMiterNX = currNormal.nx
945
+ nextMiterNY = currNormal.ny
946
+ }
901
947
  }
948
+
949
+ // 计算四个角点
950
+ const leftAX = curr.x + miterNX * halfWidth
951
+ const leftAY = curr.y + miterNY * halfWidth
952
+ const rightAX = curr.x - miterNX * halfWidth
953
+ const rightAY = curr.y - miterNY * halfWidth
954
+ const leftBX = next.x + nextMiterNX * halfWidth
955
+ const leftBY = next.y + nextMiterNY * halfWidth
956
+ const rightBX = next.x - nextMiterNX * halfWidth
957
+ const rightBY = next.y - nextMiterNY * halfWidth
958
+
959
+ // 写入两个三角形(6个顶点)
960
+ vertices[vertexWriteIndex++] = leftAX
961
+ vertices[vertexWriteIndex++] = leftAY
962
+ vertices[vertexWriteIndex++] = rightAX
963
+ vertices[vertexWriteIndex++] = rightAY
964
+ vertices[vertexWriteIndex++] = leftBX
965
+ vertices[vertexWriteIndex++] = leftBY
966
+ vertices[vertexWriteIndex++] = leftBX
967
+ vertices[vertexWriteIndex++] = leftBY
968
+ vertices[vertexWriteIndex++] = rightAX
969
+ vertices[vertexWriteIndex++] = rightAY
970
+ vertices[vertexWriteIndex++] = rightBX
971
+ vertices[vertexWriteIndex++] = rightBY
972
+ }
973
+
974
+ if (vertexWriteIndex === 0) return null
975
+
976
+ return {
977
+ vertices:
978
+ vertexWriteIndex === maxVerticesFloats ? vertices : vertices.subarray(0, vertexWriteIndex),
979
+ vertexCount: vertexWriteIndex / 2,
980
+ }
902
981
  }
903
982
 
904
- function createShader(gl: WebGL2RenderingContext, type: number, source: string): WebGLShader | null {
905
- const shader = gl.createShader(type)
906
- if (!shader) return null
983
+ function createShader(
984
+ gl: WebGL2RenderingContext,
985
+ type: number,
986
+ source: string,
987
+ ): WebGLShader | null {
988
+ const shader = gl.createShader(type)
989
+ if (!shader) return null
907
990
 
908
- gl.shaderSource(shader, source)
909
- gl.compileShader(shader)
991
+ gl.shaderSource(shader, source)
992
+ gl.compileShader(shader)
910
993
 
911
- if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
912
- return shader
913
- }
994
+ if (gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
995
+ return shader
996
+ }
914
997
 
915
- gl.deleteShader(shader)
916
- return null
998
+ gl.deleteShader(shader)
999
+ return null
917
1000
  }
918
1001
 
919
- function createProgram(gl: WebGL2RenderingContext, vertexShader: WebGLShader, fragmentShader: WebGLShader): WebGLProgram | null {
920
- const program = gl.createProgram()
921
- if (!program) return null
1002
+ function createProgram(
1003
+ gl: WebGL2RenderingContext,
1004
+ vertexShader: WebGLShader,
1005
+ fragmentShader: WebGLShader,
1006
+ ): WebGLProgram | null {
1007
+ const program = gl.createProgram()
1008
+ if (!program) return null
922
1009
 
923
- gl.attachShader(program, vertexShader)
924
- gl.attachShader(program, fragmentShader)
925
- gl.linkProgram(program)
1010
+ gl.attachShader(program, vertexShader)
1011
+ gl.attachShader(program, fragmentShader)
1012
+ gl.linkProgram(program)
926
1013
 
927
- if (gl.getProgramParameter(program, gl.LINK_STATUS)) {
928
- return program
929
- }
1014
+ if (gl.getProgramParameter(program, gl.LINK_STATUS)) {
1015
+ return program
1016
+ }
930
1017
 
931
- gl.deleteProgram(program)
932
- return null
1018
+ gl.deleteProgram(program)
1019
+ return null
933
1020
  }
934
1021
 
935
1022
  const colorCache = new Map<string, FloatColor>()
936
1023
 
937
1024
  function parseColor(color: string): FloatColor | null {
938
- const cached = colorCache.get(color)
939
- if (cached) return cached
940
-
941
- const normalized = color.trim().toLowerCase()
942
- let result: FloatColor | null = null
943
-
944
- if (normalized.startsWith('rgba(')) {
945
- const values = normalized.slice(5, -1).split(',').map((part) => Number(part.trim()))
946
- if (values.length === 4 && values.every((value) => Number.isFinite(value))) {
947
- result = [values[0]! / 255, values[1]! / 255, values[2]! / 255, values[3]!]
948
- }
949
- } else if (normalized.startsWith('rgb(')) {
950
- const values = normalized.slice(4, -1).split(',').map((part) => Number(part.trim()))
951
- if (values.length === 3 && values.every((value) => Number.isFinite(value))) {
952
- result = [values[0]! / 255, values[1]! / 255, values[2]! / 255, 1]
953
- }
954
- } else if (normalized.startsWith('#')) {
955
- const hex = normalized.slice(1)
956
- if (hex.length === 6) {
957
- result = [
958
- Number.parseInt(hex.slice(0, 2), 16) / 255,
959
- Number.parseInt(hex.slice(2, 4), 16) / 255,
960
- Number.parseInt(hex.slice(4, 6), 16) / 255,
961
- 1,
962
- ]
963
- } else if (hex.length === 3) {
964
- result = [
965
- Number.parseInt(hex[0]! + hex[0]!, 16) / 255,
966
- Number.parseInt(hex[1]! + hex[1]!, 16) / 255,
967
- Number.parseInt(hex[2]! + hex[2]!, 16) / 255,
968
- 1,
969
- ]
970
- }
971
- }
972
-
973
- if (result) colorCache.set(color, result)
974
- return result
1025
+ const cached = colorCache.get(color)
1026
+ if (cached) return cached
1027
+
1028
+ const normalized = color.trim().toLowerCase()
1029
+ let result: FloatColor | null = null
1030
+
1031
+ if (normalized.startsWith('rgba(')) {
1032
+ const values = normalized
1033
+ .slice(5, -1)
1034
+ .split(',')
1035
+ .map((part) => Number(part.trim()))
1036
+ if (values.length === 4 && values.every((value) => Number.isFinite(value))) {
1037
+ result = [values[0]! / 255, values[1]! / 255, values[2]! / 255, values[3]!]
1038
+ }
1039
+ } else if (normalized.startsWith('rgb(')) {
1040
+ const values = normalized
1041
+ .slice(4, -1)
1042
+ .split(',')
1043
+ .map((part) => Number(part.trim()))
1044
+ if (values.length === 3 && values.every((value) => Number.isFinite(value))) {
1045
+ result = [values[0]! / 255, values[1]! / 255, values[2]! / 255, 1]
1046
+ }
1047
+ } else if (normalized.startsWith('#')) {
1048
+ const hex = normalized.slice(1)
1049
+ if (hex.length === 6) {
1050
+ result = [
1051
+ Number.parseInt(hex.slice(0, 2), 16) / 255,
1052
+ Number.parseInt(hex.slice(2, 4), 16) / 255,
1053
+ Number.parseInt(hex.slice(4, 6), 16) / 255,
1054
+ 1,
1055
+ ]
1056
+ } else if (hex.length === 3) {
1057
+ result = [
1058
+ Number.parseInt(hex[0]! + hex[0]!, 16) / 255,
1059
+ Number.parseInt(hex[1]! + hex[1]!, 16) / 255,
1060
+ Number.parseInt(hex[2]! + hex[2]!, 16) / 255,
1061
+ 1,
1062
+ ]
1063
+ }
1064
+ }
1065
+
1066
+ if (result) colorCache.set(color, result)
1067
+ return result
975
1068
  }