ice-render 1.0.4 → 1.0.5
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.
- package/LICENSE +0 -0
- package/README.md +229 -141
- package/dist/THIRD-PARTY-NOTICES.txt +32 -0
- package/dist/index.cjs +30 -0
- package/dist/index.mjs +30 -0
- package/dist/index.umd.js +6 -1
- package/dist/types/FrameManager.d.mts +26 -0
- package/dist/types/FrameManager.d.ts +26 -26
- package/dist/types/ICE.d.mts +369 -0
- package/dist/types/ICE.d.ts +369 -107
- package/dist/types/a11y/accessibility.d.mts +46 -0
- package/dist/types/a11y/accessibility.d.ts +46 -0
- package/dist/types/animation/AnimationManager.d.mts +96 -0
- package/dist/types/animation/AnimationManager.d.ts +96 -25
- package/dist/types/animation/Easing.d.mts +33 -0
- package/dist/types/animation/Easing.d.ts +33 -32
- package/dist/types/consts/BIG_ZINDEX_NUMBER.d.mts +14 -0
- package/dist/types/consts/BIG_ZINDEX_NUMBER.d.ts +14 -14
- package/dist/types/consts/COMPONENT_TYPE_MAPPING.d.mts +45 -0
- package/dist/types/consts/COMPONENT_TYPE_MAPPING.d.ts +45 -36
- package/dist/types/consts/DOM_EVENT_MAPPING_CONSTS.d.mts +37 -0
- package/dist/types/consts/DOM_EVENT_MAPPING_CONSTS.d.ts +37 -19
- package/dist/types/consts/ICE_EVENT_NAME_CONSTS.d.mts +27 -0
- package/dist/types/consts/ICE_EVENT_NAME_CONSTS.d.ts +27 -20
- package/dist/types/control-panel/AlignmentGuideManager.d.mts +92 -0
- package/dist/types/control-panel/AlignmentGuideManager.d.ts +92 -0
- package/dist/types/control-panel/ICEControlPanel.d.mts +37 -0
- package/dist/types/control-panel/ICEControlPanel.d.ts +37 -37
- package/dist/types/control-panel/ICEControlPanelManager.d.mts +25 -0
- package/dist/types/control-panel/ICEControlPanelManager.d.ts +25 -23
- package/dist/types/control-panel/link-controls/LineControlPanel.d.mts +39 -0
- package/dist/types/control-panel/link-controls/LineControlPanel.d.ts +39 -39
- package/dist/types/control-panel/transform-controls/ResizeControl.d.mts +38 -0
- package/dist/types/control-panel/transform-controls/ResizeControl.d.ts +38 -38
- package/dist/types/control-panel/transform-controls/RotateControl.d.mts +12 -0
- package/dist/types/control-panel/transform-controls/RotateControl.d.ts +12 -12
- package/dist/types/control-panel/transform-controls/TransformControlPanel.d.mts +83 -0
- package/dist/types/control-panel/transform-controls/TransformControlPanel.d.ts +83 -74
- package/dist/types/control-panel/transform-controls/constraints.d.mts +24 -0
- package/dist/types/control-panel/transform-controls/constraints.d.ts +24 -0
- package/dist/types/cross-platform/PolyfillPath2D.d.mts +31 -0
- package/dist/types/cross-platform/PolyfillPath2D.d.ts +31 -0
- package/dist/types/cross-platform/root.d.mts +7 -0
- package/dist/types/cross-platform/root.d.ts +7 -2
- package/dist/types/event/DOMEventDispatcher.d.mts +68 -0
- package/dist/types/event/DOMEventDispatcher.d.ts +68 -29
- package/dist/types/event/DOMEventInterceptor.d.mts +36 -0
- package/dist/types/event/DOMEventInterceptor.d.ts +36 -7
- package/dist/types/event/EventBus.d.mts +27 -0
- package/dist/types/event/EventBus.d.ts +27 -27
- package/dist/types/event/ICEEvent.d.mts +46 -0
- package/dist/types/event/ICEEvent.d.ts +46 -46
- package/dist/types/event/ICEEventTarget.d.mts +106 -0
- package/dist/types/event/ICEEventTarget.d.ts +106 -106
- package/dist/types/event/input-normalize.d.mts +75 -0
- package/dist/types/event/input-normalize.d.ts +75 -0
- package/dist/types/geometry/GeoLine.d.mts +24 -0
- package/dist/types/geometry/GeoLine.d.ts +24 -23
- package/dist/types/geometry/GeoPoint.d.mts +53 -0
- package/dist/types/geometry/GeoPoint.d.ts +53 -66
- package/dist/types/geometry/GeoUtil.d.mts +73 -0
- package/dist/types/geometry/GeoUtil.d.ts +73 -37
- package/dist/types/geometry/ICEBoundingBox.d.mts +81 -0
- package/dist/types/geometry/ICEBoundingBox.d.ts +81 -81
- package/dist/types/graphic/ICEComponent.d.mts +436 -0
- package/dist/types/graphic/ICEComponent.d.ts +436 -264
- package/dist/types/graphic/ICEDotPath.d.mts +99 -0
- package/dist/types/graphic/ICEDotPath.d.ts +99 -63
- package/dist/types/graphic/ICEImage.d.mts +17 -0
- package/dist/types/graphic/ICEImage.d.ts +17 -17
- package/dist/types/graphic/ICEPath.d.mts +39 -0
- package/dist/types/graphic/ICEPath.d.ts +39 -36
- package/dist/types/graphic/container/ICEGroup.d.mts +101 -0
- package/dist/types/graphic/container/ICEGroup.d.ts +101 -53
- package/dist/types/graphic/link/ICEBezier.d.mts +23 -0
- package/dist/types/graphic/link/ICEBezier.d.ts +23 -15
- package/dist/types/graphic/link/ICELinkHook.d.mts +52 -0
- package/dist/types/graphic/link/ICELinkHook.d.ts +52 -52
- package/dist/types/graphic/link/ICELinkSlot.d.mts +54 -0
- package/dist/types/graphic/link/ICELinkSlot.d.ts +54 -46
- package/dist/types/graphic/link/ICELinkSlotManager.d.mts +28 -0
- package/dist/types/graphic/link/ICELinkSlotManager.d.ts +28 -28
- package/dist/types/graphic/link/ICEPolyLine.d.mts +292 -0
- package/dist/types/graphic/link/ICEPolyLine.d.ts +292 -219
- package/dist/types/graphic/link/ICEVisioLink.d.mts +163 -0
- package/dist/types/graphic/link/ICEVisioLink.d.ts +163 -129
- package/dist/types/graphic/shape/ICECircle.d.mts +19 -0
- package/dist/types/graphic/shape/ICECircle.d.ts +19 -19
- package/dist/types/graphic/shape/ICEEllipse.d.mts +29 -0
- package/dist/types/graphic/shape/ICEEllipse.d.ts +29 -23
- package/dist/types/graphic/shape/ICEIsogon.d.mts +52 -0
- package/dist/types/graphic/shape/ICEIsogon.d.ts +52 -52
- package/dist/types/graphic/shape/ICERect.d.mts +10 -0
- package/dist/types/graphic/shape/ICERect.d.ts +10 -17
- package/dist/types/graphic/shape/ICERose.d.mts +41 -0
- package/dist/types/graphic/shape/ICERose.d.ts +41 -41
- package/dist/types/graphic/shape/ICEStar.d.mts +45 -0
- package/dist/types/graphic/shape/ICEStar.d.ts +45 -45
- package/dist/types/graphic/text/ICEText.d.mts +137 -0
- package/dist/types/graphic/text/ICEText.d.ts +137 -65
- package/dist/types/index.d.mts +55 -0
- package/dist/types/index.d.ts +55 -41
- package/dist/types/layout/ICEBorderLayout.d.mts +34 -0
- package/dist/types/layout/ICEBorderLayout.d.ts +34 -0
- package/dist/types/layout/ICEBoxLayout.d.mts +30 -0
- package/dist/types/layout/ICEBoxLayout.d.ts +30 -0
- package/dist/types/layout/ICECardLayout.d.mts +36 -0
- package/dist/types/layout/ICECardLayout.d.ts +36 -0
- package/dist/types/layout/ICEFlowLayout.d.mts +31 -0
- package/dist/types/layout/ICEFlowLayout.d.ts +31 -0
- package/dist/types/layout/ICEGridLayout.d.mts +33 -0
- package/dist/types/layout/ICEGridLayout.d.ts +33 -0
- package/dist/types/layout/ICELayeredLayout.d.mts +49 -0
- package/dist/types/layout/ICELayeredLayout.d.ts +49 -0
- package/dist/types/layout/ICELayoutManager.d.mts +33 -0
- package/dist/types/layout/ICELayoutManager.d.ts +33 -0
- package/dist/types/layout/ICEOverlayLayout.d.mts +25 -0
- package/dist/types/layout/ICEOverlayLayout.d.ts +25 -0
- package/dist/types/persistence/Deserializer.d.mts +43 -0
- package/dist/types/persistence/Deserializer.d.ts +43 -14
- package/dist/types/persistence/Serializer.d.mts +35 -0
- package/dist/types/persistence/Serializer.d.ts +35 -26
- package/dist/types/plugin/PluginHost.d.mts +86 -0
- package/dist/types/plugin/PluginHost.d.ts +86 -0
- package/dist/types/renderer/CanvasRenderer.d.mts +150 -0
- package/dist/types/renderer/CanvasRenderer.d.ts +150 -22
- package/dist/types/renderer/ObjectCache.d.mts +79 -0
- package/dist/types/renderer/ObjectCache.d.ts +79 -0
- package/dist/types/renderer/dirty-rect-util.d.mts +86 -0
- package/dist/types/renderer/dirty-rect-util.d.ts +86 -0
- package/dist/types/theme/ICETheme.d.mts +382 -0
- package/dist/types/theme/ICETheme.d.ts +382 -0
- package/dist/types/util/ImageCache.d.mts +19 -0
- package/dist/types/util/ImageCache.d.ts +19 -19
- package/dist/types/util/data-util.d.mts +43 -0
- package/dist/types/util/data-util.d.ts +43 -19
- package/dist/types/util/gl-matrix-skew.d.mts +14 -0
- package/dist/types/util/gl-matrix-skew.d.ts +14 -14
- package/dist/types/util/lang.d.mts +28 -0
- package/dist/types/util/lang.d.ts +28 -0
- package/dist/types/util/uuid.d.mts +1 -0
- package/dist/types/util/uuid.d.ts +1 -1
- package/package.json +119 -81
- package/dist/index.cjs.js +0 -25
- package/dist/index.js +0 -25
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import ICEEventTarget from '../event/ICEEventTarget.mjs';
|
|
2
|
+
import ICE from '../ICE.mjs';
|
|
3
|
+
/**
|
|
4
|
+
* @class CanvasRenderer Canvas 渲染器
|
|
5
|
+
*
|
|
6
|
+
* - 一个 ICE 实例上,只能有一个渲染器实例。
|
|
7
|
+
* - 默认渲染策略为「脏矩形局部重绘」(renderMode: 'dirty-rect'):
|
|
8
|
+
* 只 clear 脏区域、按 z 序重画与区域相交的组件;不满足局部条件时自动回退全量重绘
|
|
9
|
+
* (结构变更 / 未 prime / 脏占比过高 / 区域过大 / 折线或文本等特殊类别 / 能力缺失)。
|
|
10
|
+
* 两种模式像素一致(组件 render 已做 ctx 泄漏属性归位,见 ICEComponent.__resetLeakyCtxState)。
|
|
11
|
+
*
|
|
12
|
+
* @author 大漠穷秋<damoqiongqiu@126.com>
|
|
13
|
+
*/
|
|
14
|
+
declare class CanvasRenderer extends ICEEventTarget {
|
|
15
|
+
private ice;
|
|
16
|
+
private stopped;
|
|
17
|
+
private renderMode;
|
|
18
|
+
/** @internal 内部测试钩子:强制走全量路径(对比/调试用,非公开 API)。 */
|
|
19
|
+
__forceFullRender: boolean;
|
|
20
|
+
private componentQueue;
|
|
21
|
+
private toolsQueue;
|
|
22
|
+
private __queueDirty;
|
|
23
|
+
private __zSnap;
|
|
24
|
+
/**
|
|
25
|
+
* 每个「曾上屏」组件的世界轴对齐包围盒快照([minX,minY,maxX,maxY],已含 paint pad)。
|
|
26
|
+
* WeakMap:不污染组件 state/props(序列化安全)、对 zIndex 重排免疫、组件 GC 自动回收。
|
|
27
|
+
* 用于:部分重绘帧的旧区域擦除 + 未变组件的「是否与本帧区域相交」判断。
|
|
28
|
+
*/
|
|
29
|
+
private __snap;
|
|
30
|
+
/** 距离最近一次队列重建后,是否已完成过至少一次「全量/prime」渲染(快照就绪)。 */
|
|
31
|
+
private __primed;
|
|
32
|
+
/** 组件级离屏缓存(v1 缓存 ICEText),与快照一样不污染组件 state/props。 */
|
|
33
|
+
private cache;
|
|
34
|
+
/** @internal 上一帧被视口裁剪掉的组件数(仅供性能观测与测试断言)。 */
|
|
35
|
+
__lastFrameCulled: number;
|
|
36
|
+
constructor(ice: ICE, options?: {
|
|
37
|
+
renderMode?: 'full' | 'dirty-rect';
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* @method markQueueDirty 标记组件树结构已变化,下一次渲染需重建渲染队列。
|
|
41
|
+
* 由 ICE / ICEGroup 在 addChild / removeChild 等结构性变更时调用。
|
|
42
|
+
* 结构变更必然回退全量重绘(并重新 prime 快照)。
|
|
43
|
+
*/
|
|
44
|
+
markQueueDirty(): void;
|
|
45
|
+
setRenderMode(mode: 'full' | 'dirty-rect'): void;
|
|
46
|
+
getRenderMode(): 'full' | 'dirty-rect';
|
|
47
|
+
start(): this;
|
|
48
|
+
stop(): this;
|
|
49
|
+
private frameEvtHandler;
|
|
50
|
+
private refreshQueue;
|
|
51
|
+
private __rebuildQueue;
|
|
52
|
+
/**
|
|
53
|
+
* 把当前 componentQueue + toolsQueue 的 zIndex 顺序快照到复用的 __zSnap 数组,
|
|
54
|
+
* 供下一帧做稳定性比对,避免每帧分配新数组。
|
|
55
|
+
*/
|
|
56
|
+
private __snapshotZ;
|
|
57
|
+
/**
|
|
58
|
+
* 对比当前队列的 zIndex 与上次快照,任一不同(或长度变化)即认为顺序已变。
|
|
59
|
+
*/
|
|
60
|
+
private __zOrderChanged;
|
|
61
|
+
private doRenderFull;
|
|
62
|
+
/**
|
|
63
|
+
* 收集脏区域并做局部重绘可行性判定。
|
|
64
|
+
* 返回 null = 不满足局部条件(由调用方回退全量);否则返回本帧脏区域 [minX,minY,maxX,maxY]。
|
|
65
|
+
*
|
|
66
|
+
* 区域来源:
|
|
67
|
+
* - 可见且 dirty 的组件/工具:旧快照盒 ∪ 新几何盒(可能移动/变形)。
|
|
68
|
+
* - display:false 且 dirty 且曾上屏的组件/工具:旧快照盒(仅擦除)。
|
|
69
|
+
*
|
|
70
|
+
* 判定顺序(性能关键):先做**零开销预检**(只读 display/dirty 标志),
|
|
71
|
+
* 能确定要回退全量的情况(无可见脏组件 / 脏占比超阈)绝不进入
|
|
72
|
+
* 「场景门控 + 逐组件算包围盒」的昂贵路径——否则动画全量帧会被重复 compose 翻倍。
|
|
73
|
+
*/
|
|
74
|
+
private __collect;
|
|
75
|
+
/** 渲染视口(dpr·viewport)。ICE 侧有缓存,dpr===1 时直接返回 viewport 本身。 */
|
|
76
|
+
private __renderViewport;
|
|
77
|
+
/**
|
|
78
|
+
* 预检:只读组件标志(display/dirty/快照存在),不触发矩阵/样式计算。
|
|
79
|
+
* @returns { visible: 可见数量, dirty: 可见且脏数量, hiddenErase: 是否有曾上屏的隐藏脏组件 }
|
|
80
|
+
*/
|
|
81
|
+
private __preCount;
|
|
82
|
+
/**
|
|
83
|
+
* 区域收集 pass:仅当预检通过、即将走局部时才调用。
|
|
84
|
+
* 把「可见且脏」组件的旧快照盒 ∪ 新几何盒、以及「隐藏且曾上屏」组件的旧快照盒
|
|
85
|
+
* 逐条推进 `boxes`(聚合交给 `coalesceRegions`,这里不做并集)。
|
|
86
|
+
* 返回 false = 有组件盒非法(回退全量)。
|
|
87
|
+
*/
|
|
88
|
+
private __collectDirtyBoxes;
|
|
89
|
+
/**
|
|
90
|
+
* 相交级门控:判断「对本帧脏区域有 AA 风险的组件」是否真的与区域相交。
|
|
91
|
+
*
|
|
92
|
+
* 有风险的类别(与整场景门控时代一致):
|
|
93
|
+
* - 点集路径(星形/正N边形/玫瑰/折线):clip 会切断折线抗锯齿边缘
|
|
94
|
+
* - 文本:clip 会改变字形 AA
|
|
95
|
+
* - 非不透明落墨(rgba/hsla 色、阴影、globalAlpha≠1、非 source-over)
|
|
96
|
+
*
|
|
97
|
+
* 例外:已离屏缓存的组件在主画布上只是 drawImage(不透明位图整像素采样),
|
|
98
|
+
* 不再受 clip 影响,因此不阻塞。
|
|
99
|
+
*
|
|
100
|
+
* **刚变脏的 risky 组件一律回退**:它本轮要重建位图/重算参数,而实际墨迹范围可能超出
|
|
101
|
+
* 几何盒(文本的字形与描边尤甚,实测「文本内容变更」时墨迹会超出盒若干像素),
|
|
102
|
+
* 在 clip 下重绘无法保证与全量逐像素一致。dirty-rect 像素回归正是靠这条兜住的。
|
|
103
|
+
*
|
|
104
|
+
* 干净的 risky 组件才做相交判定,盒取上屏快照(世界轴对齐盒,含 paint pad);
|
|
105
|
+
* 快照缺失(从未上屏)时无法判定 → 保守回退。
|
|
106
|
+
*/
|
|
107
|
+
private __riskyIntersectsRegions;
|
|
108
|
+
private __renderDirtyRect;
|
|
109
|
+
/**
|
|
110
|
+
* 调用插件渲染钩子。要求:
|
|
111
|
+
* - 与世界坐标一致:先把 CTM 设为「渲染视口」(dpr · viewport),插件即可按世界坐标绘制
|
|
112
|
+
* - 在两条渲染路径中都调用;局部重绘时处于 clip 之内,语义与组件一致
|
|
113
|
+
* - 未注册任何钩子时零开销(不构造 frame 对象)
|
|
114
|
+
*/
|
|
115
|
+
private __invokePluginRender;
|
|
116
|
+
private __ensureContext;
|
|
117
|
+
/**
|
|
118
|
+
* @internal 取组件上一次上屏的世界包围盒(含 paint pad,格式 [minX,minY,maxX,maxY])。
|
|
119
|
+
* 供命中检测做「廉价包围盒预筛」,避免对屏外组件做矩阵反变换 + 形状判定。无快照返回 null。
|
|
120
|
+
*/
|
|
121
|
+
getWorldBox(component: any): Float64Array | null;
|
|
122
|
+
/**
|
|
123
|
+
* 当前视口对应的可见世界矩形 [minX,minY,maxX,maxY]。画布尺寸缺失时返回 null(不裁剪)。
|
|
124
|
+
*/
|
|
125
|
+
private __visibleWorldRect;
|
|
126
|
+
/**
|
|
127
|
+
* 组件渲染入口:可缓存组件走离屏位图(命中贴图 / 纯平移复用 / 重建),
|
|
128
|
+
* 否则回退到普通 render()。
|
|
129
|
+
*/
|
|
130
|
+
private __renderComponent;
|
|
131
|
+
private __isDotPath;
|
|
132
|
+
private __isText;
|
|
133
|
+
/**
|
|
134
|
+
* 计算 dirty 组件的「新盒」(含 paint pad,世界坐标)。
|
|
135
|
+
* 需要先刷新组件参数(文本 measure / dot-path calcDots),再 refresh 合成矩阵。
|
|
136
|
+
* 返回 null = 盒非法或计算失败(回退全量)。
|
|
137
|
+
*/
|
|
138
|
+
private __freshBox;
|
|
139
|
+
/**
|
|
140
|
+
* 渲染后捕获组件的世界包围盒(含 pad)到快照,供后续帧做旧区域擦除与相交判断。
|
|
141
|
+
*/
|
|
142
|
+
private __capture;
|
|
143
|
+
/**
|
|
144
|
+
* 隐藏组件(display:false)曾上屏过、且仍挂着脏标记(render 提前返回不会自清):
|
|
145
|
+
* 本帧它的旧区域已被擦除(全量 clear 或局部 erase 区域),因此清除脏位并移除快照,
|
|
146
|
+
* 避免「永久脏组件把后续局部帧反复顶成全量」。display 重新打开时 setState 会重新置脏。
|
|
147
|
+
*/
|
|
148
|
+
private __finalizeHidden;
|
|
149
|
+
}
|
|
150
|
+
export default CanvasRenderer;
|
|
@@ -1,22 +1,150 @@
|
|
|
1
|
-
import ICEEventTarget from '../event/ICEEventTarget';
|
|
2
|
-
import ICE from '../ICE';
|
|
3
|
-
/**
|
|
4
|
-
* @class CanvasRenderer Canvas 渲染器
|
|
5
|
-
*
|
|
6
|
-
* - 一个 ICE 实例上,只能有一个渲染器实例。
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
|
|
1
|
+
import ICEEventTarget from '../event/ICEEventTarget';
|
|
2
|
+
import ICE from '../ICE';
|
|
3
|
+
/**
|
|
4
|
+
* @class CanvasRenderer Canvas 渲染器
|
|
5
|
+
*
|
|
6
|
+
* - 一个 ICE 实例上,只能有一个渲染器实例。
|
|
7
|
+
* - 默认渲染策略为「脏矩形局部重绘」(renderMode: 'dirty-rect'):
|
|
8
|
+
* 只 clear 脏区域、按 z 序重画与区域相交的组件;不满足局部条件时自动回退全量重绘
|
|
9
|
+
* (结构变更 / 未 prime / 脏占比过高 / 区域过大 / 折线或文本等特殊类别 / 能力缺失)。
|
|
10
|
+
* 两种模式像素一致(组件 render 已做 ctx 泄漏属性归位,见 ICEComponent.__resetLeakyCtxState)。
|
|
11
|
+
*
|
|
12
|
+
* @author 大漠穷秋<damoqiongqiu@126.com>
|
|
13
|
+
*/
|
|
14
|
+
declare class CanvasRenderer extends ICEEventTarget {
|
|
15
|
+
private ice;
|
|
16
|
+
private stopped;
|
|
17
|
+
private renderMode;
|
|
18
|
+
/** @internal 内部测试钩子:强制走全量路径(对比/调试用,非公开 API)。 */
|
|
19
|
+
__forceFullRender: boolean;
|
|
20
|
+
private componentQueue;
|
|
21
|
+
private toolsQueue;
|
|
22
|
+
private __queueDirty;
|
|
23
|
+
private __zSnap;
|
|
24
|
+
/**
|
|
25
|
+
* 每个「曾上屏」组件的世界轴对齐包围盒快照([minX,minY,maxX,maxY],已含 paint pad)。
|
|
26
|
+
* WeakMap:不污染组件 state/props(序列化安全)、对 zIndex 重排免疫、组件 GC 自动回收。
|
|
27
|
+
* 用于:部分重绘帧的旧区域擦除 + 未变组件的「是否与本帧区域相交」判断。
|
|
28
|
+
*/
|
|
29
|
+
private __snap;
|
|
30
|
+
/** 距离最近一次队列重建后,是否已完成过至少一次「全量/prime」渲染(快照就绪)。 */
|
|
31
|
+
private __primed;
|
|
32
|
+
/** 组件级离屏缓存(v1 缓存 ICEText),与快照一样不污染组件 state/props。 */
|
|
33
|
+
private cache;
|
|
34
|
+
/** @internal 上一帧被视口裁剪掉的组件数(仅供性能观测与测试断言)。 */
|
|
35
|
+
__lastFrameCulled: number;
|
|
36
|
+
constructor(ice: ICE, options?: {
|
|
37
|
+
renderMode?: 'full' | 'dirty-rect';
|
|
38
|
+
});
|
|
39
|
+
/**
|
|
40
|
+
* @method markQueueDirty 标记组件树结构已变化,下一次渲染需重建渲染队列。
|
|
41
|
+
* 由 ICE / ICEGroup 在 addChild / removeChild 等结构性变更时调用。
|
|
42
|
+
* 结构变更必然回退全量重绘(并重新 prime 快照)。
|
|
43
|
+
*/
|
|
44
|
+
markQueueDirty(): void;
|
|
45
|
+
setRenderMode(mode: 'full' | 'dirty-rect'): void;
|
|
46
|
+
getRenderMode(): 'full' | 'dirty-rect';
|
|
47
|
+
start(): this;
|
|
48
|
+
stop(): this;
|
|
49
|
+
private frameEvtHandler;
|
|
50
|
+
private refreshQueue;
|
|
51
|
+
private __rebuildQueue;
|
|
52
|
+
/**
|
|
53
|
+
* 把当前 componentQueue + toolsQueue 的 zIndex 顺序快照到复用的 __zSnap 数组,
|
|
54
|
+
* 供下一帧做稳定性比对,避免每帧分配新数组。
|
|
55
|
+
*/
|
|
56
|
+
private __snapshotZ;
|
|
57
|
+
/**
|
|
58
|
+
* 对比当前队列的 zIndex 与上次快照,任一不同(或长度变化)即认为顺序已变。
|
|
59
|
+
*/
|
|
60
|
+
private __zOrderChanged;
|
|
61
|
+
private doRenderFull;
|
|
62
|
+
/**
|
|
63
|
+
* 收集脏区域并做局部重绘可行性判定。
|
|
64
|
+
* 返回 null = 不满足局部条件(由调用方回退全量);否则返回本帧脏区域 [minX,minY,maxX,maxY]。
|
|
65
|
+
*
|
|
66
|
+
* 区域来源:
|
|
67
|
+
* - 可见且 dirty 的组件/工具:旧快照盒 ∪ 新几何盒(可能移动/变形)。
|
|
68
|
+
* - display:false 且 dirty 且曾上屏的组件/工具:旧快照盒(仅擦除)。
|
|
69
|
+
*
|
|
70
|
+
* 判定顺序(性能关键):先做**零开销预检**(只读 display/dirty 标志),
|
|
71
|
+
* 能确定要回退全量的情况(无可见脏组件 / 脏占比超阈)绝不进入
|
|
72
|
+
* 「场景门控 + 逐组件算包围盒」的昂贵路径——否则动画全量帧会被重复 compose 翻倍。
|
|
73
|
+
*/
|
|
74
|
+
private __collect;
|
|
75
|
+
/** 渲染视口(dpr·viewport)。ICE 侧有缓存,dpr===1 时直接返回 viewport 本身。 */
|
|
76
|
+
private __renderViewport;
|
|
77
|
+
/**
|
|
78
|
+
* 预检:只读组件标志(display/dirty/快照存在),不触发矩阵/样式计算。
|
|
79
|
+
* @returns { visible: 可见数量, dirty: 可见且脏数量, hiddenErase: 是否有曾上屏的隐藏脏组件 }
|
|
80
|
+
*/
|
|
81
|
+
private __preCount;
|
|
82
|
+
/**
|
|
83
|
+
* 区域收集 pass:仅当预检通过、即将走局部时才调用。
|
|
84
|
+
* 把「可见且脏」组件的旧快照盒 ∪ 新几何盒、以及「隐藏且曾上屏」组件的旧快照盒
|
|
85
|
+
* 逐条推进 `boxes`(聚合交给 `coalesceRegions`,这里不做并集)。
|
|
86
|
+
* 返回 false = 有组件盒非法(回退全量)。
|
|
87
|
+
*/
|
|
88
|
+
private __collectDirtyBoxes;
|
|
89
|
+
/**
|
|
90
|
+
* 相交级门控:判断「对本帧脏区域有 AA 风险的组件」是否真的与区域相交。
|
|
91
|
+
*
|
|
92
|
+
* 有风险的类别(与整场景门控时代一致):
|
|
93
|
+
* - 点集路径(星形/正N边形/玫瑰/折线):clip 会切断折线抗锯齿边缘
|
|
94
|
+
* - 文本:clip 会改变字形 AA
|
|
95
|
+
* - 非不透明落墨(rgba/hsla 色、阴影、globalAlpha≠1、非 source-over)
|
|
96
|
+
*
|
|
97
|
+
* 例外:已离屏缓存的组件在主画布上只是 drawImage(不透明位图整像素采样),
|
|
98
|
+
* 不再受 clip 影响,因此不阻塞。
|
|
99
|
+
*
|
|
100
|
+
* **刚变脏的 risky 组件一律回退**:它本轮要重建位图/重算参数,而实际墨迹范围可能超出
|
|
101
|
+
* 几何盒(文本的字形与描边尤甚,实测「文本内容变更」时墨迹会超出盒若干像素),
|
|
102
|
+
* 在 clip 下重绘无法保证与全量逐像素一致。dirty-rect 像素回归正是靠这条兜住的。
|
|
103
|
+
*
|
|
104
|
+
* 干净的 risky 组件才做相交判定,盒取上屏快照(世界轴对齐盒,含 paint pad);
|
|
105
|
+
* 快照缺失(从未上屏)时无法判定 → 保守回退。
|
|
106
|
+
*/
|
|
107
|
+
private __riskyIntersectsRegions;
|
|
108
|
+
private __renderDirtyRect;
|
|
109
|
+
/**
|
|
110
|
+
* 调用插件渲染钩子。要求:
|
|
111
|
+
* - 与世界坐标一致:先把 CTM 设为「渲染视口」(dpr · viewport),插件即可按世界坐标绘制
|
|
112
|
+
* - 在两条渲染路径中都调用;局部重绘时处于 clip 之内,语义与组件一致
|
|
113
|
+
* - 未注册任何钩子时零开销(不构造 frame 对象)
|
|
114
|
+
*/
|
|
115
|
+
private __invokePluginRender;
|
|
116
|
+
private __ensureContext;
|
|
117
|
+
/**
|
|
118
|
+
* @internal 取组件上一次上屏的世界包围盒(含 paint pad,格式 [minX,minY,maxX,maxY])。
|
|
119
|
+
* 供命中检测做「廉价包围盒预筛」,避免对屏外组件做矩阵反变换 + 形状判定。无快照返回 null。
|
|
120
|
+
*/
|
|
121
|
+
getWorldBox(component: any): Float64Array | null;
|
|
122
|
+
/**
|
|
123
|
+
* 当前视口对应的可见世界矩形 [minX,minY,maxX,maxY]。画布尺寸缺失时返回 null(不裁剪)。
|
|
124
|
+
*/
|
|
125
|
+
private __visibleWorldRect;
|
|
126
|
+
/**
|
|
127
|
+
* 组件渲染入口:可缓存组件走离屏位图(命中贴图 / 纯平移复用 / 重建),
|
|
128
|
+
* 否则回退到普通 render()。
|
|
129
|
+
*/
|
|
130
|
+
private __renderComponent;
|
|
131
|
+
private __isDotPath;
|
|
132
|
+
private __isText;
|
|
133
|
+
/**
|
|
134
|
+
* 计算 dirty 组件的「新盒」(含 paint pad,世界坐标)。
|
|
135
|
+
* 需要先刷新组件参数(文本 measure / dot-path calcDots),再 refresh 合成矩阵。
|
|
136
|
+
* 返回 null = 盒非法或计算失败(回退全量)。
|
|
137
|
+
*/
|
|
138
|
+
private __freshBox;
|
|
139
|
+
/**
|
|
140
|
+
* 渲染后捕获组件的世界包围盒(含 pad)到快照,供后续帧做旧区域擦除与相交判断。
|
|
141
|
+
*/
|
|
142
|
+
private __capture;
|
|
143
|
+
/**
|
|
144
|
+
* 隐藏组件(display:false)曾上屏过、且仍挂着脏标记(render 提前返回不会自清):
|
|
145
|
+
* 本帧它的旧区域已被擦除(全量 clear 或局部 erase 区域),因此清除脏位并移除快照,
|
|
146
|
+
* 避免「永久脏组件把后续局部帧反复顶成全量」。display 重新打开时 setState 会重新置脏。
|
|
147
|
+
*/
|
|
148
|
+
private __finalizeHidden;
|
|
149
|
+
}
|
|
150
|
+
export default CanvasRenderer;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export interface CachedSurface {
|
|
2
|
+
canvas: any;
|
|
3
|
+
ctx: any;
|
|
4
|
+
/** 位图尺寸(设备像素,四周各含 1px 透明余量,用于吸收贴图取整误差)。 */
|
|
5
|
+
pw: number;
|
|
6
|
+
ph: number;
|
|
7
|
+
/** 当前贴图落点(整数设备像素)。 */
|
|
8
|
+
dx: number;
|
|
9
|
+
dy: number;
|
|
10
|
+
/** 建位图时的贴图落点;纯平移复用由 `dx0/dy0` 加「设备像素取整的位移」推出,不会累积漂移。 */
|
|
11
|
+
dx0: number;
|
|
12
|
+
dy0: number;
|
|
13
|
+
/** 建位图时的世界盒左上角(paint pad 之后)。 */
|
|
14
|
+
buildMinX: number;
|
|
15
|
+
buildMinY: number;
|
|
16
|
+
/** 建位图时的渲染视口:`device = world * rs + (ox, oy)`。视口一变,位图即失效。 */
|
|
17
|
+
rs: number;
|
|
18
|
+
ox: number;
|
|
19
|
+
oy: number;
|
|
20
|
+
contentKey: string;
|
|
21
|
+
linearKey: string;
|
|
22
|
+
}
|
|
23
|
+
declare class ObjectCache {
|
|
24
|
+
private ice;
|
|
25
|
+
private map;
|
|
26
|
+
/** 已缓存位图的累计字节数(用于总预算门控;WeakMap 不可遍历,故显式记账)。 */
|
|
27
|
+
private __bytes;
|
|
28
|
+
/** 上一帧的渲染视口(复用同一对象,避免每帧分配)。 */
|
|
29
|
+
private __vp;
|
|
30
|
+
/** 本帧的渲染视口是否与上一帧不同。视口变化帧一律不缓存,见 `beginFrame()`。 */
|
|
31
|
+
private __vpChanged;
|
|
32
|
+
constructor(ice: any);
|
|
33
|
+
/** 渲染视口:世界 → 画布设备像素的仿射映射(`device = world * scale + (tx, ty)`)。 */
|
|
34
|
+
private __rvp;
|
|
35
|
+
/**
|
|
36
|
+
* 渲染器每帧开头调用:记录「渲染视口是否相对上一帧发生了变化」。
|
|
37
|
+
*
|
|
38
|
+
* 视口一变,所有位图的栅格都要重算(重新光栅化),代价与「这一帧直接落墨」同阶;
|
|
39
|
+
* 而缩放/平移过程中视口每帧都在变 —— 那时缓存只会白扫一遍整屏。因此视口变化的那一帧
|
|
40
|
+
* 直接停用缓存(`isCachable` 返回 false),落到与旧引擎一致的直接绘制路径;
|
|
41
|
+
* 手势停下后的第一帧再统一重建一次。
|
|
42
|
+
*/
|
|
43
|
+
beginFrame(): void;
|
|
44
|
+
/** 位图是否与当前渲染视口同源(缩放与平移都必须一致,否则栅格不再对齐)。 */
|
|
45
|
+
private __sameViewport;
|
|
46
|
+
/**
|
|
47
|
+
* 组件是否走离屏缓存。v1 只缓存「非编辑态、可见」的 ICEText;后续可扩展到 dot-path /
|
|
48
|
+
* 半透明 / ICEGroup 子树。
|
|
49
|
+
*/
|
|
50
|
+
isCachable(component: any): boolean;
|
|
51
|
+
has(component: any): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* 内容指纹:决定位图是否需要重新光栅化。只涵盖影响文本外观的 state 字段,
|
|
54
|
+
* 不包含 left/top/transform(由 linearKey 单独处理,以便纯平移复用)。
|
|
55
|
+
*/
|
|
56
|
+
contentKey(component: any): string;
|
|
57
|
+
private __styleKey;
|
|
58
|
+
/** 线性变换指纹(composedMatrix 的 a,b,c,d);平移分量单独保存,供纯平移复用。 */
|
|
59
|
+
linearKey(component: any): string;
|
|
60
|
+
/**
|
|
61
|
+
* 按缓存路径渲染组件。
|
|
62
|
+
* @returns true = 已由缓存处理;false = 组件不可缓存,调用方应回退到 component.render()。
|
|
63
|
+
*/
|
|
64
|
+
render(component: any): boolean;
|
|
65
|
+
/** 组件的「真实落墨盒」(世界坐标):几何盒 + paint pad。 */
|
|
66
|
+
private __paintBox;
|
|
67
|
+
private build;
|
|
68
|
+
/**
|
|
69
|
+
* 纯平移复用:保持位图内容不变,把贴图落点按「设备像素取整的位移」挪过去。
|
|
70
|
+
*
|
|
71
|
+
* @returns false = 位图已罩不住新盒(或位移非设备像素对齐)→ 调用方必须重建。
|
|
72
|
+
*/
|
|
73
|
+
private refreshPosition;
|
|
74
|
+
/** 贴图:回到单位变换,按整数设备像素落点 1:1 拷贝位图(不传目标宽高 → 零重采样)。 */
|
|
75
|
+
private draw;
|
|
76
|
+
invalidate(component: any): void;
|
|
77
|
+
clear(): void;
|
|
78
|
+
}
|
|
79
|
+
export default ObjectCache;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export interface CachedSurface {
|
|
2
|
+
canvas: any;
|
|
3
|
+
ctx: any;
|
|
4
|
+
/** 位图尺寸(设备像素,四周各含 1px 透明余量,用于吸收贴图取整误差)。 */
|
|
5
|
+
pw: number;
|
|
6
|
+
ph: number;
|
|
7
|
+
/** 当前贴图落点(整数设备像素)。 */
|
|
8
|
+
dx: number;
|
|
9
|
+
dy: number;
|
|
10
|
+
/** 建位图时的贴图落点;纯平移复用由 `dx0/dy0` 加「设备像素取整的位移」推出,不会累积漂移。 */
|
|
11
|
+
dx0: number;
|
|
12
|
+
dy0: number;
|
|
13
|
+
/** 建位图时的世界盒左上角(paint pad 之后)。 */
|
|
14
|
+
buildMinX: number;
|
|
15
|
+
buildMinY: number;
|
|
16
|
+
/** 建位图时的渲染视口:`device = world * rs + (ox, oy)`。视口一变,位图即失效。 */
|
|
17
|
+
rs: number;
|
|
18
|
+
ox: number;
|
|
19
|
+
oy: number;
|
|
20
|
+
contentKey: string;
|
|
21
|
+
linearKey: string;
|
|
22
|
+
}
|
|
23
|
+
declare class ObjectCache {
|
|
24
|
+
private ice;
|
|
25
|
+
private map;
|
|
26
|
+
/** 已缓存位图的累计字节数(用于总预算门控;WeakMap 不可遍历,故显式记账)。 */
|
|
27
|
+
private __bytes;
|
|
28
|
+
/** 上一帧的渲染视口(复用同一对象,避免每帧分配)。 */
|
|
29
|
+
private __vp;
|
|
30
|
+
/** 本帧的渲染视口是否与上一帧不同。视口变化帧一律不缓存,见 `beginFrame()`。 */
|
|
31
|
+
private __vpChanged;
|
|
32
|
+
constructor(ice: any);
|
|
33
|
+
/** 渲染视口:世界 → 画布设备像素的仿射映射(`device = world * scale + (tx, ty)`)。 */
|
|
34
|
+
private __rvp;
|
|
35
|
+
/**
|
|
36
|
+
* 渲染器每帧开头调用:记录「渲染视口是否相对上一帧发生了变化」。
|
|
37
|
+
*
|
|
38
|
+
* 视口一变,所有位图的栅格都要重算(重新光栅化),代价与「这一帧直接落墨」同阶;
|
|
39
|
+
* 而缩放/平移过程中视口每帧都在变 —— 那时缓存只会白扫一遍整屏。因此视口变化的那一帧
|
|
40
|
+
* 直接停用缓存(`isCachable` 返回 false),落到与旧引擎一致的直接绘制路径;
|
|
41
|
+
* 手势停下后的第一帧再统一重建一次。
|
|
42
|
+
*/
|
|
43
|
+
beginFrame(): void;
|
|
44
|
+
/** 位图是否与当前渲染视口同源(缩放与平移都必须一致,否则栅格不再对齐)。 */
|
|
45
|
+
private __sameViewport;
|
|
46
|
+
/**
|
|
47
|
+
* 组件是否走离屏缓存。v1 只缓存「非编辑态、可见」的 ICEText;后续可扩展到 dot-path /
|
|
48
|
+
* 半透明 / ICEGroup 子树。
|
|
49
|
+
*/
|
|
50
|
+
isCachable(component: any): boolean;
|
|
51
|
+
has(component: any): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* 内容指纹:决定位图是否需要重新光栅化。只涵盖影响文本外观的 state 字段,
|
|
54
|
+
* 不包含 left/top/transform(由 linearKey 单独处理,以便纯平移复用)。
|
|
55
|
+
*/
|
|
56
|
+
contentKey(component: any): string;
|
|
57
|
+
private __styleKey;
|
|
58
|
+
/** 线性变换指纹(composedMatrix 的 a,b,c,d);平移分量单独保存,供纯平移复用。 */
|
|
59
|
+
linearKey(component: any): string;
|
|
60
|
+
/**
|
|
61
|
+
* 按缓存路径渲染组件。
|
|
62
|
+
* @returns true = 已由缓存处理;false = 组件不可缓存,调用方应回退到 component.render()。
|
|
63
|
+
*/
|
|
64
|
+
render(component: any): boolean;
|
|
65
|
+
/** 组件的「真实落墨盒」(世界坐标):几何盒 + paint pad。 */
|
|
66
|
+
private __paintBox;
|
|
67
|
+
private build;
|
|
68
|
+
/**
|
|
69
|
+
* 纯平移复用:保持位图内容不变,把贴图落点按「设备像素取整的位移」挪过去。
|
|
70
|
+
*
|
|
71
|
+
* @returns false = 位图已罩不住新盒(或位移非设备像素对齐)→ 调用方必须重建。
|
|
72
|
+
*/
|
|
73
|
+
private refreshPosition;
|
|
74
|
+
/** 贴图:回到单位变换,按整数设备像素落点 1:1 拷贝位图(不传目标宽高 → 零重采样)。 */
|
|
75
|
+
private draw;
|
|
76
|
+
invalidate(component: any): void;
|
|
77
|
+
clear(): void;
|
|
78
|
+
}
|
|
79
|
+
export default ObjectCache;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 脏矩形局部重绘(dirty-rect)的纯函数工具集。
|
|
3
|
+
*
|
|
4
|
+
* 本模块不依赖任何引擎实例/ctx,所有几何与阈值计算都可用 jest 直接单测。
|
|
5
|
+
* 设计目标见 docs/architecture/04-rendering-performance.md「脏矩形局部重绘」章节。
|
|
6
|
+
*
|
|
7
|
+
* 盒的表示:一维数组 [minX, minY, maxX, maxY](世界/画布坐标,轴对齐,已含 paint pad)。
|
|
8
|
+
*/
|
|
9
|
+
/** 抗锯齿兜底余量(px),覆盖 1px 级 AA 溢出与文字 baseline 溢出。 */
|
|
10
|
+
export declare const PAD_AA = 2;
|
|
11
|
+
/**
|
|
12
|
+
* 命中预筛的包围盒容差(px)。
|
|
13
|
+
*
|
|
14
|
+
* 命中的第一道筛子用「渲染快照的世界盒」做 O(1) 拒绝;快照盒本身已含 paint pad
|
|
15
|
+
* (含 AA 余量),但折线的命中判定自带 errorRange 容差,这里再放宽 1px 作为安全余量,
|
|
16
|
+
* 确保预筛绝不误杀边界命中。
|
|
17
|
+
*/
|
|
18
|
+
export declare const HIT_BOX_TOLERANCE = 1;
|
|
19
|
+
/**
|
|
20
|
+
* 计算组件「实际绘制会溢出几何边界多少像素」的保守 padding。
|
|
21
|
+
* 依据 state(style.lineWidth / lineBorderWidth / shadow 等)实时估算,
|
|
22
|
+
* 用于把几何包围盒扩成「真实落墨盒」。
|
|
23
|
+
*/
|
|
24
|
+
export declare function stylePaintPad(state: any): number;
|
|
25
|
+
export declare function boxWidth(box: number[]): number;
|
|
26
|
+
export declare function boxHeight(box: number[]): number;
|
|
27
|
+
export declare function boxArea(box: number[]): number;
|
|
28
|
+
/**
|
|
29
|
+
* 把 src 盒并进 target 盒(原地修改 target,减少分配)。
|
|
30
|
+
* target 传入空盒([Infinity,Infinity,-Infinity,-Infinity])即可从 src 开始累加。
|
|
31
|
+
*/
|
|
32
|
+
export declare function unionBoxes(target: number[], src: number[]): number[];
|
|
33
|
+
/** 判断盒 a 与盒 b 是否相交(含边界相触)。 */
|
|
34
|
+
export declare function intersects(a: number[], b: number[]): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* 盒内是否有限(无 NaN/Infinity)。非法盒不得参与区域计算或写入快照。
|
|
37
|
+
*/
|
|
38
|
+
export declare function isFiniteBox(box: number[]): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* 生成一个「空盒」,可用作 unionBoxes 的起点。
|
|
41
|
+
*/
|
|
42
|
+
export declare function emptyBox(): number[];
|
|
43
|
+
/**
|
|
44
|
+
* 把盒外扩到整像素边界(min 向下取整、max 向上取整),保证 clearRect/clip 用同一像素掩码,
|
|
45
|
+
* 消除「清除区域与裁剪区域亚像素不一致」导致的接缝。
|
|
46
|
+
*/
|
|
47
|
+
export declare function integerAlign(box: number[]): number[];
|
|
48
|
+
/**
|
|
49
|
+
* 合并两个盒为一个盒(取并集,不修改入参)。
|
|
50
|
+
*/
|
|
51
|
+
export declare function mergeBox(a: number[], b: number[]): number[];
|
|
52
|
+
export declare function coalesceRegions(boxes: number[][], maxRegions?: number): number[][];
|
|
53
|
+
/**
|
|
54
|
+
* 多块裁剪区的总面积占画布的比例(用于「接近整屏则回退全量」的判定)。
|
|
55
|
+
* 各块互不相接,面积可直接相加。
|
|
56
|
+
*/
|
|
57
|
+
export declare function regionsAreaRatio(regions: number[][], canvasWidth: number, canvasHeight: number): number;
|
|
58
|
+
/**
|
|
59
|
+
* 把「世界坐标盒」映射到「渲染坐标盒」(含 dpr),并向外取整。
|
|
60
|
+
*
|
|
61
|
+
* 渲染坐标 = 世界坐标 × 渲染视口 scale + 渲染视口 tx/ty,而 `ICE.getRenderViewport()` 已经
|
|
62
|
+
* 把 dpr 乘进 scale 与 tx/ty(见 `ICE.getRenderViewport`)。`clearRect` / `clip` 用的正是这个
|
|
63
|
+
* 坐标系,但脏区收集是在**世界坐标**里做的(上屏快照盒、组件几何盒都是世界盒),
|
|
64
|
+
* 两者只在「视口为单位变换且 dpr === 1」时才重合 —— 这个函数就是它们之间唯一的换算点。
|
|
65
|
+
*
|
|
66
|
+
* 向外取整(min 向下、max 向上)保证映射后的区域不小于真实脏区,避免缩放时边缘出现接缝。
|
|
67
|
+
*/
|
|
68
|
+
export declare function mapBoxToRender(box: number[], viewport: {
|
|
69
|
+
scale: number;
|
|
70
|
+
tx: number;
|
|
71
|
+
ty: number;
|
|
72
|
+
}, out?: number[]): number[];
|
|
73
|
+
/**
|
|
74
|
+
* 区域占画布总面积的比例,用于「接近整屏则回退全量」的判定。
|
|
75
|
+
*/
|
|
76
|
+
export declare function regionRatio(box: number[], canvasWidth: number, canvasHeight: number): number;
|
|
77
|
+
/**
|
|
78
|
+
* 判断组件是否以「完全不透明、仅 source-over」的方式绘制。
|
|
79
|
+
*
|
|
80
|
+
* dirty-rect 用 clip 把补画限定在脏区域内;clip 边界与「半透明落墨(alpha 色 / 阴影 /
|
|
81
|
+
* globalAlpha / 合成模式)」相交时,canvas 的 clip 会改变边界像素的子像素覆盖率,
|
|
82
|
+
* 产生与全量渲染不一致的接缝。因此 v1 约定:本帧区域涉及任何非不透明落墨的组件时回退全量,
|
|
83
|
+
* 局部重绘只服务于不透明场景(编辑器里的大多数实体/卡片/表格)。
|
|
84
|
+
* 语义化渐变色(对象)视为不透明。
|
|
85
|
+
*/
|
|
86
|
+
export declare function isOpaqueDrawing(state: any): boolean;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 脏矩形局部重绘(dirty-rect)的纯函数工具集。
|
|
3
|
+
*
|
|
4
|
+
* 本模块不依赖任何引擎实例/ctx,所有几何与阈值计算都可用 jest 直接单测。
|
|
5
|
+
* 设计目标见 docs/architecture/04-rendering-performance.md「脏矩形局部重绘」章节。
|
|
6
|
+
*
|
|
7
|
+
* 盒的表示:一维数组 [minX, minY, maxX, maxY](世界/画布坐标,轴对齐,已含 paint pad)。
|
|
8
|
+
*/
|
|
9
|
+
/** 抗锯齿兜底余量(px),覆盖 1px 级 AA 溢出与文字 baseline 溢出。 */
|
|
10
|
+
export declare const PAD_AA = 2;
|
|
11
|
+
/**
|
|
12
|
+
* 命中预筛的包围盒容差(px)。
|
|
13
|
+
*
|
|
14
|
+
* 命中的第一道筛子用「渲染快照的世界盒」做 O(1) 拒绝;快照盒本身已含 paint pad
|
|
15
|
+
* (含 AA 余量),但折线的命中判定自带 errorRange 容差,这里再放宽 1px 作为安全余量,
|
|
16
|
+
* 确保预筛绝不误杀边界命中。
|
|
17
|
+
*/
|
|
18
|
+
export declare const HIT_BOX_TOLERANCE = 1;
|
|
19
|
+
/**
|
|
20
|
+
* 计算组件「实际绘制会溢出几何边界多少像素」的保守 padding。
|
|
21
|
+
* 依据 state(style.lineWidth / lineBorderWidth / shadow 等)实时估算,
|
|
22
|
+
* 用于把几何包围盒扩成「真实落墨盒」。
|
|
23
|
+
*/
|
|
24
|
+
export declare function stylePaintPad(state: any): number;
|
|
25
|
+
export declare function boxWidth(box: number[]): number;
|
|
26
|
+
export declare function boxHeight(box: number[]): number;
|
|
27
|
+
export declare function boxArea(box: number[]): number;
|
|
28
|
+
/**
|
|
29
|
+
* 把 src 盒并进 target 盒(原地修改 target,减少分配)。
|
|
30
|
+
* target 传入空盒([Infinity,Infinity,-Infinity,-Infinity])即可从 src 开始累加。
|
|
31
|
+
*/
|
|
32
|
+
export declare function unionBoxes(target: number[], src: number[]): number[];
|
|
33
|
+
/** 判断盒 a 与盒 b 是否相交(含边界相触)。 */
|
|
34
|
+
export declare function intersects(a: number[], b: number[]): boolean;
|
|
35
|
+
/**
|
|
36
|
+
* 盒内是否有限(无 NaN/Infinity)。非法盒不得参与区域计算或写入快照。
|
|
37
|
+
*/
|
|
38
|
+
export declare function isFiniteBox(box: number[]): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* 生成一个「空盒」,可用作 unionBoxes 的起点。
|
|
41
|
+
*/
|
|
42
|
+
export declare function emptyBox(): number[];
|
|
43
|
+
/**
|
|
44
|
+
* 把盒外扩到整像素边界(min 向下取整、max 向上取整),保证 clearRect/clip 用同一像素掩码,
|
|
45
|
+
* 消除「清除区域与裁剪区域亚像素不一致」导致的接缝。
|
|
46
|
+
*/
|
|
47
|
+
export declare function integerAlign(box: number[]): number[];
|
|
48
|
+
/**
|
|
49
|
+
* 合并两个盒为一个盒(取并集,不修改入参)。
|
|
50
|
+
*/
|
|
51
|
+
export declare function mergeBox(a: number[], b: number[]): number[];
|
|
52
|
+
export declare function coalesceRegions(boxes: number[][], maxRegions?: number): number[][];
|
|
53
|
+
/**
|
|
54
|
+
* 多块裁剪区的总面积占画布的比例(用于「接近整屏则回退全量」的判定)。
|
|
55
|
+
* 各块互不相接,面积可直接相加。
|
|
56
|
+
*/
|
|
57
|
+
export declare function regionsAreaRatio(regions: number[][], canvasWidth: number, canvasHeight: number): number;
|
|
58
|
+
/**
|
|
59
|
+
* 把「世界坐标盒」映射到「渲染坐标盒」(含 dpr),并向外取整。
|
|
60
|
+
*
|
|
61
|
+
* 渲染坐标 = 世界坐标 × 渲染视口 scale + 渲染视口 tx/ty,而 `ICE.getRenderViewport()` 已经
|
|
62
|
+
* 把 dpr 乘进 scale 与 tx/ty(见 `ICE.getRenderViewport`)。`clearRect` / `clip` 用的正是这个
|
|
63
|
+
* 坐标系,但脏区收集是在**世界坐标**里做的(上屏快照盒、组件几何盒都是世界盒),
|
|
64
|
+
* 两者只在「视口为单位变换且 dpr === 1」时才重合 —— 这个函数就是它们之间唯一的换算点。
|
|
65
|
+
*
|
|
66
|
+
* 向外取整(min 向下、max 向上)保证映射后的区域不小于真实脏区,避免缩放时边缘出现接缝。
|
|
67
|
+
*/
|
|
68
|
+
export declare function mapBoxToRender(box: number[], viewport: {
|
|
69
|
+
scale: number;
|
|
70
|
+
tx: number;
|
|
71
|
+
ty: number;
|
|
72
|
+
}, out?: number[]): number[];
|
|
73
|
+
/**
|
|
74
|
+
* 区域占画布总面积的比例,用于「接近整屏则回退全量」的判定。
|
|
75
|
+
*/
|
|
76
|
+
export declare function regionRatio(box: number[], canvasWidth: number, canvasHeight: number): number;
|
|
77
|
+
/**
|
|
78
|
+
* 判断组件是否以「完全不透明、仅 source-over」的方式绘制。
|
|
79
|
+
*
|
|
80
|
+
* dirty-rect 用 clip 把补画限定在脏区域内;clip 边界与「半透明落墨(alpha 色 / 阴影 /
|
|
81
|
+
* globalAlpha / 合成模式)」相交时,canvas 的 clip 会改变边界像素的子像素覆盖率,
|
|
82
|
+
* 产生与全量渲染不一致的接缝。因此 v1 约定:本帧区域涉及任何非不透明落墨的组件时回退全量,
|
|
83
|
+
* 局部重绘只服务于不透明场景(编辑器里的大多数实体/卡片/表格)。
|
|
84
|
+
* 语义化渐变色(对象)视为不透明。
|
|
85
|
+
*/
|
|
86
|
+
export declare function isOpaqueDrawing(state: any): boolean;
|