@shijiu/jsview 1.9.731 → 1.9.759

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 (124) hide show
  1. package/dom/jsv-browser-debug-dom.js +12 -5
  2. package/dom/jsv-code-debug.mjs +14 -0
  3. package/dom/jsv-dom.js +12 -5
  4. package/dom/jsv-engine-js-browser.js +12 -5
  5. package/dom/jsv-forge-define.js +17 -5
  6. package/package.json +14 -17
  7. package/patches/node_modules/react-scripts/config/paths.js +161 -0
  8. package/patches/node_modules/react-scripts/config/webpack.config.js +825 -0
  9. package/patches/node_modules/react-scripts/package.json +108 -0
  10. package/patches/node_modules/vite/dist/node/chunks/dep-0fc8e132.js +8 -1
  11. package/patches/node_modules/vite/dist/node/jsview.vite.config.js +15 -7
  12. package/tools/common.js +7 -2
  13. package/tools/jsview-post-build.js +3 -3
  14. package/tools/jsview-post-install-react.js +1 -3
  15. package/tools/jsview-post-install.js +1 -1
  16. package/dom/jsview-dom/README.md +0 -5
  17. package/dom/jsview-dom/package-lock.json-perfect +0 -3898
  18. package/dom/jsview-dom/package.json +0 -23
  19. package/dom/jsview-dom/rollup/browser-debug-dom.rollup.config.js +0 -15
  20. package/dom/jsview-dom/rollup/dom.rollup.config.js +0 -14
  21. package/dom/jsview-dom/rollup/engine-js-browser.rollup.config.js +0 -14
  22. package/dom/jsview-dom/rollup/forge-define.rollup.config.js +0 -14
  23. package/dom/jsview-dom/scripts/release_dist.sh +0 -36
  24. package/dom/jsview-dom/src/dom-browser-hook/HookDocument.js +0 -118
  25. package/dom/jsview-dom/src/dom-browser-hook/OriginDocument.js +0 -19
  26. package/dom/jsview-dom/src/dom-browser-hook/StyleFormatCheck.js +0 -559
  27. package/dom/jsview-dom/src/dom-browser-hook/index.js +0 -6
  28. package/dom/jsview-dom/src/dom-wrapper/ForgeExtension.js +0 -226
  29. package/dom/jsview-dom/src/dom-wrapper/JsViewForgeApp.js +0 -85
  30. package/dom/jsview-dom/src/dom-wrapper/JsViewProxy.js +0 -51
  31. package/dom/jsview-dom/src/dom-wrapper/event/AnimationEvent.js +0 -7
  32. package/dom/jsview-dom/src/dom-wrapper/event/Event.js +0 -12
  33. package/dom/jsview-dom/src/dom-wrapper/event/FocusEvent.js +0 -9
  34. package/dom/jsview-dom/src/dom-wrapper/event/KeyboardEvent.js +0 -43
  35. package/dom/jsview-dom/src/dom-wrapper/event/LoadEvent.js +0 -8
  36. package/dom/jsview-dom/src/dom-wrapper/index.js +0 -16
  37. package/dom/jsview-dom/src/dom-wrapper/node/AnchorElement.js +0 -24
  38. package/dom/jsview-dom/src/dom-wrapper/node/AudioElement.js +0 -60
  39. package/dom/jsview-dom/src/dom-wrapper/node/Comment.js +0 -10
  40. package/dom/jsview-dom/src/dom-wrapper/node/DivElement.js +0 -498
  41. package/dom/jsview-dom/src/dom-wrapper/node/Document.js +0 -274
  42. package/dom/jsview-dom/src/dom-wrapper/node/Element.js +0 -852
  43. package/dom/jsview-dom/src/dom-wrapper/node/FDivElement.js +0 -48
  44. package/dom/jsview-dom/src/dom-wrapper/node/HeadElement.js +0 -47
  45. package/dom/jsview-dom/src/dom-wrapper/node/ImageElement.js +0 -203
  46. package/dom/jsview-dom/src/dom-wrapper/node/JsvAudioTrackElement.js +0 -22
  47. package/dom/jsview-dom/src/dom-wrapper/node/JsvElement.js +0 -40
  48. package/dom/jsview-dom/src/dom-wrapper/node/LinkElement.js +0 -48
  49. package/dom/jsview-dom/src/dom-wrapper/node/MediaElement.js +0 -230
  50. package/dom/jsview-dom/src/dom-wrapper/node/Node.js +0 -178
  51. package/dom/jsview-dom/src/dom-wrapper/node/SVGElement.js +0 -9
  52. package/dom/jsview-dom/src/dom-wrapper/node/ScriptElement.js +0 -45
  53. package/dom/jsview-dom/src/dom-wrapper/node/StyleElement.js +0 -33
  54. package/dom/jsview-dom/src/dom-wrapper/node/StyleElementCache.js +0 -41
  55. package/dom/jsview-dom/src/dom-wrapper/node/Text.js +0 -22
  56. package/dom/jsview-dom/src/dom-wrapper/node/UnknownElement.js +0 -4
  57. package/dom/jsview-dom/src/dom-wrapper/node/VideoElement.js +0 -237
  58. package/dom/jsview-dom/src/dom-wrapper/style/BorderImage.js +0 -25
  59. package/dom/jsview-dom/src/dom-wrapper/style/Inset.js +0 -26
  60. package/dom/jsview-dom/src/dom-wrapper/style/JsvStyleVariable.js +0 -65
  61. package/dom/jsview-dom/src/dom-wrapper/style/KeyframeRule.js +0 -11
  62. package/dom/jsview-dom/src/dom-wrapper/style/StyleDeclaration.js +0 -609
  63. package/dom/jsview-dom/src/dom-wrapper/style/StyleSheet.js +0 -51
  64. package/dom/jsview-dom/src/dom-wrapper/style/StyleValue.js +0 -385
  65. package/dom/jsview-dom/src/dom-wrapper/style/TextStylePackMap.js +0 -43
  66. package/dom/jsview-dom/src/dom-wrapper/style/URL.js +0 -144
  67. package/dom/jsview-dom/src/dom-wrapper/utils/EventHandler.js +0 -42
  68. package/dom/jsview-dom/src/dom-wrapper/utils/FDivRoot.js +0 -86
  69. package/dom/jsview-dom/src/dom-wrapper/utils/JsvLazySyncCache.js +0 -64
  70. package/dom/jsview-dom/src/dom-wrapper/utils/Log.js +0 -42
  71. package/dom/jsview-dom/src/dom-wrapper/utils/MutationObserver.js +0 -32
  72. package/dom/jsview-dom/src/dom-wrapper/utils/focusableNode.js +0 -715
  73. package/dom/jsview-dom/src/engine-js/ForgeDefine.js +0 -8
  74. package/dom/jsview-dom/src/engine-js/ForgeExtensionDefine.js +0 -14
  75. package/dom/jsview-dom/src/engine-js/browser/PlatformUtils.js +0 -100
  76. package/dom/jsview-dom/src/engine-js/browser/animation_base.js +0 -313
  77. package/dom/jsview-dom/src/engine-js/browser/animation_keyframe.js +0 -64
  78. package/dom/jsview-dom/src/engine-js/browser/animation_progress.js +0 -287
  79. package/dom/jsview-dom/src/engine-js/browser/animation_proxy.js +0 -906
  80. package/dom/jsview-dom/src/engine-js/browser/apic_decoder/demux.js +0 -143
  81. package/dom/jsview-dom/src/engine-js/browser/apic_decoder/gifDecoder.js +0 -12
  82. package/dom/jsview-dom/src/engine-js/browser/apic_decoder/libwebp-0.6.0.min.js +0 -160
  83. package/dom/jsview-dom/src/engine-js/browser/console_log.js +0 -25
  84. package/dom/jsview-dom/src/engine-js/browser/dynamic_key_frames.js +0 -95
  85. package/dom/jsview-dom/src/engine-js/browser/easing.js +0 -114
  86. package/dom/jsview-dom/src/engine-js/browser/html_shared_tools/element_transform.js +0 -122
  87. package/dom/jsview-dom/src/engine-js/browser/html_shared_tools/gjk.js +0 -450
  88. package/dom/jsview-dom/src/engine-js/browser/html_shared_tools/mat.js +0 -102
  89. package/dom/jsview-dom/src/engine-js/browser/html_shared_tools/range_model.js +0 -296
  90. package/dom/jsview-dom/src/engine-js/browser/html_shared_tools/test_collide.js +0 -10
  91. package/dom/jsview-dom/src/engine-js/browser/index.js +0 -38
  92. package/dom/jsview-dom/src/engine-js/browser/latex_parse.js +0 -336
  93. package/dom/jsview-dom/src/engine-js/browser/layout_params.js +0 -113
  94. package/dom/jsview-dom/src/engine-js/browser/layout_view.js +0 -3545
  95. package/dom/jsview-dom/src/engine-js/browser/layout_view_debug.js +0 -15
  96. package/dom/jsview-dom/src/engine-js/browser/media.js +0 -379
  97. package/dom/jsview-dom/src/engine-js/browser/page_base.js +0 -941
  98. package/dom/jsview-dom/src/engine-js/browser/particle_view.js +0 -526
  99. package/dom/jsview-dom/src/engine-js/browser/platform_timer.js +0 -61
  100. package/dom/jsview-dom/src/engine-js/browser/react_utils.js +0 -5
  101. package/dom/jsview-dom/src/engine-js/browser/rect_utils.js +0 -91
  102. package/dom/jsview-dom/src/engine-js/browser/render_bridge.js +0 -128
  103. package/dom/jsview-dom/src/engine-js/browser/render_texture_proxy.js +0 -155
  104. package/dom/jsview-dom/src/engine-js/browser/renderer_deprecated.js +0 -75
  105. package/dom/jsview-dom/src/engine-js/browser/sound_pool.js +0 -139
  106. package/dom/jsview-dom/src/engine-js/browser/steps_animation.js +0 -192
  107. package/dom/jsview-dom/src/engine-js/browser/text_style_cache.js +0 -454
  108. package/dom/jsview-dom/src/engine-js/browser/text_utils.js +0 -299
  109. package/dom/jsview-dom/src/engine-js/browser/text_view.js +0 -428
  110. package/dom/jsview-dom/src/engine-js/browser/texture_manager.js +0 -1060
  111. package/dom/jsview-dom/src/engine-js/browser/url.js +0 -69
  112. package/dom/jsview-dom/src/engine-js/browser/velocity.js +0 -40
  113. package/dom/jsview-dom/src/engine-js/browser/view_sensor/autofroze_sensor.js +0 -77
  114. package/dom/jsview-dom/src/engine-js/browser/view_sensor/drag_impact_sensor.js +0 -67
  115. package/dom/jsview-dom/src/engine-js/browser/view_sensor/impact_sensor.js +0 -98
  116. package/dom/jsview-dom/src/engine-js/browser/view_sensor/impact_sensor_callback.js +0 -21
  117. package/dom/jsview-dom/src/engine-js/browser/view_sensor/impact_sensor_manager.js +0 -24
  118. package/dom/jsview-dom/src/engine-js/browser/view_sensor/index.js +0 -9
  119. package/dom/jsview-dom/src/engine-js/browser/view_sensor/view_sensor.js +0 -268
  120. package/dom/jsview-dom/src/engine-js/browser/view_sensor/view_sensor_manager.js +0 -84
  121. package/dom/jsview-dom/src/engine-js/browser/view_sensor/visible_sensor.js +0 -213
  122. package/dom/jsview-dom/src/engine-js/browser/view_store.js +0 -41
  123. package/dom/jsview-dom/src/engine-js/index.js +0 -2
  124. package/dom/jsview-dom/src/engine-js/native/README.md +0 -1
@@ -1,3545 +0,0 @@
1
- /* eslint-disable no-unused-vars */
2
- import Forge from "../ForgeDefine";
3
- import { parseLatex, toHtml } from "./latex_parse";
4
- import Velocity from "./velocity";
5
-
6
- window.gRootView = null; // For record root view
7
- Forge.sRootView = null;
8
-
9
- /**
10
- * @file layout_view.js
11
- * @namespace Forge
12
- */
13
- class TextureSetting {
14
- constructor(texture, mask, texture_before_image_load, has_alpha) {
15
- this.Texture = texture;
16
- this._IsTextureExternal = false;
17
- if (mask instanceof Forge.ImageTexture) {
18
- // 重新设置请求时间
19
- if (mask && mask.RenderTexture && mask.RenderTexture.NeedCheckExpired) {
20
- mask.RenderTexture.RequireTime = 0;
21
- }
22
- this.MaskSetting = new Forge.ViewTextureMask(mask);
23
- } else {
24
- this.MaskSetting = mask;
25
- }
26
- // 重新设置请求时间
27
- if (
28
- texture &&
29
- texture.RenderTexture &&
30
- texture.RenderTexture.NeedCheckExpired
31
- ) {
32
- texture.RenderTexture.RequireTime = 0;
33
- }
34
-
35
- this._IsMaskTextureExternal = false;
36
- this.TextureBeforeImageLoad = texture_before_image_load;
37
- this._IsPreloadImageTextureExternal = false;
38
- if (typeof has_alpha === "undefined") has_alpha = true;
39
- this.HasAlpha = has_alpha;
40
- }
41
-
42
- /**
43
- * 标识这个Texture集合是否为外部Texture<br>
44
- * 默认为内部Texture,内部Texture将在所附着的LayoutView从RootView移除时被强制释放<br>
45
- * 文字的Texture应该用内部Texture,图形Texture一般用外部Texture
46
- *
47
- * @public
48
- * @func SetExternal
49
- * @memberof Forge.TextureSetting
50
- * @instance
51
- * @param {boolean} is_texture_external 主要Texture是否为外部Texture
52
- * @param {boolean} is_mask_external 遮罩Texture是否为外部Texture
53
- * @param {boolean} is_reload_image_external 次要Texture是否为外部Texture
54
- * */
55
- SetExternal(is_texture_external, is_mask_external, is_reload_image_external) {
56
- this._IsTextureExternal = is_texture_external;
57
- this._IsMaskTextureExternal = is_mask_external;
58
- this._IsPreloadImageTextureExternal = is_reload_image_external;
59
- }
60
-
61
- ReleaseInternalTexture(renderer, container_view) {
62
- if (!this._IsTextureExternal && this.Texture) {
63
- this.Texture.UnloadTex();
64
- this.Texture = null;
65
- }
66
- if (
67
- !this._IsMaskTextureExternal &&
68
- this.MaskSetting /* && this.MaskSetting instanceof Forge.ImageTexture */
69
- ) {
70
- this.MaskSetting.UnLoad();
71
- this.MaskSetting = null;
72
- }
73
- if (!this._IsPreloadImageTextureExternal && this.TextureBeforeImageLoad) {
74
- this.TextureBeforeImageLoad.UnloadTex();
75
- this.TextureBeforeImageLoad = null;
76
- }
77
- }
78
-
79
- DebugPrint() {
80
- return ` _IsTextureExternal=${this._IsTextureExternal}`;
81
- }
82
- }
83
- Forge.TextureSetting = TextureSetting;
84
- window.TextureSetting = Forge.TextureSetting; // export class;
85
-
86
- class ExternalTextureSetting extends Forge.TextureSetting {
87
- constructor(texture, mask_texture, texture_before_image_load, has_alpha) {
88
- super(texture, mask_texture, texture_before_image_load, has_alpha);
89
- this.SetExternal(true, true, true);
90
- }
91
- }
92
- Forge.ExternalTextureSetting = ExternalTextureSetting;
93
- window.ExternalTextureSetting = Forge.ExternalTextureSetting; // export class;
94
-
95
- class PackedLayout {
96
- constructor(layout_view_base) {
97
- const data_from = layout_view_base.RectInfo;
98
- this.RectInfo = {
99
- coordX: data_from.coordX,
100
- coordY: data_from.coordY,
101
- width: data_from.width,
102
- height: data_from.height,
103
- };
104
-
105
- this.LayoutParams = JSON.parse(
106
- JSON.stringify(layout_view_base.LayoutParams)
107
- );
108
- }
109
-
110
- ApplyToView(target_view) {
111
- const data_from = this.RectInfo;
112
- target_view.RectInfo = {
113
- coordX: data_from.coordX,
114
- coordY: data_from.coordY,
115
- width: data_from.width,
116
- height: data_from.height,
117
- };
118
-
119
- target_view.LayoutParams = JSON.parse(JSON.stringify(this.LayoutParams));
120
- }
121
- }
122
- Forge.PackedLayout = PackedLayout;
123
-
124
- class ViewMask {
125
- constructor() {
126
- this._MaskType = "COMMON";
127
- }
128
-
129
- Type() {
130
- return this._MaskType;
131
- }
132
-
133
- UnLoad() {
134
- // need to be overrided
135
- }
136
- }
137
- Forge.ViewMask = ViewMask;
138
-
139
- class ViewTextureMask extends Forge.ViewMask {
140
- constructor(image_texture) {
141
- super();
142
- this._MaskType = "TEXTURE";
143
- this.ImageTexture = image_texture;
144
- }
145
-
146
- UnLoad() {
147
- this.ImageTexture.UnloadTex();
148
- }
149
- }
150
- Forge.ViewTextureMask = ViewTextureMask;
151
- class ViewRoundCornerMask extends Forge.ViewMask {
152
- constructor(top_left, top_right, bottom_left, bottom_right) {
153
- super();
154
-
155
- this._MaskType = "CORNER";
156
-
157
- this._TopLeft = top_left;
158
- this._TopRight = !isNaN(top_right) ? top_right : top_left;
159
- this._BottomLeft = !isNaN(bottom_left) ? bottom_left : top_left;
160
- this._BottomRight = !isNaN(bottom_right) ? bottom_right : top_left;
161
-
162
- this._CornersWidth = [0.0, 0.0, 0.0, 0.0];
163
- this._CornersDisable = [
164
- this._TopLeft === 0 ? 1.0 : 0.0,
165
- this._TopRight === 0 ? 1.0 : 0.0,
166
- this._BottomLeft === 0 ? 1.0 : 0.0,
167
- this._BottomRight === 0 ? 1.0 : 0.0,
168
- ];
169
- }
170
-
171
- UnLoad() {
172
- // nothing to do
173
- }
174
- }
175
- Forge.ViewRoundCornerMask = ViewRoundCornerMask;
176
-
177
- class DragSetting {
178
- /**
179
- * 拖拽参数设置
180
- * @param {int}drag_direction 拖拽方向: 横向、纵向、自由拖拽、Disable
181
- * @param {int}trigger_moved_distance onMoved事件触发的移动距离
182
- * @param {boolean} enable_js_fling 是否由js进行fling操作,true:js进行fling,false:系统执行fling
183
- * @param {Forge.RectArea} slide_pile 滑桩 view 滑动时由滑桩控制其滑动区域
184
- * @param {int}fling_page_width 滑动页的宽度,即开启整平滑动模式
185
- * @param {int}fling_page_edge 触发整屏滑动页的边界,默认为1/4
186
- */
187
- constructor(
188
- drag_direction,
189
- trigger_moved_distance,
190
- enable_js_fling,
191
- slide_pile,
192
- fling_page_width,
193
- fling_page_edge
194
- ) {
195
- this.DragDirection = drag_direction || 0;
196
- this.TriggerMovedDistance = trigger_moved_distance || 0;
197
- this._EnableJsFling = enable_js_fling ? 1 : 0;
198
- this.SlidePile = slide_pile || new Forge.RectArea(0, 0, 1280, 720);
199
- this.PageWidth = fling_page_width > 0 ? fling_page_width : 0xffff;
200
- this.EnableTabMode = fling_page_width > 0;
201
- this.PageEdge = fling_page_edge || 1 / 4;
202
- }
203
- }
204
-
205
- Forge.DragSetting = DragSetting;
206
- Forge.DragSetting.DIRECTION_DISABLE = 0x00; // 只接收长按/quick tap事件
207
- Forge.DragSetting.DIRECTION_VERTICAL = 0x01;
208
- Forge.DragSetting.DIRECTION_HORIZONTAL = 0x02;
209
- Forge.DragSetting.DIRECTION_AUTO =
210
- Forge.DragSetting.DIRECTION_VERTICAL | Forge.DragSetting.DIRECTION_HORIZONTAL;
211
-
212
- Forge.DragInfo = class {
213
- constructor() {
214
- this.Settings = null;
215
- this.Listener = null;
216
- this.ListenerFlags = 0;
217
- this.OverListener = null;
218
- this.OverListenerFlags = 0;
219
- this.Formula = null;
220
- this.SyncString = null; // Deprecated;
221
- }
222
-
223
- SetListener(listener) {
224
- this.Listener = listener;
225
- }
226
- };
227
- Forge.DragInfo.INFLEXION = 0.35; // Tension lines cross at (INFLEXION, 1)//拐点
228
-
229
- Forge.DragInfo.DECELERATION_RATE = Math.log(0.78) / Math.log(0.9); // 减速率
230
-
231
- Forge.DragInfo.PHYSICAL_COEF = 51890.2; // 物理系数
232
-
233
- /**
234
- * final float ppi = context.getResources().getDisplayMetrics().density * 160.0f;
235
- PHYSICAL_COEF = SensorManager.GRAVITY_EARTH // g (m/s^2)
236
- * 39.37f // inch/meter
237
- * ppi
238
- * 0.84f; // look and feel tuning
239
- */
240
- Forge.DragInfo.SCROLL_FRICTION = 0.015 * 4; // 摩擦系数
241
-
242
- Forge.DragInfo.EVENT_TYPE = {
243
- OnDown: 0,
244
- OnTap: 1,
245
- OnLongPress: 2,
246
- OnDragStart: 3,
247
- OnMoved: 4,
248
- OnDragEnd: 5,
249
- OnRelease: 6,
250
- OnFling: 7,
251
- };
252
-
253
- let count = 0;
254
- class LayoutViewBase {
255
- constructor(texture_setting, element_name) {
256
- this.TextureSetting = texture_setting;
257
- if (texture_setting) {
258
- console.error(
259
- "LayoutViewBase constructor texture_setting not undefined!"
260
- );
261
- }
262
- this._dispatchLongPress = this._dispatchLongPress.bind(this);
263
- this.Visibility = "VISIBLE";
264
- this.LayoutParams = null; // TODO: 为了节省内存,将改成按需求生成
265
- this.ParentView = null;
266
- this.ChildViews = []; // TODO: 为了节省内存,将改成按需求生成
267
- // Z-index
268
- this.zIndex = 0;
269
- this._Perspective = 0;
270
- this._PerspectiveAnchor = [0.5, 0.5];
271
- this._BackfaceVisibility = 1;
272
- this._DebugCount = ++count;
273
- this.childZIndexCount = 0; // 计数器,统计子界面中有多少个设置了index的界面,用于优化AddView时的z-index调整处理
274
- this._IsChildOfRootView = false;
275
- this._DetachFromSystemCallback = null;
276
- this.Element = null;
277
- this.InnerChildElement = null; // 例如video element
278
- if (element_name === "root") { // react root element
279
- this.Element = window.originDocument.getElementById(element_name);
280
- if (!this.Element) { // vue root element
281
- this.Element = window.originDocument.getElementById("app");
282
- }
283
- } else if (element_name === "svg" || element_name === "path") {
284
- this.Element = document.createElementNS(
285
- "http://www.w3.org/2000/svg",
286
- element_name
287
- );
288
- } else if (element_name) {
289
- this.Element = window.originDocument.createElement(element_name);
290
- this.Element.style.position = "absolute";
291
- }
292
-
293
- this.TransitionStore = {}; // div的所有transition信息,多个Transition动画会同时作用?
294
-
295
- this.TransformAnimationObj = null;
296
- this._TextureAnimationObj = null;
297
-
298
- // drag 2018/10/16(luocf), 2019/09/02(ludl)
299
- this._DragInfo = null;
300
- // drag 相关变量 2020/09/21
301
- this.DragControl = null;
302
- this._Velocity = { x: new Velocity(), y: new Velocity() };
303
- this._TouchSlopSquare = 8 * 8;
304
- this._InDragging = null;
305
- this._InLongPress = null;
306
- this._AlwaysInTapRegion = null;
307
- this._LastFocusX = null;
308
- this._LastFocusY = null;
309
- this._DownFocusX = null;
310
- this._DownFocusY = null;
311
- this._LastTimeStamp = null;
312
- this._ObjectFitTestCache = null;
313
-
314
- this._ProxyView = null;
315
-
316
- // 是否曾今挂载过rootView并拿掉了(LayoutView只能往rootView挂载一次)
317
- this.Expired = false;
318
- }
319
-
320
- Init(texture_setting) {
321
- this.ResetTexture(texture_setting);
322
- }
323
-
324
- SetElementProp(changed_props, owner_activity) {
325
- if (changed_props) {
326
- Object.keys(changed_props).forEach((name) => {
327
- switch (name) {
328
- case "jsv_enable_fade":
329
- // 启动图片加载完成后的淡出处理,PC端无效
330
- break;
331
- case "jsv_poster_on_top":
332
- // 启动海报层级提高优先级处理,PC端无效
333
- break;
334
- case "jsv_innerview": {
335
- // 加入通过ViewStore传入的LayoutView对象
336
- const view_info = Forge.sViewStore.get(changed_props[name]);
337
- if (view_info) {
338
- const proxy_view = view_info.view;
339
-
340
- // 使用本view的layout作为代理view的尺寸,并重置本view尺寸信息
341
- // 以此来解决dom的transition变化时,设置时位置style信息的传递问题
342
- if (this.LayoutParams == null) {
343
- // 避免LayoutParams为null
344
- this.ResetLayoutParams({ x: 0, y: 0, width: 0, height: 0 });
345
- }
346
- let proxy_view_lp = this.LayoutParams;
347
- this.ResetLayoutParams({ x: 0, y: 0, width: 0, height: 0 });
348
-
349
- if (proxy_view) {
350
- if (this._ProxyView === null) {
351
- this._InsertProxyLayer(proxy_view, proxy_view_lp);
352
- } else {
353
- if (proxy_view !== this._ProxyView) {
354
- console.error("Error: Can not reset proxy view");
355
- } else {
356
- // Do nothing
357
- }
358
- }
359
- }
360
- }
361
- break;
362
- }
363
- case "jsv_media_usetexture":
364
- // Video view中使用texture展示,已经被外部处理,此处不需再处理
365
- break;
366
- case "jsv_text_definition":
367
- // 设置本LayoutView以及所有子View中文字的清晰度,默认为1.0x,PC端无效
368
- break;
369
- default:
370
- Forge.LogE(`Error: View Unknown prop name=${name}`);
371
- break;
372
- }
373
- });
374
- }
375
- }
376
-
377
- InsertView(child_view, child_view_in_list, layout_params, packed_layout) {
378
- this._InsertView(child_view, child_view_in_list, layout_params, packed_layout);
379
- }
380
-
381
- AddView(child_view, layout_params, packed_layout) {
382
- this._InsertView(child_view, null, layout_params, packed_layout);
383
- }
384
-
385
- MoveChildView(child_view_to_move, target_parent, child_view_in_list) {
386
- if (this._ProxyView != null && child_view_to_move != this._ProxyView) {
387
- // 所有的 MoveChildView 操作被ProxyView代理
388
- this._ProxyView.MoveChildView(child_view_to_move, target_parent);
389
- return;
390
- }
391
-
392
- // 从原节点拿掉
393
- let found = false;
394
- for (var i = 0; i < this.ChildViews.length; i++) {
395
- if (this.ChildViews[i] == child_view_to_move) {
396
- if (child_view_to_move.zIndex != 0)
397
- this.childZIndexCount--;
398
- this.ChildViews.splice(i, 1);
399
- child_view_to_move.ParentView = null;
400
- found = true;
401
- break;
402
- }
403
- }
404
- if (!found) {
405
- Forge.LogE("MoveChildView(): view is not in child list" + " stack=");
406
- }
407
-
408
- // 移动到新节点中
409
- target_parent._InsertView(child_view_to_move, child_view_in_list, child_view_to_move.LayoutParams);
410
-
411
- // 执行HTML的element移动操作,移动后原父节点会自动删除
412
- let behind_view = null;
413
- if (child_view_in_list) {
414
- behind_view = target_parent.ChildViews[target_parent.ChildViews.indexOf(child_view_in_list) + 1];
415
- }
416
- if (behind_view && target_parent.Element.contains(behind_view.Element)) {
417
- target_parent.Element.insertBefore(child_view_to_move.Element, behind_view.Element);
418
- } else {
419
- target_parent.Element.appendChild(child_view_to_move.Element);
420
- }
421
- }
422
-
423
- _InsertView(child_view, child_view_in_list, layout_params, packed_layout) {
424
- if (layout_params) {
425
- if (!(layout_params instanceof Forge.LayoutParamsBase)) {
426
- child_view.LayoutParams = new Forge.LayoutParams(layout_params);
427
- } else {
428
- child_view.LayoutParams = layout_params.Clone();
429
- }
430
- } else {
431
- if (!child_view.LayoutParams) {
432
- child_view.LayoutParams = new Forge.LayoutParams({ x: 0, y: 0 });
433
- }
434
- }
435
-
436
- if (child_view.LayoutParams !== null) {
437
- if (child_view.LayoutParams.MarginLeft) {
438
- child_view.Element.style.left = `${child_view.LayoutParams.MarginLeft}px`;
439
- }
440
- if (child_view.LayoutParams.MarginTop) {
441
- child_view.Element.style.top = `${child_view.LayoutParams.MarginTop}px`;
442
- }
443
- if (child_view.LayoutParams.Width) {
444
- child_view.Element.style.width = `${child_view.LayoutParams.Width}px`;
445
- }
446
-
447
- if (child_view.LayoutParams.Height) {
448
- child_view.Element.style.height = `${child_view.LayoutParams.Height}px`;
449
- } else {
450
- child_view.Element.style.height = "";
451
- }
452
- }
453
-
454
- child_view.ParentView = this;
455
- if (child_view_in_list) {
456
- // 插入模式(插到目标view之前)
457
- let found_idx = this.ChildViews.indexOf(child_view_in_list);
458
- if (found_idx < 0) {
459
- found_idx = this.ChildViews.length; // 默认追加到最后
460
- }
461
- this.ChildViews.splice(found_idx, 0, child_view);
462
- } else {
463
- // 非插入形式
464
- this.ChildViews.push(child_view);
465
- }
466
- this._ChildrenListDirty = true;
467
-
468
- if (this._IsChildOfRootView) {
469
- child_view._OnAttachToSystem();
470
- }
471
- }
472
-
473
- SetZIndex(z_index) {
474
- this.Element.style.zIndex = z_index;
475
- this.zIndex = z_index;
476
- }
477
-
478
- /**
479
- * Perspective距离<br>
480
- *
481
- * hide public
482
- * @func SetPerspective
483
- * @memberof Forge.LayoutViewBase
484
- * @instance
485
- * @param {int} distance 观察点距离view的值, 最大为2^16 - 1
486
- * */
487
- SetPerspective(distance, origin) {
488
- this.Element.style.perspective = `${distance}px`;
489
- this.Element.style.webkitPerspective = `${distance}px`;
490
- this.Element.style.perspectiveOrigin = origin;
491
- this.Element.style.webkitPerspectiveOrigin = origin;
492
- this._Perspective = distance;
493
- this._PerspectiveOrigin = origin;
494
- }
495
-
496
- /**
497
- * 背面是否可见<br>
498
- *
499
- * hide public
500
- * @func SetBackfaceVisibility
501
- * @memberof Forge.LayoutViewBase
502
- * @instance
503
- * @param {boolean} visible 可见性
504
- * */
505
- SetBackfaceVisibility(visible) {
506
- console.log("set back face", visible);
507
- this.Element.style.backfaceVisibility = visible ? "visible" : "hidden";
508
- this.Element.style.webkitBackfaceVisibility = visible
509
- ? "visible"
510
- : "hidden";
511
- console.log(`back face style ${this.Element.style.backfaceVisibility}`);
512
- this._BackfaceVisibility = visible ? 1 : 0;
513
- }
514
-
515
- SetTransformStyle(transform_style) {
516
- this.Element.style.transformStyle = transform_style;
517
- this.Element.style.webkitTransformStyle = transform_style;
518
- this._TransformStyle = transform_style;
519
- }
520
-
521
- EnableDivTouch(ele, setting) {
522
- if (ele.eventHandlers && ele.eventHandlers.onClick) {
523
- this.Element.onclick = (ev) => {
524
- ele.eventHandlers.onClick();
525
- if (ev.preventDefault) {
526
- ev.preventDefault();
527
- }
528
- };
529
- this.Element.style.pointerEvents = "auto";
530
- }
531
- }
532
-
533
- _DoDragPause(event) {
534
- if (this._DragInfo.Settings.EnableTabMode) {
535
- return;
536
- }
537
- if (this.DragControl) {
538
- this.DragControl.pause((view_x, view_y) => {
539
- if (this.Element.style.transform !== null) {
540
- // 对view_x, view_y进行校对
541
- let lp = this.GetLayoutParams();
542
- lp = this._GetMovedLayoutParams(
543
- view_x - lp.MarginLeft,
544
- view_y - lp.MarginTop
545
- );
546
- this.ResetLayoutParams(lp);
547
- this._DragImactSensorRecycle();
548
- console.log(
549
- `_DoDragPause lp.MarginLeft:${lp.MarginLeft}, lp.MarginTop:${lp.MarginTop}`
550
- );
551
- this.DragControl = null;
552
- this.Element.style.transform = null;
553
- // 补充event
554
- event.viewX = view_x;
555
- event.viewY = view_y;
556
-
557
- this._DragInfo.Listener.OnFling(event);
558
- }
559
- });
560
- }
561
- }
562
-
563
- TouchEventProcess(event) {
564
- // 将event type转换为字符串
565
- let event_used = false;
566
- switch (event.type) {
567
- case Forge.DragInfo.EVENT_TYPE.OnDown: {
568
- console.log("TouchEventProcess OnDown in");
569
- this._DoDragPause(event);
570
- if (this._DragInfo.Listener && this._DragInfo.Listener.OnDown) {
571
- event_used = this._DragInfo.Listener.OnDown(event);
572
- }
573
- break;
574
- }
575
- case Forge.DragInfo.EVENT_TYPE.OnTap:
576
- if (this._DragInfo.Listener && this._DragInfo.Listener.OnTap) {
577
- event_used = this._DragInfo.Listener.OnTap(event);
578
- }
579
- break;
580
- case Forge.DragInfo.EVENT_TYPE.OnLongPress:
581
- if (this._DragInfo.Listener && this._DragInfo.Listener.OnLongPress) {
582
- event_used = this._DragInfo.Listener.OnLongPress(event);
583
- }
584
- break;
585
- case Forge.DragInfo.EVENT_TYPE.OnDragStart:
586
- this._DragMovedDistanceX = 0;
587
- this._DragMovedDistanceY = 0;
588
- if (this._DragInfo.Listener && this._DragInfo.Listener.OnDragStart) {
589
- event_used = this._DragInfo.Listener.OnDragStart(event);
590
- }
591
- break;
592
- case Forge.DragInfo.EVENT_TYPE.OnMoved:
593
- if (this._DragInfo.Listener && this._DragInfo.Listener.OnMoved) {
594
- event_used = this._DoDragMove(event, true);
595
- }
596
- break;
597
- case Forge.DragInfo.EVENT_TYPE.OnDragEnd:
598
- if (this._DragInfo.Listener && this._DragInfo.Listener.OnDragEnd) {
599
- // 对应吸附性,进行动画调整
600
- const enable_tab_mode = this._SlideIfEnableTabMod(event, -1);
601
- if (enable_tab_mode) {
602
- event_used = true;
603
- } else {
604
- event_used = this._DoDragEnd(event);
605
- }
606
- }
607
- break;
608
- case Forge.DragInfo.EVENT_TYPE.OnRelease:
609
- if (this._DragInfo.Listener && this._DragInfo.Listener.OnRelease) {
610
- event_used = this._DragInfo.Listener.OnRelease(event);
611
- }
612
- break;
613
- case Forge.DragInfo.EVENT_TYPE.OnFling:
614
- if (this._DragInfo.Listener && this._DragInfo.Listener.OnFling) {
615
- const enable_tab_mode = this._SlideIfEnableTabMod(event, -1);
616
- if (enable_tab_mode) {
617
- event_used = true;
618
- } else {
619
- event_used = this._DoFling(event);
620
- }
621
- }
622
- break;
623
- default:
624
- console.log(`TouchEventProcess:${event}`);
625
- break;
626
- }
627
-
628
- return event_used;
629
- }
630
-
631
- /**
632
- * 使Drag无效
633
- * @constructor
634
- */
635
- DisableDrag() {
636
- this._DragInfo = null;
637
- }
638
-
639
- /**
640
- * 使能拖拽
641
- * @param {Forge.DragSetting} setting 拖拽设置
642
- * @param {Object} listener 拖拽事件 listener Event事件:
643
- * OnDragEnd:{viewX:0,viewY:0},
644
- * OnMoved:{deltaX:0,deltaY:0},
645
- * Other:{x:0,y:0}//点击位置,相对于屏幕的绝对坐标
646
- * @param {String} movement_formula 移动公式
647
- * @constructor
648
- */
649
- EnableDrag(setting, listener, movement_formula) {
650
- if (!(setting instanceof Forge.DragSetting)) {
651
- Forge.ThrowError("EnableDrag The setting is not Forge.DragSetting");
652
- }
653
- if (listener === null) {
654
- Forge.ThrowError("EnableDrag The listener is null");
655
- }
656
-
657
- const drag_info = new Forge.DragInfo();
658
- drag_info.Settings = setting;
659
- drag_info.SetListener(listener);
660
- drag_info.Formula = movement_formula;
661
- this._DragInfo = drag_info;
662
- this.DragControl = null;
663
-
664
- // 追加事件监听
665
- this._AddEventListener();
666
- Forge.sRenderBridge.RequestSwap();
667
- }
668
-
669
- RemoveView(child_view_to_remove) {
670
- for (let i = 0; i < this.ChildViews.length; i++) {
671
- if (this.ChildViews[i] === child_view_to_remove) {
672
- if (child_view_to_remove.IsChildOfRootView()) {
673
- child_view_to_remove._OnDetachFromSystem();
674
- }
675
- this.ChildViews.splice(i, 1);
676
- child_view_to_remove.ParentView = null;
677
- break;
678
- }
679
- }
680
- }
681
-
682
- _OnDetachFromSystem() {
683
- this._IsChildOfRootView = false;
684
- if (this._DetachFromSystemCallback) {
685
- this._DetachFromSystemCallback.some((o, i, arr) => {
686
- o();
687
- });
688
- this._DetachFromSystemCallback = null; // 执行完毕要清理
689
- } else {
690
- this.OnDettachFromSystem();
691
- }
692
- for (let i = 0; i < this.ChildViews.length; i++) {
693
- const child_view = this.ChildViews[i];
694
- child_view._OnDetachFromSystem();
695
- }
696
- this.ParentView.Element.removeChild(this.Element);
697
-
698
- this._releaseViewResources();
699
- }
700
-
701
- RegisterDetachCallback(callback) {
702
- if (callback) {
703
- if (this._DetachFromSystemCallback == null) {
704
- this._DetachFromSystemCallback = [];
705
- }
706
- this._DetachFromSystemCallback.push(callback);
707
- }
708
- }
709
-
710
- UnregisterDetachCallback(callback) {
711
- if (callback && this._DetachFromSystemCallback) {
712
- let found = false;
713
- let arr = this._DetachFromSystemCallback;
714
- for (let i = 0; i < arr.length; i++) {
715
- if (arr[i] === callback) {
716
- arr.splice(i, 1);
717
- found = true;
718
- break;
719
- }
720
- }
721
- if (!found) {
722
- console.error("no found");
723
- } else {
724
- if (arr.length == 0) {
725
- this._DetachFromSystemCallback = null; // 清理内存
726
- }
727
- }
728
- } else {
729
- console.error("Unregister nothing...");
730
- }
731
- }
732
-
733
- /**
734
- * 按需重载的回调函数
735
- *
736
- * @public
737
- * @func OnDettachFromSystem
738
- * @memberof Forge.LayoutViewBase
739
- * @instance
740
- * */
741
- OnDettachFromSystem() {
742
- // Override if needed
743
- }
744
-
745
- _releaseViewResources() {
746
- if (!this.Expired) {
747
- // Stop animation
748
- this.StopAnimation();
749
- this.StopTextureAnimation();
750
- this.Expired = true;
751
- }
752
- }
753
-
754
- ClearViews() {
755
- const child_count = this.ChildViews.length;
756
- if (child_count === 0) {
757
- return;
758
- }
759
- for (let i = 0; i < child_count; i++) {
760
- const child_view = this.ChildViews[i];
761
- if (child_view && child_view.IsChildOfRootView()) {
762
- child_view._OnDetachFromSystem();
763
- }
764
- }
765
-
766
- this.ChildViews = [];
767
- }
768
-
769
- _ResetTextStyle(resource_info) {
770
- this.Element.style.overflow = "hidden";
771
-
772
- // Get all style from id
773
- // display style
774
- let ds_describe = Forge.sTextStyleCache.GetDsFromId(
775
- resource_info.Set.IDS.DS
776
- ).Describe;
777
- // font style
778
- let fs_describe = Forge.sTextStyleCache.GetFsFromId(
779
- resource_info.Set.IDS.FS
780
- ).Describe;
781
- // color style
782
- let cs_describe = Forge.sTextStyleCache.GetCsFromId(
783
- resource_info.Set.IDS.CS
784
- ).Describe;
785
- // special style
786
- let ss_describe = null;
787
- if (resource_info.Set.IDS.SS !== "DISABLE") {
788
- ss_describe = Forge.sTextStyleCache.GetSsFromId(
789
- resource_info.Set.IDS.SS
790
- ).Describe;
791
- }
792
-
793
- // font
794
- this.Element.style.fontFamily = fs_describe.font;
795
- this.Element.style.fontSize = `${resource_info.Set.FS}px`;
796
- if (fs_describe.italic) {
797
- this.Element.style.fontStyle = "italic";
798
- }
799
- if (fs_describe.bold) {
800
- this.Element.style.fontWeight = "bold";
801
- } else {
802
- this.Element.style.fontWeight = "normal";
803
- }
804
- this.Element.style.textOverflow = ds_describe.text_overflow;
805
- this.Element.style.wordBreak = "normal";
806
-
807
- // word wrap
808
- let word_wrap = ds_describe.word_wrap;
809
- if (word_wrap === "none") {
810
- this.Element.style.whiteSpace = "nowrap";
811
- } else if (word_wrap) {
812
- this.Element.style.wordWrap = word_wrap.replace("_", "-");
813
- }
814
-
815
- // align
816
- this.Element.style.textAlign = ds_describe.alignment;
817
- this.Element.style.verticalAlign = ds_describe.vertical_area_align; // 配合高阶控件区域居中设置
818
-
819
- //direction
820
- this.Element.style.direction = ds_describe.direction;
821
-
822
- // color
823
- let text_color = cs_describe.text_color;
824
- if (text_color.startsWith("#") && text_color.length === 9) {
825
- // #AARRGGBB -> #RRGGBB
826
- text_color = "#" + text_color.substr(3, 6);
827
- }
828
- this.Element.style.color = text_color;
829
- let bg_color = cs_describe.bg_color;
830
- let opacity = false;
831
- if (bg_color.startsWith("#") && bg_color.length === 9) {
832
- // #AARRGGBB -> #RRGGBB
833
- opacity = bg_color.startsWith("#00");
834
- bg_color = "#" + bg_color.substr(3, 6);
835
- }
836
- if (!opacity) {
837
- this.Element.style.backgroundColor = bg_color;
838
- }
839
-
840
- if (ss_describe) {
841
- // Text shadow
842
- if (ss_describe.shadow_blur > 0) {
843
- this.Element.style.textShadow = `${ss_describe.shadow_offset_x}px ${ss_describe.shadow_offset_y}px ${ss_describe.shadow_blur}px ${ss_describe.shadow_color}`
844
- }
845
-
846
- // Text stroke
847
- if (ss_describe.stroke_width > 0) {
848
- this.Element.style.WebkitTextStroke = `${ss_describe.stroke_width}px ${ss_describe.stroke_color}`;
849
- }
850
- }
851
-
852
- // 显示width x height
853
- this.Element.style.width = `${resource_info.Set.W}px`;
854
- this.Element.style.height = `${resource_info.Set.H}px`;
855
-
856
- // line height
857
- if (resource_info.Set.LH) {
858
- this.Element.style.lineHeight = `${resource_info.Set.LH}px`;
859
- }
860
-
861
- if (resource_info.Set.EA) {
862
- let emptyRect = resource_info.Set.EA;
863
- let div = window.originDocument.createElement("div");
864
- div.style.float = emptyRect.x > 0 ? "right" : "left";
865
- div.style.width = emptyRect.w + "px";
866
- // -1, 是因为网页端会多影响一行
867
- div.style.height = emptyRect.h - 1 + "px";
868
- div.style.backgroundColor = "rgba(0,0,0,0)";
869
- div.style.position = "relative";
870
- this.Element.appendChild(div);
871
- }
872
-
873
- if (resource_info.Set.LA) {
874
- // latex文本
875
- const node_info = parseLatex(resource_info.Set.ST);
876
- toHtml(this.Element, node_info);
877
- } else {
878
- let textDiv = window.originDocument.createElement("span");
879
- textDiv.textContent = resource_info.Set.ST;
880
- this.Element.appendChild(textDiv);
881
- }
882
- }
883
-
884
- _SetBorderRadius(mask_setting) {
885
- const target_element = this.InnerChildElement
886
- ? this.InnerChildElement
887
- : this.Element;
888
- target_element.style.borderRadius = `${mask_setting._TopLeft}px ${mask_setting._TopRight}px ${mask_setting._BottomRight}px ${mask_setting._BottomLeft}px`;
889
- }
890
-
891
- // 将本View的所有子节点都移动到Proxy层中
892
- _InsertProxyLayer(proxy_view, layout_params) {
893
- proxy_view.ParentView = this;
894
-
895
- // ParentView绑定后, 执行Proxy View 往RootView上的绑定操作
896
- if (this._IsChildOfRootView) {
897
- // 步骤1: 当前view所有子 depth + 1(因为插入了新层次proxyView)
898
- for (let children_view of this.ChildViews) {
899
- children_view._AdvanceDepthForProxyLayer();
900
- }
901
-
902
- // 步骤2: proxy加入rootView树中
903
- proxy_view._OnAttachToSystem();
904
- }
905
-
906
- // 将此View Child合并到proxyView的Child中
907
- proxy_view.ChildViews = proxy_view.ChildViews.concat(this.ChildViews);
908
- proxy_view._ChildrenListDirty = true;
909
- for (let i = 0; i < proxy_view.ChildViews.length; i++) {
910
- proxy_view.ChildViews[i].ParentView = proxy_view;
911
- proxy_view._RequestLayoutForAddingView(proxy_view.ChildViews[i]);
912
- }
913
-
914
- // 应用Layout params
915
- if (layout_params !== null) {
916
- if (!(layout_params instanceof Forge.LayoutParamsBase)) {
917
- proxy_view.LayoutParams = new Forge.LayoutParams(layout_params);
918
- } else {
919
- proxy_view.LayoutParams = layout_params.Clone();
920
- }
921
- } else {
922
- if (proxy_view.LayoutParams === null) {
923
- proxy_view.LayoutParams = new Forge.LayoutParams({ x: 0, y: 0 });
924
- }
925
- }
926
- // 设置element 属性
927
- proxy_view.ResetLayoutParams(proxy_view.LayoutParams);
928
-
929
- // 重置原节点的ChildViews
930
- this.ChildViews = [proxy_view];
931
- this._ChildrenListDirty = true;
932
- this._RequestLayoutForAddingView(proxy_view);
933
-
934
- // 关联ProxyView
935
- this._ProxyView = proxy_view;
936
- // Poster on top关系不需要重建
937
-
938
- // 将子view追加到父view上
939
- if (this._IsChildOfRootView) {
940
- proxy_view._OnAttachToSystem();
941
- }
942
- }
943
-
944
- _RequestLayoutForAddingView(child_view) {
945
- this._RequestLayout();
946
- }
947
-
948
- /**
949
- * 设置新的Texture集合
950
- *
951
- * @public
952
- * @func ResetTexture
953
- * @memberof Forge.LayoutViewBase
954
- * @instance
955
- * @param {Forge.TextureSetting} texture_setting 新的Texture集合
956
- * */
957
- ResetTexture(texture_setting) {
958
- this.TextureSetting = texture_setting;
959
- if (texture_setting) {
960
- if (texture_setting.Texture.Source) {
961
- if (this.Element.tagName === "IMG") {
962
- // 图片元素,设置url到src中
963
- this.Element.src = texture_setting.Texture.Source;
964
- } else {
965
- this.Element.style.backgroundImage = `url(${texture_setting.Texture.Source})`;
966
- this.Element.style.backgroundSize = "100% 100%";
967
- }
968
- } else if (texture_setting.Texture.Gradient) {
969
- this.Element.style.backgroundImage = texture_setting.Texture.Gradient;
970
- } else if (
971
- texture_setting.Texture.RenderTexture &&
972
- texture_setting.Texture.RenderTexture._SyncingResourceInfo
973
- ) {
974
- const render_texture = texture_setting.Texture.RenderTexture;
975
- const resource_info = render_texture._SyncingResourceInfo;
976
- if (resource_info.Nam === "TST") {
977
- this._ResetTextStyle(resource_info);
978
- } else if (resource_info.Nam === "CT") {
979
- this.Element.style.backgroundColor = resource_info.Set.Clr;
980
- } else if (resource_info.Nam === "VPLY") {
981
- const video_el = resource_info.Set.Hdl;
982
-
983
- // 在Forge html状态,video的显示尺寸由父元素决定
984
- video_el.style.width = "100%";
985
- video_el.style.height = "100%";
986
- video_el.style.objectFit = "fill";
987
-
988
- this.Element.appendChild(video_el);
989
- this.InnerChildElement = video_el;
990
- }
991
- }
992
-
993
- if (texture_setting.MaskSetting) {
994
- if (texture_setting.MaskSetting._MaskType === "CORNER") {
995
- this._SetBorderRadius(texture_setting.MaskSetting);
996
- }
997
- }
998
- } else {
999
- this.Element.style.backgroundColor = ""
1000
- this.Element.style.backgroundImage = "";
1001
- this.Element.style.borderRadius = "";
1002
- }
1003
- }
1004
-
1005
- SetVisibility(new_visibility) {
1006
- if (typeof new_visibility === "string") {
1007
- this.Element.style.visibility = new_visibility.toLocaleLowerCase();
1008
- } else {
1009
- this.Element.style.visibility = "inherit";
1010
- }
1011
- }
1012
-
1013
- _OnAttachToSystem() {
1014
- if (this.Element.id === "svg" || this.Element.id === "path") {
1015
- console.log("_OnAttachToSystem appendChild");
1016
- }
1017
-
1018
- // 进行Element插入操作
1019
- let behind_view = this.ParentView.ChildViews[this.ParentView.ChildViews.indexOf(this) + 1];
1020
- if (behind_view && this.ParentView.Element.contains(behind_view.Element)) {
1021
- this.ParentView.Element.insertBefore(this.Element, behind_view.Element);
1022
- } else {
1023
- this.ParentView.Element.appendChild(this.Element);
1024
- }
1025
-
1026
- this._IsChildOfRootView = true;
1027
- const child_view_list = this.ChildViews;
1028
- let child_view;
1029
- for (let i = 0; i < child_view_list.length; i++) {
1030
- child_view = child_view_list[i];
1031
- child_view._OnAttachToSystem();
1032
- }
1033
- }
1034
-
1035
- IsChildOfRootView() {
1036
- return this._IsChildOfRootView;
1037
- }
1038
-
1039
- StartAnimation(anim, anim_for_self, delay) {
1040
- if (
1041
- typeof this.TransformAnimationObj !== "undefined" &&
1042
- this.TransformAnimationObj
1043
- ) {
1044
- this.TransformAnimationObj.Cancel(anim);
1045
- this.TransformAnimationObj = null;
1046
- if (!window.jsvInAndroidWebView) {
1047
- this.Element.style.animation = null;
1048
- } else {
1049
- this.Element.style.webkitAnimation = null;
1050
- }
1051
- }
1052
-
1053
- // 动画事件转发给proxyView,本体不做,用于解决inner-view的css-transition和css-animation不容易设置的问题
1054
- // 注意点:放在Animation cancel之后,以防本view有原始动画(不过理论上不会有)
1055
- if (this._ProxyView != null) {
1056
- this._ProxyView.StartAnimation(anim, anim_for_self, delay);
1057
- return;
1058
- }
1059
-
1060
- this.TransformAnimationObj = anim;
1061
- if (!isNaN(delay) && delay > 0) {
1062
- anim.EnableDelay(delay);
1063
- }
1064
- anim.Start(this);
1065
- }
1066
-
1067
- ApplyStyleTransition(new_map) {
1068
- this.TransitionStore = { ...this.TransitionStore, ...new_map };
1069
- let transitions = "";
1070
- Object.values(this.TransitionStore).forEach((value) => {
1071
- if (transitions) {
1072
- transitions += ",";
1073
- }
1074
- transitions += value;
1075
- });
1076
- if (!window.jsvInAndroidWebView) {
1077
- this.Element.style.transition = transitions;
1078
- } else {
1079
- this.Element.style.webkitTransition = transitions;
1080
- }
1081
- }
1082
-
1083
- /**
1084
- * 停止这个LayoutView的动画变换,并重置曾经进行动画变换的矩阵
1085
- *
1086
- * @public
1087
- * @func StopAnimation
1088
- * @memberof Forge.LayoutViewBase
1089
- * @instance
1090
- * */
1091
- StopAnimation() {
1092
- if (
1093
- typeof this.TransformAnimationObj !== "undefined" &&
1094
- this.TransformAnimationObj
1095
- ) {
1096
- this.TransformAnimationObj.Cancel();
1097
- this.TransformAnimationObj = null;
1098
- // 状态将在Animation触发的DetachAnimation中恢复,不需要在此手动恢复
1099
- }
1100
-
1101
- // 动画事件转发给proxyView,本体不做,用于解决inner-view的css-transition和css-animation不容易设置的问题
1102
- // 注意点:放在Animation cancel之后,以防本view有原始动画(不过理论上不会有)
1103
- if (this._ProxyView != null) {
1104
- this._ProxyView.StopAnimation();
1105
- return;
1106
- }
1107
- }
1108
-
1109
- /**
1110
- * 对这个LayoutView开始进行Texture动画变换(相对于view自身)
1111
- *
1112
- * @public
1113
- * @func StartTextureAnimation
1114
- * @memberof Forge.LayoutViewBase
1115
- * @instance
1116
- * @param {Forge.AnimationBase} anim 动画设置,例如通过new Forge.TranslateAnimation()创建
1117
- * */
1118
- StartTextureAnimation(anim) {
1119
- if (
1120
- typeof this._TextureAnimationObj !== "undefined" &&
1121
- this._TextureAnimationObj
1122
- ) {
1123
- this._TextureAnimationObj.Cancel(anim);
1124
- this._TextureAnimationObj = null;
1125
- }
1126
- this._TextureAnimationObj = anim;
1127
- anim.AsTextureAnimation();
1128
- anim.Start(this);
1129
- this._RequestLayout();
1130
- }
1131
-
1132
- _RequestLayout() { }
1133
-
1134
- /**
1135
- * 停止这个LayoutView中的Texture的动画变换,并重置曾经进行动画变换的矩阵
1136
- *
1137
- * @public
1138
- * @func StopAnimation
1139
- * @memberof Forge.LayoutViewBase
1140
- * @instance
1141
- * */
1142
- StopTextureAnimation() {
1143
- if (
1144
- typeof this._TextureAnimationObj !== "undefined" &&
1145
- this._TextureAnimationObj
1146
- ) {
1147
- this._TextureAnimationObj.Cancel();
1148
- this._TextureAnimationObj = null;
1149
- }
1150
- }
1151
-
1152
- /**
1153
- * 停止该LayoutView和其所有子LayoutView的动画,并重置曾经进行动画变换的矩阵
1154
- *
1155
- * @public
1156
- * @func StopAllAnimations
1157
- * @memberof Forge.LayoutViewBase
1158
- * @instance
1159
- * */
1160
- StopAllAnimations() {
1161
- this.StopAnimation();
1162
- this.StopTextureAnimation();
1163
- for (let i = 0; i < this.ChildViews.length; i++) {
1164
- this.ChildViews[i].StopAllAnimations();
1165
- }
1166
- }
1167
-
1168
- /**
1169
- * 获得正在进行动的动画的句柄
1170
- *
1171
- * @public
1172
- * @func GetAnimation
1173
- * @memberof Forge.LayoutViewBase
1174
- * @instance
1175
- * @return {Forge.AnimationBase}
1176
- * */
1177
- GetAnimation() {
1178
- return this.TransformAnimationObj;
1179
- }
1180
-
1181
- /**
1182
- * 移除动画设置。<br>
1183
- * 架构内部函数,应只能被Forge.AnimationBase调用
1184
- *
1185
- * @func DetachAnimation
1186
- * @memberof Forge.LayoutViewBase
1187
- * @instance
1188
- * @param {Forge.AnimationBase} anim 要移除的动画
1189
- * */
1190
- DetachAnimation(anim) {
1191
- if (this.TransformAnimationObj === anim) {
1192
- this.TransformAnimationObj = null;
1193
-
1194
- if (!window.jsvInAndroidWebView) {
1195
- this.Element.style.animation = null;
1196
- this.Element.style.transition = null;
1197
- } else {
1198
- this.Element.style.webkitAnimation = null;
1199
- this.Element.style.webkitTransition = null;
1200
- }
1201
- }
1202
- }
1203
-
1204
- ResetCssTransform(transform_string, transform_origin_string) {
1205
- if (
1206
- transform_string !== this._CssTransform ||
1207
- transform_origin_string !== this._CssTransformOrigin
1208
- ) {
1209
- // console.log("ResetCssTransform transform_string:", transform_string);
1210
- if (!window.jsvInAndroidWebView) {
1211
- this.Element.style.transform = transform_string;
1212
- this.Element.style.transformOrigin = transform_origin_string;
1213
- } else {
1214
- this.Element.style.webkitTransform = transform_string;
1215
- this.Element.style.webkitTransformOrigin = transform_origin_string;
1216
- }
1217
-
1218
- this._CssTransform = transform_string;
1219
- this._CssTransformOrigin = transform_origin_string;
1220
- }
1221
- }
1222
-
1223
- ResetTextureCssTransform(transform_string, transform_origin_string) {
1224
- this.ResetCssTransform(transform_string, transform_origin_string);
1225
- }
1226
-
1227
- /** **************************************
1228
- * View getter
1229
- */
1230
- SetId(id) {
1231
- this.Id = id;
1232
- }
1233
-
1234
- ResetLayoutParams(new_params) {
1235
- if (this._ProxyView != null) {
1236
- // 由ProxyView代理原view的尺寸变化设置, 解决transiton动画问题
1237
- this._ProxyView.ResetLayoutParams(new_params);
1238
- return;
1239
- }
1240
-
1241
- if (new_params !== null) {
1242
- if (!(new_params instanceof Forge.LayoutParamsBase)) {
1243
- this.LayoutParams = new Forge.LayoutParams(new_params);
1244
- } else {
1245
- this.LayoutParams = new_params.Clone();
1246
- }
1247
- this.Element.style.left = `${this.LayoutParams.MarginLeft}px`;
1248
- this.Element.style.top = `${this.LayoutParams.MarginTop}px`;
1249
- if (this.LayoutParams.Width) {
1250
- this.Element.style.width = `${this.LayoutParams.Width}px`;
1251
- }
1252
- if (this.LayoutParams.Height) {
1253
- this.Element.style.height = `${this.LayoutParams.Height}px`;
1254
- }
1255
- } else {
1256
- Forge.ThrowError("ResetLayoutParams(): new params is null");
1257
- }
1258
- }
1259
-
1260
- /**
1261
- * 获得关联的Forge.Renderer
1262
- *
1263
- * hide public
1264
- * @func GetRenderer
1265
- * @memberof Forge.LayoutViewBase
1266
- * @instance
1267
- * @return {Forge.Renderer}
1268
- * */
1269
- GetRenderer() {
1270
- return Forge.LayoutViewBase.sRenderer;
1271
- }
1272
-
1273
- /**
1274
- * 获得当前布局配置的拷贝
1275
- *
1276
- * @public
1277
- * @func GetLayoutParams
1278
- * @memberof Forge.LayoutViewBase
1279
- * @instance
1280
- * @return {Forge.LayoutParams}
1281
- * */
1282
- GetLayoutParams() {
1283
- if (!this.LayoutParams) {
1284
- return new Forge.LayoutParams();
1285
- }
1286
- return this.LayoutParams.Clone();
1287
- }
1288
-
1289
- /**
1290
- * 启用自适应高度
1291
- *
1292
- * @public
1293
- * @func EnableAutoHeight
1294
- * @memberof Forge.LayoutViewBase
1295
- * @instance
1296
- * */
1297
- EnableAutoHeight() {
1298
- this._AutoHeight = true;
1299
- }
1300
-
1301
- // 功能: 标识本LayoutView要根据自身Texture加载完成后,根据Texture的尺寸重新Resize
1302
- // 当enable后,无论尺寸设成多少,同步给Native的界面尺寸都会固定为(1,1),
1303
- // 以保证View会被渲染,从而防止Texture由于不在界面上不会加载的处理生效,同时小尺寸不会被注意
1304
- // JsView根据这个信息判断是否在屏幕内,而决定是否进行加载(屏幕外内容不加载以节省内存)
1305
- WaitTextureToResize(enable) {
1306
- // js模式下为控制显示和隐藏
1307
- // 这边控制显隐会导致用户端设置ninepatch为隐藏时,这边将其显示
1308
- // this.Element.style.visibility = enable ? "hidden" : "visible";
1309
- }
1310
-
1311
- // 根据object fit,调整texture在view中的显示位置
1312
- // 当view的宽/高,单项为0时,可以进行内容的自适应扩展
1313
- ApplyObjectFit(
1314
- frame_width,
1315
- frame_height,
1316
- texture_width,
1317
- texture_height,
1318
- object_fit,
1319
- object_fit_define
1320
- ) {
1321
- if (this._ObjectFitTestCache === null) {
1322
- // 创建检测结果的缓存,用于加快检测速度
1323
- this._ObjectFitTestCache = {
1324
- frameWidth: NaN,
1325
- frameHeight: NaN,
1326
- textureWidth: NaN,
1327
- textureHeight: NaN,
1328
- objectFit: null,
1329
- clipLayout: null,
1330
- };
1331
- }
1332
-
1333
- const test_cache = this._ObjectFitTestCache;
1334
-
1335
- if (
1336
- test_cache.frameWidth === frame_width &&
1337
- test_cache.objectFit === object_fit &&
1338
- test_cache.frameHeight === frame_height &&
1339
- test_cache.textureWidth === texture_width &&
1340
- test_cache.textureHeight === texture_height
1341
- ) {
1342
- return test_cache.clipLayout;
1343
- }
1344
-
1345
- const clip_layout = {
1346
- x: 0,
1347
- y: 0,
1348
- width: frame_width,
1349
- height: frame_height,
1350
- overflow: false,
1351
- };
1352
-
1353
- // Flush cache, 放在判断处理调整viewSize之前进行cache
1354
- test_cache.frameWidth = frame_width;
1355
- test_cache.frameHeight = frame_height;
1356
- test_cache.textureWidth = texture_width;
1357
- test_cache.textureHeight = texture_height;
1358
- test_cache.objectFit = object_fit;
1359
- test_cache.clipLayout = clip_layout;
1360
-
1361
- let expect_size = { width: 0, height: 0 };
1362
-
1363
- let frame_ratio = frame_width / frame_height;
1364
- const texture_ratio = texture_width / texture_height;
1365
-
1366
- if (!texture_ratio) {
1367
- console.warn("Warning:Texture size is 0!")
1368
- return clip_layout;
1369
- }
1370
-
1371
- if (frame_width === 0 || frame_height === 0) {
1372
- if (frame_width === 0 && frame_height === 0) {
1373
- // frame没有size的场合
1374
- return clip_layout;
1375
- }
1376
-
1377
- // 调整frame width 和 frame height,并计算新的frame ratio
1378
- if (frame_width === 0) {
1379
- frame_width = frame_height * texture_ratio;
1380
- } else {
1381
- // frame height === 0
1382
- frame_height = frame_width / texture_ratio;
1383
- }
1384
- frame_ratio = frame_width / frame_height;
1385
- }
1386
-
1387
- let object_fit_str = "";
1388
-
1389
- switch (object_fit) {
1390
- case object_fit_define.FILL:
1391
- expect_size.width = frame_width;
1392
- expect_size.height = frame_height;
1393
- object_fit_str = "fill";
1394
- break;
1395
- case object_fit_define.NONE:
1396
- expect_size.width = texture_width;
1397
- expect_size.height = texture_height;
1398
- object_fit_str = "none";
1399
- break;
1400
- case object_fit_define.COVER:
1401
- expect_size = this._StretchSize(
1402
- frame_width,
1403
- frame_height,
1404
- texture_ratio,
1405
- texture_ratio < frame_ratio
1406
- );
1407
- object_fit_str = "cover";
1408
- break;
1409
- case object_fit_define.SCALEDOWN: {
1410
- // 使用contain和none之间尺寸小的一个。
1411
- let refer_width = texture_ratio > frame_ratio; // use object-fit.contain
1412
- if (frame_width > texture_width && frame_height > texture_height) {
1413
- // use object-fit.none
1414
- refer_width = texture_ratio < frame_ratio; // use object-fit.contain
1415
- }
1416
- expect_size = this._StretchSize(
1417
- frame_width,
1418
- frame_height,
1419
- texture_ratio,
1420
- refer_width
1421
- );
1422
- object_fit_str = "scaledown";
1423
- break;
1424
- }
1425
- case object_fit_define.CONTAIN:
1426
- expect_size = this._StretchSize(
1427
- frame_width,
1428
- frame_height,
1429
- texture_ratio,
1430
- texture_ratio > frame_ratio
1431
- );
1432
- // console.warn("Element.JsvFitViewLayout() expect_size=" + JSON.stringify(expect_size));
1433
- object_fit_str = "contain";
1434
- break;
1435
- default:
1436
- throw new Error("Unexpected object-fit.");
1437
- }
1438
-
1439
- // format expect size
1440
- expect_size.width = Math.floor(expect_size.width);
1441
- expect_size.height = Math.floor(expect_size.height);
1442
-
1443
- // 计算可视区域
1444
- clip_layout.width = Math.min(expect_size.width, frame_width);
1445
- clip_layout.height = Math.min(expect_size.height, frame_height);
1446
- clip_layout.x = Math.floor((frame_width - clip_layout.width) / 2);
1447
- clip_layout.y = Math.floor((frame_height - clip_layout.height) / 2);
1448
- clip_layout.overflow =
1449
- expect_size.width > frame_width || expect_size.height > frame_height;
1450
-
1451
- // element设置object fit
1452
- const target_ele = this.InnerChildElement
1453
- ? this.InnerChildElement
1454
- : this.Element;
1455
- target_ele.style.width = `${frame_width}px`;
1456
- target_ele.style.height = `${frame_height}px`;
1457
- target_ele.style.objectFit = object_fit_str;
1458
-
1459
- return clip_layout;
1460
- }
1461
-
1462
- _StretchSize(origin_width, origin_height, ratio, refer_width) {
1463
- const stretchSize = { width: 0, height: 0 };
1464
-
1465
- if (refer_width) {
1466
- stretchSize.width = origin_width;
1467
- stretchSize.height = origin_width / ratio;
1468
- } else {
1469
- stretchSize.height = origin_height;
1470
- stretchSize.width = origin_height * ratio;
1471
- }
1472
-
1473
- return stretchSize;
1474
- }
1475
-
1476
- /**
1477
- * 注意:改坐标计算过程中,只通过LayoutParams进行计算,不计算变形矩阵
1478
- *
1479
- * @func GetPositionOffset
1480
- * @memberof Forge.LayoutViewBase
1481
- * @instance
1482
- * @param {Forge.LayoutViewBase} target_parent Offset测试目标父节点的LayoutView
1483
- * @return {Forge.Coordinate} 坐标值
1484
- * */
1485
- GetPositionOffset(target_parent) {
1486
- let test_view = this;
1487
- let x_offset = 0;
1488
- let y_offset = 0;
1489
- while (target_parent !== test_view) {
1490
- x_offset += test_view.LayoutParams
1491
- ? test_view.LayoutParams.MarginLeft
1492
- : 0;
1493
- y_offset += test_view.LayoutParams ? test_view.LayoutParams.MarginTop : 0;
1494
- test_view = test_view.ParentView;
1495
- if (!test_view)
1496
- Forge.ThrowError(
1497
- "ERROR: Target parent layoutview is not found in LayoutView tree"
1498
- );
1499
- }
1500
- return new Forge.Coordinate(x_offset, y_offset);
1501
- }
1502
-
1503
- _dispatchLongPress() {
1504
- this._LongPressDelayRequestTaskId = 0;
1505
- this._InLongPress = true;
1506
- const target_event = {
1507
- type: Forge.DragInfo.EVENT_TYPE.OnLongPress,
1508
- x: this._CurrentDownEvent.designX,
1509
- y: this._CurrentDownEvent.designY,
1510
- };
1511
- this.TouchEventProcess(target_event);
1512
- }
1513
-
1514
- _onMouseDown(designX, designY, timeStamp) {
1515
- // reset velocity
1516
- this._Velocity.x.reset();
1517
- this._Velocity.y.reset();
1518
- this._Velocity.x.updatePosition(designX);
1519
- this._Velocity.y.updatePosition(designY);
1520
- this._LastFocusX = designX;
1521
- this._DownFocusX = this._LastFocusX;
1522
- this._LastFocusY = designY;
1523
- this._DownFocusY = this._LastFocusY;
1524
- this._CurrentDownEvent = { designX, designY, timeStamp };
1525
- this._AlwaysInTapRegion = true;
1526
-
1527
- // 重置long press状态
1528
- this._InLongPress = false;
1529
- if (this._LongPressDelayRequestTaskId !== 0) {
1530
- clearTimeout(this._LongPressDelayRequestTaskId);
1531
- this._LongPressDelayRequestTaskId = 0;
1532
- }
1533
-
1534
- this._LongPressDelayRequestTaskId = setTimeout(
1535
- this._dispatchLongPress,
1536
- 600
1537
- );
1538
- const target_event = {
1539
- type: Forge.DragInfo.EVENT_TYPE.OnDown,
1540
- x: designX,
1541
- y: designY,
1542
- deltaX: 0,
1543
- deltaY: 0,
1544
- };
1545
- return target_event;
1546
- }
1547
-
1548
- _onMouseMove(designX, designY, timeStamp) {
1549
- if (!this._CurrentDownEvent) {
1550
- return null;
1551
- }
1552
- this._Velocity.x.updatePosition(designX);
1553
- this._Velocity.y.updatePosition(designY);
1554
- const deltaX = parseInt(designX - this._LastFocusX, 10);
1555
- const deltaY = parseInt(designY - this._LastFocusY, 10);
1556
- const distanceX = parseInt(designX - this._DownFocusX, 10);
1557
- const distanceY = parseInt(designY - this._DownFocusY, 10);
1558
- let target_event = null;
1559
- if (this._AlwaysInTapRegion) {
1560
- const distance = distanceX * distanceX + distanceY * distanceY;
1561
- const slopSquare = this._TouchSlopSquare;
1562
- if (distance > slopSquare) {
1563
- target_event = {
1564
- type: Forge.DragInfo.EVENT_TYPE.OnDragStart,
1565
- x: designX,
1566
- y: designY,
1567
- };
1568
- this._LastFocusX = designX;
1569
- this._LastFocusY = designY;
1570
- this._LastTimeStamp = timeStamp;
1571
- this._AlwaysInTapRegion = false; // 状态从Tap恢复到DragStart
1572
- this._InLongPress = false; // 状态从LongPress恢复到DragStart
1573
- this._InDragging = true; // 进入DragMove状态
1574
- if (this._LongPressDelayRequestTaskId !== 0) {
1575
- clearTimeout(this._LongPressDelayRequestTaskId);
1576
- this._LongPressDelayRequestTaskId = 0;
1577
- }
1578
- }
1579
- } else if (
1580
- this._InDragging &&
1581
- (Math.abs(deltaX) >= 1 || Math.abs(deltaY) >= 1)
1582
- ) {
1583
- target_event = {
1584
- type: Forge.DragInfo.EVENT_TYPE.OnMoved,
1585
- x: designX,
1586
- y: designY,
1587
- deltaX: distanceX, // 匹配jsview touch 返回值
1588
- deltaY: distanceY,
1589
- _deltaX: deltaX, // 内部使用
1590
- _deltaY: deltaY,
1591
-
1592
- timeStamp: parseInt((this._LastTimeStamp - timeStamp) / 1000, 10),
1593
- };
1594
- this._LastFocusX = designX;
1595
- this._LastFocusY = designY;
1596
- this._LastTimeStamp = timeStamp;
1597
- }
1598
- return target_event;
1599
- }
1600
-
1601
- _onMouseUp(designX, designY, timeStamp) {
1602
- let target_event = null;
1603
- //console.log("_onMouseUp, ", this._CurrentDownEvent);
1604
- if (this._CurrentDownEvent) {
1605
- const designMap = window.Forge.DesignMap();
1606
- const screenBufferWidth = Math.floor(
1607
- designMap.displayScale * designMap.width
1608
- );
1609
- const screenBufferRatio = window.innerWidth / screenBufferWidth;
1610
- const designVelocityX =
1611
- this._Velocity.x.getVelocity() / screenBufferRatio;
1612
- const designVelocityY =
1613
- this._Velocity.y.getVelocity() / screenBufferRatio;
1614
- let distance_x = designX - this._CurrentDownEvent.designX;
1615
- let distance_y = designY - this._CurrentDownEvent.designY;
1616
- const deltaX = designX - this._LastFocusX;
1617
- const deltaY = designY - this._LastFocusY;
1618
- if (this._InLongPress) {
1619
- // 长按状态下不处理任何事件
1620
- } else if (this._AlwaysInTapRegion) {
1621
- target_event = {
1622
- type: Forge.DragInfo.EVENT_TYPE.OnTap,
1623
- x: designX,
1624
- y: designY,
1625
- velocityX: 0,
1626
- velocityY: 0,
1627
- deltaX: distance_x,
1628
- deltaY: distance_y,
1629
- _deltaX: deltaX,
1630
- _deltaY: deltaY,
1631
- };
1632
- } else {
1633
- // A fling must travel the minimum tap distance
1634
- // 一个fling最小的速度,单位:px/s 70
1635
- if (Math.abs(designVelocityY) > 70 || Math.abs(designVelocityX) > 70) {
1636
- distance_x = this._GetSplineFlingDistance(designVelocityX);
1637
- distance_y = this._GetSplineFlingDistance(designVelocityY);
1638
- target_event = {
1639
- type: Forge.DragInfo.EVENT_TYPE.OnFling,
1640
- x: designX,
1641
- y: designY,
1642
- velocityX: designVelocityX,
1643
- velocityY: designVelocityY,
1644
- deltaX: designVelocityX < 0 ? -distance_x : distance_x,
1645
- deltaY: designVelocityY < 0 ? -distance_y : distance_y,
1646
- _deltaX: deltaX,
1647
- _deltaY: deltaY,
1648
- };
1649
- } else {
1650
- target_event = {
1651
- type: Forge.DragInfo.EVENT_TYPE.OnDragEnd,
1652
- x: designX,
1653
- y: designY,
1654
- deltaX: distance_x,
1655
- deltaY: distance_y,
1656
- _deltaX: deltaX,
1657
- _deltaY: deltaY,
1658
- };
1659
- }
1660
- this.TouchEventProcess(target_event);
1661
- // Release
1662
- target_event = {
1663
- type: Forge.DragInfo.EVENT_TYPE.OnRelease,
1664
- x: designX,
1665
- y: designY,
1666
- deltaX: distance_x,
1667
- deltaY: distance_y,
1668
- _deltaX: deltaX,
1669
- _deltaY: deltaY,
1670
- };
1671
- this._CurrentDownEvent = null;
1672
- }
1673
-
1674
- // 重置long press状态
1675
- this._InLongPress = false;
1676
- if (this._LongPressDelayRequestTaskId !== 0) {
1677
- clearTimeout(this._LongPressDelayRequestTaskId);
1678
- this._LongPressDelayRequestTaskId = 0;
1679
- }
1680
- }
1681
- return target_event;
1682
- }
1683
-
1684
- _onTouchEvent(event) {
1685
- const designMap = window.Forge.DesignMap();
1686
- const screenBufferWidth = Math.floor(
1687
- designMap.displayScale * designMap.width
1688
- );
1689
- const screenBufferRatio = window.innerWidth / screenBufferWidth;
1690
- const designX = event.clientX / screenBufferRatio;
1691
- const designY = event.clientY / screenBufferRatio;
1692
-
1693
- // 转换event
1694
- let target_event = null;
1695
- switch (event.type) {
1696
- case "touchstart":
1697
- case "mousedown": {
1698
- target_event = this._onMouseDown(designX, designY, event.timeStamp);
1699
- break;
1700
- }
1701
- case "touchmove":
1702
- case "mousemove": {
1703
- target_event = this._onMouseMove(designX, designY, event.timeStamp);
1704
- break;
1705
- }
1706
- case "touchend":
1707
- case "touchcancel":
1708
- case "mouseup": {
1709
- target_event = this._onMouseUp(designX, designY, event.timeStamp);
1710
- break;
1711
- }
1712
- default:
1713
- break;
1714
- }
1715
-
1716
- if (target_event) {
1717
- return this.TouchEventProcess(target_event);
1718
- }
1719
- return false;
1720
- }
1721
-
1722
- _AddEventListener() {
1723
- this.Element.style.pointerEvents = "auto";
1724
- this._ValidTouch = false;
1725
- const isTouch = "ontouchstart" in window;
1726
- // console.log(`isTouch:${isTouch}`);
1727
- if (isTouch) {
1728
- this.Element.addEventListener(
1729
- "touchstart",
1730
- (event) => {
1731
- console.log("touchstart", event);
1732
- this._ValidTouch = true;
1733
- if (event.touches && event.touches.length > 0) {
1734
- console.log(
1735
- `touchstart event.touches[0].clientX:${event.touches[0].clientX}, event.touches[0].clientY:${event.touches[0].clientY}`
1736
- );
1737
- const event_used = this._onTouchEvent({
1738
- type: event.type,
1739
- clientX: event.touches[0].clientX,
1740
- clientY: event.touches[0].clientY,
1741
- timeStamp: event.timeStamp,
1742
- });
1743
- if (event_used) {
1744
- event.stopPropagation();
1745
- }
1746
- }
1747
- },
1748
- true
1749
- );
1750
- this.Element.addEventListener(
1751
- "touchmove",
1752
- (event) => {
1753
- if (this._ValidTouch) {
1754
- console.log("touchmove", event);
1755
- if (event.touches && event.touches.length > 0) {
1756
- console.log(
1757
- `touchmove event.touches[0].clientX:${event.touches[0].clientX}, event.touches[0].clientY:${event.touches[0].clientY}`
1758
- );
1759
- const event_used = this._onTouchEvent({
1760
- type: event.type,
1761
- clientX: event.touches[0].clientX,
1762
- clientY: event.touches[0].clientY,
1763
- timeStamp: event.timeStamp,
1764
- });
1765
- if (event_used) {
1766
- event.stopPropagation();
1767
- }
1768
- }
1769
- }
1770
- },
1771
- true
1772
- );
1773
- this.Element.addEventListener(
1774
- "touchend",
1775
- (event) => {
1776
- console.log(
1777
- `touchend event.touches.length:${event.touches.length}, event.clientX:${event.clientX}, event.pageX:${event.pageX}`
1778
- );
1779
- this._ValidTouch = false;
1780
- if (event.changedTouches && event.changedTouches.length > 0) {
1781
- console.log(
1782
- `touchend event.changedTouches[0].clientX:${event.changedTouches[0].clientX}, event.changedTouches[0].pageX:${event.changedTouches[0].pageX}`
1783
- );
1784
- const event_used = this._onTouchEvent({
1785
- type: event.type,
1786
- clientX: event.changedTouches[0].clientX,
1787
- clientY: event.changedTouches[0].clientY,
1788
- timeStamp: event.timeStamp,
1789
- });
1790
- if (event_used) {
1791
- event.stopPropagation();
1792
- }
1793
- }
1794
- },
1795
- true
1796
- );
1797
- this.Element.addEventListener(
1798
- "touchcancel",
1799
- (event) => {
1800
- this._ValidTouch = false;
1801
- console.log("touchcancel", event);
1802
- if (event.changedTouches && event.changedTouches.length > 0) {
1803
- console.log(
1804
- `touchcancel event.clientX:${event.clientX}, event.clientY:${event.clientY}`
1805
- );
1806
- const event_used = this._onTouchEvent({
1807
- type: event.type,
1808
- clientX: event.touches[0].clientX,
1809
- clientY: event.touches[0].clientY,
1810
- timeStamp: event.timeStamp,
1811
- });
1812
- if (event_used) {
1813
- event.stopPropagation();
1814
- }
1815
- }
1816
- },
1817
- true
1818
- );
1819
- } else {
1820
- this.Element.addEventListener(
1821
- "mousedown",
1822
- (event) => {
1823
- console.log("mousedown", event);
1824
- this._ValidTouch = true;
1825
- const event_used = this._onTouchEvent(event);
1826
- if (event_used) {
1827
- event.stopPropagation();
1828
- }
1829
- },
1830
- true
1831
- );
1832
-
1833
- this.Element.addEventListener(
1834
- "mousemove",
1835
- (event) => {
1836
- if (this._ValidTouch) {
1837
- const event_used = this._onTouchEvent(event);
1838
- if (event_used) {
1839
- event.stopPropagation();
1840
- }
1841
- }
1842
- },
1843
- true
1844
- );
1845
-
1846
- this.Element.addEventListener(
1847
- "mouseup",
1848
- (event) => {
1849
- console.log("mouseup", event);
1850
- this._ValidTouch = false;
1851
- const event_used = this._onTouchEvent(event);
1852
- if (event_used) {
1853
- event.stopPropagation();
1854
- }
1855
- },
1856
- true
1857
- );
1858
- }
1859
- }
1860
-
1861
- /*
1862
- _GetSplineFlingDuration(velocity) {
1863
- let l = this._GetSplineDeceleration(velocity);
1864
- let decelMinusOne = Forge.DragInfo.DECELERATION_RATE - 1.0;
1865
- return parseInt(1000.0 * Math.exp(l / decelMinusOne));
1866
- }
1867
- */
1868
- // 减速带
1869
- _GetSplineDeceleration(velocity) {
1870
- return Math.log(
1871
- (Forge.DragInfo.INFLEXION * Math.abs(velocity)) /
1872
- (Forge.DragInfo.SCROLL_FRICTION * Forge.DragInfo.PHYSICAL_COEF)
1873
- );
1874
- }
1875
-
1876
- _GetSplineFlingDistance(velocity) {
1877
- const l = this._GetSplineDeceleration(velocity);
1878
- const decelMinusOne = Forge.DragInfo.DECELERATION_RATE - 1.0;
1879
- return (
1880
- Forge.DragInfo.SCROLL_FRICTION *
1881
- Forge.DragInfo.PHYSICAL_COEF *
1882
- Math.exp((Forge.DragInfo.DECELERATION_RATE / decelMinusOne) * l)
1883
- );
1884
- }
1885
-
1886
- _DoDragMove(event, need_anim) {
1887
- let deltaX = event._deltaX;
1888
- let deltaY = event._deltaY;
1889
- this._DragMovedDistanceX += deltaX;
1890
- this._DragMovedDistanceY += deltaY;
1891
- if (!need_anim) {
1892
- // onFling时,dragmove不更新view坐标,故用deltaX,不使用内部的_deltaX。
1893
- deltaX = event.deltaX;
1894
- deltaY = event.deltaY;
1895
- }
1896
-
1897
- const duration = event.timeStamp / 1000;
1898
- let transition = `left ${duration}s, top ${duration}s`;
1899
- if (
1900
- this._DragInfo.Settings.DragDirection ===
1901
- Forge.DragSetting.DIRECTION_VERTICAL
1902
- ) {
1903
- deltaX = 0;
1904
- transition = `top ${duration}s`;
1905
- } else if (
1906
- this._DragInfo.Settings.DragDirection ===
1907
- Forge.DragSetting.DIRECTION_HORIZONTAL
1908
- ) {
1909
- deltaY = 0;
1910
- transition = `left ${duration}s`;
1911
- } else if (
1912
- this._DragInfo.Settings.DragDirection ===
1913
- Forge.DragSetting.DIRECTION_DISABLE
1914
- ) {
1915
- deltaX = 0;
1916
- deltaY = 0;
1917
- }
1918
- let lp = this.GetLayoutParams();
1919
- // const viewX = lp.MarginLeft;
1920
- // const viewY = lp.MarginTop;
1921
- // 检测边界
1922
- lp = this._GetMovedLayoutParams(deltaX, deltaY);
1923
- if (need_anim) {
1924
- this.Element.style.transition = transition;
1925
- this.ResetLayoutParams(lp);
1926
- }
1927
- if (
1928
- Math.abs(this._DragMovedDistanceX) >=
1929
- this._DragInfo.Settings.TriggerMovedDistance ||
1930
- Math.abs(this._DragMovedDistanceY) >=
1931
- this._DragInfo.Settings.TriggerMovedDistance
1932
- ) {
1933
- if (this._DragInfo.Listener && this._DragInfo.Listener.OnMoved) {
1934
- // 补充event
1935
- event.viewX = lp.MarginLeft;
1936
- event.viewY = lp.MarginTop;
1937
- return this._DragInfo.Listener.OnMoved(event);
1938
- }
1939
- }
1940
- return false;
1941
- }
1942
-
1943
- _GetMovedLayoutParams(deltaX, deltaY) {
1944
- const lp = this.GetLayoutParams();
1945
- let x = lp.MarginLeft + deltaX;
1946
- let y = lp.MarginTop + deltaY;
1947
-
1948
- if (x > this._DragInfo.Settings.SlidePile.x) {
1949
- x = this._DragInfo.Settings.SlidePile.x;
1950
- } else if (
1951
- x + lp.Width <
1952
- this._DragInfo.Settings.SlidePile.x +
1953
- this._DragInfo.Settings.SlidePile.width
1954
- ) {
1955
- x =
1956
- this._DragInfo.Settings.SlidePile.x +
1957
- this._DragInfo.Settings.SlidePile.width -
1958
- lp.Width;
1959
- }
1960
- if (y > this._DragInfo.Settings.SlidePile.y) {
1961
- y = this._DragInfo.Settings.SlidePile.y;
1962
- } else if (
1963
- y + lp.Height <
1964
- this._DragInfo.Settings.SlidePile.y +
1965
- this._DragInfo.Settings.SlidePile.height
1966
- ) {
1967
- y =
1968
- this._DragInfo.Settings.SlidePile.y +
1969
- this._DragInfo.Settings.SlidePile.height -
1970
- lp.Height;
1971
- }
1972
- lp.SetPosition(x, y);
1973
-
1974
- return lp;
1975
- }
1976
-
1977
- _SlideIfEnableTabMod(event, direction) {
1978
- if (!this._DragInfo.Settings.EnableTabMode) {
1979
- return false;
1980
- }
1981
- const deltaX = event._deltaX;
1982
- const deltaY = event._deltaY;
1983
- let distance_x = event.deltaX;
1984
- let distance_y = event.deltaY;
1985
- let page_edge =
1986
- this._DragInfo.Settings.PageWidth * this._DragInfo.Settings.PageEdge;
1987
- const lp = this.GetLayoutParams();
1988
- const viewX = lp.MarginLeft + deltaX;
1989
- const viewY = lp.MarginTop + deltaY;
1990
- if (event.type === Forge.DragInfo.EVENT_TYPE.OnFling) {
1991
- page_edge = 0; // fling时,不进行edge判断
1992
- }
1993
-
1994
- // 计算
1995
- switch (this._DragInfo.Settings.DragDirection) {
1996
- case Forge.DragSetting.DIRECTION_VERTICAL: {
1997
- // 当拖拽的距离大于等于limitrange时,进行同向动画,否则动画相反
1998
- distance_x = 0;
1999
- // 重置duration 与 距离
2000
- if (distance_y >= 0) {
2001
- const left_width =
2002
- this._DragInfo.Settings.PageWidth -
2003
- (Math.abs(viewY) % this._DragInfo.Settings.PageWidth);
2004
- if (left_width >= page_edge) {
2005
- distance_y = this._DragInfo.Settings.PageWidth - left_width;
2006
- } else {
2007
- distance_y = -left_width;
2008
- }
2009
- } else {
2010
- const left_width =
2011
- Math.abs(viewY) % this._DragInfo.Settings.PageWidth;
2012
- if (left_width >= page_edge) {
2013
- distance_y = -(this._DragInfo.Settings.PageWidth - left_width);
2014
- } else {
2015
- distance_y = left_width;
2016
- }
2017
- }
2018
- break;
2019
- }
2020
- case Forge.DragSetting.DIRECTION_HORIZONTAL: {
2021
- distance_y = 0;
2022
- if (distance_x >= 0) {
2023
- const left_width =
2024
- this._DragInfo.Settings.PageWidth -
2025
- (Math.abs(viewX) % this._DragInfo.Settings.PageWidth);
2026
- if (left_width >= page_edge) {
2027
- distance_x = this._DragInfo.Settings.PageWidth - left_width;
2028
- } else {
2029
- distance_x = -left_width;
2030
- }
2031
- console.log(
2032
- `right, left_width:${left_width}, distance_x:${distance_x}`
2033
- );
2034
- } else {
2035
- const left_width =
2036
- Math.abs(viewX) % this._DragInfo.Settings.PageWidth;
2037
- if (left_width >= page_edge) {
2038
- distance_x = -(this._DragInfo.Settings.PageWidth - left_width);
2039
- } else {
2040
- distance_x = left_width;
2041
- }
2042
- console.log(
2043
- `left, left_width:${left_width}, distance_x:${distance_x}`
2044
- );
2045
- }
2046
- break;
2047
- }
2048
- case Forge.DragSetting.DIRECTION_AUTO: {
2049
- console.log(
2050
- "slideIfEnableTabMode DragDirection error DRAG_DIRECTION_AUTO"
2051
- );
2052
- break;
2053
- }
2054
- default:
2055
- break;
2056
- }
2057
-
2058
- if (distance_x === 0 && distance_y === 0) {
2059
- console.log("slideIfEnableTabMode distance_x === 0 && distance_y === 0");
2060
- return false;
2061
- }
2062
- const speed =
2063
- Math.sqrt(distance_x * distance_x + distance_y * distance_y) / 0.3; // 与jsview 效果匹配,300ms完成动画
2064
- event.deltaX = distance_x;
2065
- event.deltaY = distance_y;
2066
- this._DonFlingAnim(event, speed);
2067
- return true;
2068
- }
2069
-
2070
- _DoDragEnd(event) {
2071
- let deltaX = event._deltaX;
2072
- let deltaY = event._deltaY;
2073
- if (
2074
- this._DragInfo.Settings.DragDirection ===
2075
- Forge.DragSetting.DIRECTION_VERTICAL
2076
- ) {
2077
- deltaX = 0;
2078
- } else if (
2079
- this._DragInfo.Settings.DragDirection ===
2080
- Forge.DragSetting.DIRECTION_HORIZONTAL
2081
- ) {
2082
- deltaY = 0;
2083
- } else if (
2084
- this._DragInfo.Settings.DragDirection ===
2085
- Forge.DragSetting.DIRECTION_DISABLE
2086
- ) {
2087
- deltaX = 0;
2088
- deltaY = 0;
2089
- }
2090
-
2091
- console.log("_DoDragEnd event:", event, this.Element.style);
2092
- let lp = this.GetLayoutParams();
2093
- // 检测边界
2094
- lp = this._GetMovedLayoutParams(deltaX, deltaY);
2095
- this.ResetLayoutParams(lp);
2096
-
2097
- // 补充event
2098
- event.viewX = lp.MarginLeft;
2099
- event.viewY = lp.MarginTop;
2100
-
2101
- return this._DragInfo.Listener.OnDragEnd(event);
2102
- }
2103
-
2104
- _DragImactSensorRecycle() {
2105
- console.log(
2106
- "_DragImactSensorRecycle this._DragImactSensor:",
2107
- this._DragImactSensor
2108
- );
2109
- if (this._DragImactSensor) {
2110
- this._DragImactSensor.Recycle();
2111
- }
2112
- }
2113
-
2114
- _DonFlingAnim(event, speed) {
2115
- const distance_x = event.deltaX;
2116
- const distance_y = event.deltaY;
2117
- const lp = this.GetLayoutParams();
2118
- const view_origin_x = lp.MarginLeft;
2119
- const view_origin_y = lp.MarginTop;
2120
- const target_x = lp.MarginLeft + distance_x;
2121
- const target_y = lp.MarginTop + distance_y;
2122
- const adjust_lp = this._GetMovedLayoutParams(distance_x, distance_y);
2123
- if (
2124
- adjust_lp.MarginLeft === lp.MarginLeft &&
2125
- adjust_lp.MarginTop === lp.MarginTop
2126
- ) {
2127
- console.log(
2128
- "_DonFlingAnim adjust_lp.MarginLeft === lp.MarginLeft && adjust_lp.MarginTop === lp.MarginTop"
2129
- );
2130
- return;
2131
- }
2132
-
2133
- this.DragControl = new Forge.DragTranslateControl();
2134
- this.DragControl._SetView(this);
2135
- this.DragControl.speed(speed);
2136
- console.log(`OnFling speed:${speed}`);
2137
- const setting = this._DragInfo.Settings;
2138
- this._DragImactSensorRecycle();
2139
-
2140
- this.Element.style.transform = null;
2141
- this.DragControl.target(lp.MarginLeft, lp.MarginTop).jumpSilent();
2142
- // TODO 需确认,恢复view的坐标,进行动画,否则碰撞检测时,会使用坐标并将其于transform translate合计,导致碰撞错误
2143
- lp.SetPosition(0, 0);
2144
- this.ResetLayoutParams(lp);
2145
- let timeStamp = 0;
2146
-
2147
- this.DragControl.target(target_x, target_y).start(
2148
- (view_x, view_y) => {
2149
- this.DragControl = null;
2150
- lp.SetPosition(view_x, view_y);
2151
- this.ResetLayoutParams(lp);
2152
- this.Element.style.transform = null;
2153
- this._DragImactSensorRecycle();
2154
-
2155
- // 补充event
2156
- event.viewX = view_x;
2157
- event.viewY = view_y;
2158
- this._DragInfo.Listener.OnFling(event);
2159
- console.log(
2160
- `_DonFlingAnim end view_x:${view_x}, view_y:${view_y}, distance_x:${distance_x}, distance_y:${distance_y}`
2161
- );
2162
- },
2163
- (progress) => {
2164
- const deltaX = distance_x * progress;
2165
- const deltaY = distance_y * progress;
2166
- console.log(
2167
- `_DonFlingAnim progress:${progress}, deltaX:${deltaX}, deltaY:${deltaY}`
2168
- );
2169
- if (
2170
- Math.abs(deltaX) > this._DragInfo.Settings.TriggerMovedDistance ||
2171
- Math.abs(deltaY) > this._DragInfo.Settings.TriggerMovedDistance
2172
- ) {
2173
- const target_event = {
2174
- deltaX: view_origin_x + deltaX,
2175
- deltaY: view_origin_y + deltaY,
2176
- _deltaX: deltaX,
2177
- _deltaY: deltaY,
2178
- timeStamp: parseInt((Date.now() - timeStamp) / 1000, 10),
2179
- };
2180
- this._DoDragMove(target_event, false);
2181
- timeStamp = Date.now();
2182
- }
2183
- }
2184
- );
2185
- const parent_view_position = this.GetPositionOffset(this.ParentView);
2186
- // 设置碰撞sensor
2187
- this._DragImactSensor = new Forge.DragImpactSensor(
2188
- [
2189
- {
2190
- x: setting.SlidePile.x + parent_view_position.x,
2191
- y: setting.SlidePile.y + parent_view_position.y,
2192
- },
2193
- {
2194
- x:
2195
- setting.SlidePile.x +
2196
- parent_view_position.x +
2197
- setting.SlidePile.width,
2198
- y: setting.SlidePile.y + parent_view_position.y,
2199
- },
2200
- {
2201
- x: setting.SlidePile.x + parent_view_position.x,
2202
- y:
2203
- setting.SlidePile.y +
2204
- parent_view_position.y +
2205
- setting.SlidePile.height,
2206
- },
2207
- {
2208
- x:
2209
- setting.SlidePile.x +
2210
- parent_view_position.x +
2211
- setting.SlidePile.width,
2212
- y:
2213
- setting.SlidePile.y +
2214
- parent_view_position.y +
2215
- setting.SlidePile.height,
2216
- },
2217
- ],
2218
- this.Element,
2219
- new Forge.sImpactSensorManager.Callback((element_position) => {
2220
- this._DoDragPause(event);
2221
- this._DragImactSensorRecycle();
2222
- }, null)
2223
- );
2224
- }
2225
-
2226
- _DoFling(event) {
2227
- let distance_x = event.deltaX;
2228
- let distance_y = event.deltaY;
2229
- let need_fling = true;
2230
- let speed = 0;
2231
- switch (this._DragInfo.Settings.DragDirection) {
2232
- case Forge.DragSetting.DIRECTION_VERTICAL:
2233
- distance_x = 0;
2234
- if (distance_y === 0) {
2235
- need_fling = false;
2236
- }
2237
- speed = Math.abs(event.velocityY);
2238
- break;
2239
- case Forge.DragSetting.DIRECTION_HORIZONTAL:
2240
- distance_y = 0;
2241
- if (distance_x === 0) {
2242
- need_fling = false;
2243
- }
2244
- speed = Math.abs(event.velocityX);
2245
- break;
2246
- case Forge.DragSetting.DIRECTION_DISABLE:
2247
- need_fling = false;
2248
- break;
2249
- default:
2250
- speed = Math.sqrt(event.velocityX ** 2, event.velocityY ** 2);
2251
- break;
2252
- }
2253
-
2254
- if (need_fling) {
2255
- event.deltaX = distance_x;
2256
- event.deltaY = distance_y;
2257
- this._DonFlingAnim(event, speed);
2258
- }
2259
- return true;
2260
- }
2261
-
2262
- GetBoundingClientRect() {
2263
- return new Promise((resolve, reject) => {
2264
- if (this.Element) {
2265
- //浏览器上仅为实现相似效果, 而style.animation设置后同一时间片内TransformAnimationObj还未创建,因此通过setTimeout保证TransformAnimationObj存在
2266
- setTimeout(() => {
2267
- let view = this;
2268
- let animCount = 0;
2269
- while(view) {
2270
- if (view.TransformAnimationObj && view.TransformAnimationObj.repeatTimes > 0) {
2271
- animCount++;
2272
- view.TransformAnimationObj.AddAnimationListener(new Forge.AnimationListener(null, (normal_end) => {
2273
- animCount--;
2274
- if (animCount <= 0) {
2275
- const {left, top, width, height} = this.Element.getBoundingClientRect();
2276
- resolve({
2277
- left,
2278
- top,
2279
- width,
2280
- height,
2281
- });
2282
- }
2283
- }));
2284
- }
2285
- view = view.ParentView;
2286
- }
2287
- }, 1);
2288
- } else {
2289
- reject(new Error("BrowserError: dom element is null."));
2290
- }
2291
- })
2292
- }
2293
- }
2294
- LayoutViewBase.DivId = 0;
2295
- // Static variable
2296
- Forge.LayoutViewBase = LayoutViewBase;
2297
-
2298
- class LayoutView extends Forge.LayoutViewBase {
2299
- /**
2300
- * 渲染树的每个节点。<br>
2301
- * 创建例子:<br>
2302
- * 1. 通过Forge.TextureManager创建Texture<br>
2303
- * 2. 将Texture装入Forge.TextureSetting集合, var ts = new Forge.TextureSetting(...);<br>
2304
- * 3. var v = new Forge.LayoutView(ts)<br>
2305
- * 4. 将view加入渲染树 parent_view.AddView(v, {x:0, y:0, width:100, height:100})<br>
2306
- * width和height决定Texture的描画尺寸(拉伸)<br>
2307
- *
2308
- * @public
2309
- * @constructor Forge.LayoutView
2310
- * @extends Forge.LayoutViewBase
2311
- * @param {Forge.TextureSetting} texture_setting 用于描画的Texture合集
2312
- * */
2313
- constructor(texture_setting, element_name) {
2314
- if (texture_setting && !(texture_setting instanceof Forge.TextureSetting)) {
2315
- Forge.ThrowError("ERROR:LayoutView need TextureSetting as parameter");
2316
- }
2317
- element_name = element_name || "div";
2318
- super(texture_setting, element_name);
2319
- }
2320
- }
2321
-
2322
- Forge.LayoutView = LayoutView;
2323
- window.LayoutView = Forge.LayoutView; // export class
2324
- class RootView extends Forge.LayoutView {
2325
- /**
2326
- * 根节点LayoutView
2327
- *
2328
- * @protected
2329
- * @constructor Forge.RootView
2330
- * @extends Forge.LayoutView
2331
- * */
2332
- constructor() {
2333
- super(undefined, "root");
2334
- this._ViewType = 1;
2335
- this._IsChildOfRootView = true;
2336
- window.gRootView = this;
2337
- Forge.sRootView = this;
2338
- }
2339
-
2340
- /**
2341
- * 初始化RootView的尺寸(一般根据window.innerHeight和window.innerWidth)
2342
- *
2343
- * @public
2344
- * @func Init
2345
- * @memberof Forge.RootView
2346
- * @instance
2347
- * @param {Forge.Renderer} renderer
2348
- * @param {int} left
2349
- * @param {int} top
2350
- * @param {int} width
2351
- * @param {int} height
2352
- * */
2353
- Init(renderer, left, top, width, height) {
2354
- // Init static private value
2355
- this.InitLayoutViewStaticValues(renderer);
2356
-
2357
- this.ResetLayoutParams({ x: 0, y: 0, width: 1280, height: 720 }); // TODO: 需要和ActivityManager设置进行对接
2358
- }
2359
-
2360
- /**
2361
- * 初始化LayoutViewBase中的静态变量
2362
- *
2363
- * @protected
2364
- * @func InitLayoutViewStaticValues
2365
- * @memberof Forge.LayoutViewBase
2366
- * @instance
2367
- * @param {Forge.Renderer} renderer
2368
- * */
2369
- InitLayoutViewStaticValues(renderer) {
2370
- Forge.LayoutViewBase.sRenderer = renderer; // Set shared renderer of all LayoutView
2371
- Forge.LayoutViewBase.sInternalTextureManager = renderer.GetSharedTextureManager();
2372
- Forge.LayoutViewBase.sIdentityMat4 = new Forge.Mat4();
2373
- Forge.LayoutViewBase.sNullDirectParentMat4 = new Forge.Mat4();
2374
- Forge.LayoutViewBase.sBakeFlipYMat4 = new Forge.Mat4().rotatex(180);
2375
- }
2376
- }
2377
- Forge.RootView = RootView;
2378
- window.RootView = Forge.RootView; // export class
2379
- class CClipRectInfo {
2380
- constructor(x, y, w, h, enable) {
2381
- this.coordX = x;
2382
- this.coordY = y;
2383
- this.width = w;
2384
- this.height = h;
2385
- this.useScissors = enable;
2386
- this.maskStencil = null;
2387
- }
2388
-
2389
- updateInfo(x, y, w, h, enable) {
2390
- this.coordX = x;
2391
- this.coordY = y;
2392
- this.width = w;
2393
- this.height = h;
2394
- this.useScissors = enable;
2395
- }
2396
-
2397
- setMaskStencil(local_file_uri) {
2398
- this.maskStencil = local_file_uri;
2399
- }
2400
- }
2401
-
2402
- class ClipView extends Forge.LayoutView {
2403
- /**
2404
- * 带裁剪功能的LayoutView
2405
- *
2406
- * @public
2407
- * @constructor Forge.ClipView
2408
- * @extends Forge.LayoutView
2409
- * @param {Forge.TextureSetting} texture_setting 背景Texture集合
2410
- * */
2411
- constructor(texture_setting) {
2412
- super(texture_setting, "div");
2413
- this._ClipRectInfo = null;
2414
- this.Id = "ClipView";
2415
- this.TextureSetting = null;
2416
- }
2417
-
2418
- /**
2419
- * 重载LayoutView.SetId,为所设置的Id添加后缀_ClipView
2420
- *
2421
- * @public
2422
- * @func SetId
2423
- * @memberof Forge.ClipView
2424
- * @instance
2425
- * @param {string} id 原始id
2426
- * */
2427
- SetId(id) {
2428
- this.Id = `${id}_ClipView`;
2429
- }
2430
-
2431
- /**
2432
- * 设置裁剪区域大小
2433
- *
2434
- * @public
2435
- * @func SetClipRect
2436
- * @memberof Forge.ClipView
2437
- * @instance
2438
- * @param {int} x 相对于自己的坐标
2439
- * @param {int} y 相对于自己的坐标
2440
- * @param {int} width 相对于自己的坐标
2441
- * @param {int} height 相对于自己的坐标
2442
- * @param {boolean} use_scissors 是否进行裁剪
2443
- * */
2444
- SetClipRect(x, y, width, height, use_scissors) {
2445
- // use_scissors = false; // Enabled only when debug
2446
- if (this._ClipRectInfo === null) {
2447
- this._ClipRectInfo = new CClipRectInfo(x, y, width, height, use_scissors);
2448
- } else {
2449
- this._ClipRectInfo.updateInfo(x, y, width, height, use_scissors);
2450
- }
2451
- const clip_left = x;
2452
- const clip_top = y;
2453
- const clip_right = this.LayoutParams.Width - clip_left - width;
2454
- const clip_bottom = this.LayoutParams.Height - clip_top - height;
2455
- if (use_scissors) {
2456
- this.Element.style.overflow = "hidden";
2457
- this.Element.style.clipPath = `inset(${clip_top}px ${clip_right}px ${clip_bottom}px ${clip_left}px)`;
2458
- } else {
2459
- this.Element.style.overflow = "visible";
2460
- this.Element.style.clipPath = "unset";
2461
- }
2462
- }
2463
- }
2464
- Forge.ClipView = ClipView;
2465
- window.ClipView = Forge.ClipView; // export class
2466
-
2467
- class NinePatchView extends Forge.LayoutView {
2468
- /**
2469
- * 按照NinePatch方式进行渲染的专用LayoutView
2470
- *
2471
- * @public
2472
- * @constructor Forge.NinePatchView
2473
- * @extends Forge.LayoutView
2474
- * @param {Forge.TextureSetting} texture_setting 背景Texture集合
2475
- * */
2476
- constructor(texture_setting) {
2477
- super(texture_setting, "div");
2478
- this._HorizontalRepeats = [0, 0, 0, 0];
2479
- this._VerticalRepeats = [0, 0, 0, 0];
2480
- this._HorizontalPadding = [0, 0];
2481
- this._VerticalPadding = [0, 0];
2482
- this._ImageDspWidth = 0;
2483
- this._ImageDspHeight = 0;
2484
- }
2485
-
2486
- /**
2487
- * 设置新的Texture集合
2488
- *
2489
- * @public
2490
- * @func ResetTexture
2491
- * @memberof Forge.LayoutViewBase
2492
- * @instance
2493
- * @param {Forge.TextureSetting} texture_setting 新的Texture集合
2494
- * */
2495
- ResetTexture(texture_setting) {
2496
- this.TextureSetting = texture_setting;
2497
- this._ApplyChanges();
2498
- }
2499
-
2500
- /**
2501
- * 设置横向延展区域和纵向延展的区域。(即NinePatch规则中的上边线和左边线)
2502
- *
2503
- * @public
2504
- * @func SetRepeat
2505
- * @memberof Forge.NinePatchView
2506
- * @instance
2507
- * @param {Array} horizontal_repeat 横向延展区域设置数组(目前延展区域个数最大支持2个)<br>
2508
- * 数组元素内容,包含start和end该点:{start:xxx, width:xxx}
2509
- * @param {Array} vertical_repeat 纵向延展区域设置数组(目前延展区域个数最大支持2个)<br>
2510
- * 数组元素内容,包含start和end该点:{start:xxx, width:xxx}
2511
- * */
2512
- SetRepeat(horizontal_repeat, vertical_repeat) {
2513
- Forge.Assert(horizontal_repeat.length <= 2);
2514
- Forge.Assert(vertical_repeat.length <= 2);
2515
-
2516
- for (let i = 0; i < 2; i++) {
2517
- if (i < horizontal_repeat.length) {
2518
- this._HorizontalRepeats[i * 2] = horizontal_repeat[i].start;
2519
- this._HorizontalRepeats[i * 2 + 1] = horizontal_repeat[i].width;
2520
- } else {
2521
- this._HorizontalRepeats[i * 2] = 0;
2522
- this._HorizontalRepeats[i * 2 + 1] = 0;
2523
- }
2524
-
2525
- if (i < vertical_repeat.length) {
2526
- this._VerticalRepeats[i * 2] = vertical_repeat[i].start;
2527
- this._VerticalRepeats[i * 2 + 1] = vertical_repeat[i].width;
2528
- } else {
2529
- this._VerticalRepeats[i * 2] = 0;
2530
- this._VerticalRepeats[i * 2 + 1] = 0;
2531
- }
2532
- }
2533
-
2534
- this._ApplyChanges();
2535
-
2536
- return this; // 为了支持连续设定的用法
2537
- }
2538
-
2539
- /**
2540
- * 设置横向填充区尺寸以及纵向填充区尺寸。(即NinePatch规则中的下边线和右边线)
2541
- *
2542
- * @public
2543
- * @func SetPadding
2544
- * @memberof Forge.NinePatchView
2545
- * @instance
2546
- * @param {Object} horizontal_padding 内容覆盖区域(横向),格式:{start:xxx, width:xxx}
2547
- * @param {Object} vertical_padding 内容覆盖区域(纵向向),格式:{start:xxx, width:xxx}
2548
- * */
2549
- SetPadding(horizontal_padding, vertical_padding) {
2550
- Forge.Assert(horizontal_padding !== null);
2551
- Forge.Assert(vertical_padding !== null);
2552
- this._VerticalPadding[0] = vertical_padding.start;
2553
- this._VerticalPadding[1] = vertical_padding.width;
2554
- this._HorizontalPadding[0] = horizontal_padding.start;
2555
- this._HorizontalPadding[1] = horizontal_padding.width;
2556
-
2557
- this._ApplyChanges();
2558
-
2559
- return this; // 为了支持连续设定的用法
2560
- }
2561
-
2562
- /**
2563
- * 应对NinePatch图要缩放显示的场景,可以设置显示尺寸
2564
- *
2565
- * @public
2566
- * @func SetImageDspSize
2567
- * @memberof Forge.NinePatchView
2568
- * @instance
2569
- * @param {int} image_dsp_width 图片缩放后的显示宽度
2570
- * @param {int} image_dsp_height 图片缩放后的显示高度
2571
- * */
2572
- SetImageDspSize(image_dsp_width, image_dsp_height) {
2573
- this._ImageDspWidth = image_dsp_width;
2574
- this._ImageDspHeight = image_dsp_height;
2575
- }
2576
-
2577
- _ApplyChanges() {
2578
- let texture_setting = this.TextureSetting;
2579
- if (texture_setting) {
2580
- if (texture_setting.MaskSetting) {
2581
- if (texture_setting.MaskSetting._MaskType === "CORNER") {
2582
- this._SetBorderRadius(texture_setting.MaskSetting);
2583
- }
2584
- }
2585
- if (texture_setting.Texture.Source) {
2586
- const texture_width = texture_setting.Texture.RenderTexture.Width;
2587
- const texture_height = texture_setting.Texture.RenderTexture.Height;
2588
- const scale_width = texture_width / this._ImageDspWidth;
2589
- const scale_height = texture_height / this._ImageDspHeight;
2590
-
2591
- // image wide
2592
- const wide_left = this._HorizontalRepeats[0];
2593
- const wide_right = this._ImageDspWidth - this._HorizontalRepeats[1] - wide_left;
2594
- const wide_top = this._VerticalRepeats[0];
2595
- const wide_bottom = this._ImageDspHeight - this._VerticalRepeats[1] - wide_top;
2596
-
2597
- // slice top right bottom left
2598
- let slice_left = Math.floor(this._HorizontalRepeats[0] * scale_width);
2599
- let slice_right =
2600
- texture_width - Math.floor(this._HorizontalRepeats[1] * scale_width) - slice_left;
2601
- let slice_top = Math.floor(this._VerticalRepeats[0] * scale_height);
2602
- let slice_bottom =
2603
- texture_height - Math.floor(this._VerticalRepeats[1] * scale_height) - slice_top;
2604
-
2605
- if (slice_left + slice_right >= texture_width) {
2606
- // 修正.9无中心repeat区域在PC repeat区域上不显示问题
2607
- slice_left -= 1;
2608
- slice_right -= 1;
2609
- }
2610
-
2611
- if (slice_top + slice_bottom >= texture_height) {
2612
- // 修正.9无中心repeat区域在PC repeat区域上不显示问题
2613
- slice_top -= 1;
2614
- slice_bottom -= 1;
2615
- }
2616
-
2617
- const slice_str = `${slice_top} ${slice_right} ${slice_bottom} ${slice_left}`;
2618
-
2619
- // BorderImage
2620
- this.Element.style.borderImage = `url(${texture_setting.Texture.Source}) ${slice_str} fill`; // 图片边框向内偏移。
2621
-
2622
- // outset
2623
- const outset_left = this._HorizontalPadding[0];
2624
- const outset_right =
2625
- this._ImageDspWidth - this._HorizontalPadding[1] - outset_left;
2626
- const outset_top = this._VerticalPadding[0];
2627
- const outset_bottom =
2628
- this._ImageDspHeight - this._VerticalPadding[1] - outset_top;
2629
-
2630
- this.Element.style.borderImageWidth = `${wide_top}px ${wide_right}px ${wide_bottom}px ${wide_left}px`; // 图片边框的宽度。
2631
- this.Element.style.borderImageOutset = `${outset_top}px ${outset_right}px ${outset_bottom}px ${outset_left}px`; // 边框图像区域超出边框的量。
2632
- }
2633
- } else {
2634
- // clear image set
2635
-
2636
- // border radius
2637
- this.Element.style.borderRadius = "";
2638
-
2639
- // Border image
2640
- this.Element.style.borderImage = "";
2641
- }
2642
- }
2643
- }
2644
-
2645
- Forge.NinePatchView = NinePatchView;
2646
-
2647
- class JsvElementView extends Forge.LayoutView {
2648
- /**
2649
- * 根节点LayoutView
2650
- *
2651
- * @protected
2652
- * @constructor Forge.RootView
2653
- * @extends Forge.LayoutView
2654
- * */
2655
- constructor(name) {
2656
- let origin_name;
2657
- if (name.startsWith("jsve-")) {
2658
- // 新模式 jsve-XXXX 避免和vue的普通定义重名
2659
- origin_name = name.substr(5);
2660
- } else {
2661
- // 兼容老版本的 jsvXXX 模式
2662
- origin_name = name.substr(3);
2663
- }
2664
- super(undefined, origin_name);
2665
- }
2666
-
2667
- setAttribute(name, value) {
2668
- this.Element.setAttribute(name, value);
2669
- }
2670
-
2671
- removeAttribute(name) {
2672
- this.Element.removeAttribute(name);
2673
- }
2674
-
2675
- getAttribute(name) {
2676
- return this.Element.getAttribute(name);
2677
- }
2678
-
2679
- hasAttribute(name) {
2680
- return this.Element.hasAttribute(name);
2681
- }
2682
-
2683
- get textContent() {
2684
- return this.Element.textContent;
2685
- }
2686
-
2687
- set textContent(text) {
2688
- this.Element.textContent = text;
2689
- }
2690
- }
2691
- Forge.JsvElementView = JsvElementView;
2692
-
2693
- class VideoView extends Forge.LayoutView {
2694
- constructor(video_player_hdl, texture_setting) {
2695
- super(texture_setting);
2696
- this._ViewType = 8;
2697
- this.Element = video_player_hdl.Ele;
2698
- this.Id = "VideoView";
2699
- }
2700
-
2701
- /**
2702
- * 重载LayoutView.SetId,为所设置的Id添加后缀_VideoView
2703
- *
2704
- * @public
2705
- * @func SetId
2706
- * @memberof Forge.VideoView
2707
- * @instance
2708
- * @param {string} id 原始id
2709
- * */
2710
- SetId(id) {
2711
- this.Id = `${id}_VideoView`;
2712
- }
2713
-
2714
- ResetLayoutParams(new_params) {
2715
- if (new_params !== null) {
2716
- if (!(new_params instanceof Forge.LayoutParamsBase)) {
2717
- this.LayoutParams = new Forge.LayoutParams(new_params);
2718
- } else {
2719
- this.LayoutParams = new_params.Clone();
2720
- }
2721
- this.Element.style.left = `${this.LayoutParams.MarginLeft}px`;
2722
- this.Element.style.top = `${this.LayoutParams.MarginTop}px`;
2723
- if (this.LayoutParams.Width) {
2724
- this.Element.style.width = `${this.LayoutParams.Width}px`;
2725
- }
2726
- if (this.LayoutParams.Height) {
2727
- this.Element.style.height = `${this.LayoutParams.Height}px`;
2728
- }
2729
- } else {
2730
- Forge.ThrowError("ResetLayoutParams(): new params is null");
2731
- }
2732
- }
2733
-
2734
- _OnDetachFromSystem() {
2735
- super._OnDetachFromSystem();
2736
- if (this._VideoPlayerHdl) {
2737
- this._VideoPlayerHdl.unload();
2738
- this._VideoPlayerHdl = null;
2739
- }
2740
- }
2741
- }
2742
- Forge.VideoView = VideoView;
2743
-
2744
- class EditControlView extends Forge.LayoutView {
2745
- /**
2746
- * 带输入框功能的LayoutView
2747
- *
2748
- * @constructor Forge.EditControlView
2749
- * @extends Forge.LayoutView
2750
- * @param {Forge.TextureSetting} texture_setting 背景Texture集合
2751
- * */
2752
- constructor() {
2753
- super(null, "input");
2754
- this._ViewType = 5;
2755
- this._InputType = Forge.TextInputType.TEXT;
2756
- this.Id = "EditControlView";
2757
- }
2758
-
2759
- _OnAttachToSystem() {
2760
- super._OnAttachToSystem();
2761
- // 该input只作为文字录入的辅助作用,故移除屏幕外,
2762
- // 具体描画为高阶控件操控
2763
- this.Element.style.left = "-1920px";
2764
- this.Element.style.top = "-1080px";
2765
- this.Element.style.width = "1px";
2766
- this.Element.style.height = "1px";
2767
- /* //TODO for Test
2768
- this.Element.style.left="300px";
2769
- this.Element.style.top="100px";
2770
- this.Element.style.width="100px";
2771
- this.Element.style.height="50px"; */
2772
-
2773
- // pointerEvents设置,input才能获得焦点
2774
- this.Element.style.pointerEvents = "auto";
2775
- this.Element.addEventListener("keydown", (event) => {
2776
- // add listener keydown for textarea
2777
- event = event || window.event;
2778
- let cur_offset = this.Element.selectionStart;
2779
- console.log(`keydown cur_offset:${cur_offset}`);
2780
- if (event.keyCode === 37) {
2781
- --cur_offset;
2782
- if (cur_offset < 0) {
2783
- cur_offset = 0;
2784
- }
2785
- if (cur_offset !== this.Element.selectionStart) {
2786
- this.OnTextChanged(this.Element.value, cur_offset, true);
2787
- if (event.stopPropagation) {
2788
- event.stopPropagation();
2789
- }
2790
- } else {
2791
- this.Element.blur();
2792
- }
2793
- } else if (event.keyCode === 39) {
2794
- ++cur_offset;
2795
- if (cur_offset > this.Element.value.length) {
2796
- cur_offset = this.Element.value.length;
2797
- }
2798
- if (cur_offset !== this.Element.selectionStart) {
2799
- this.OnTextChanged(this.Element.value, cur_offset, true);
2800
- if (event.stopPropagation) {
2801
- event.stopPropagation();
2802
- }
2803
- } else {
2804
- this.Element.blur();
2805
- }
2806
- } else if (event.keyCode === 38 || event.keyCode === 40) {
2807
- this.Element.blur();
2808
- }
2809
- });
2810
-
2811
- // input onfocus焦点获得
2812
- this.Element.onfocus = (event) => {
2813
- console.log("onfocus in");
2814
- this.OnStatusChanged(1);
2815
- };
2816
- // input onfocus焦点丢失
2817
- this.Element.onblur = (event) => {
2818
- console.log("onblur in");
2819
- this.OnStatusChanged(0);
2820
- };
2821
- const ifDigital = (char) =>
2822
- "0".charCodeAt() <= char.charCodeAt() &&
2823
- char.charCodeAt() <= "9".charCodeAt();
2824
-
2825
- // input 文字变化时
2826
- this.Element.oninput = (event) => {
2827
- console.log("oninput:", event);
2828
- if (event.target.value.length > 0 && event.target.selectionStart > 0) {
2829
- const start = event.target.selectionStart - 1;
2830
- const end = event.target.selectionStart;
2831
- const add_text = event.target.value.slice(start, end);
2832
- if (
2833
- !ifDigital(add_text) &&
2834
- this._InputType === Forge.TextInputType.NUMBER
2835
- ) {
2836
- event.target.value =
2837
- event.target.value.substr(0, start) +
2838
- event.target.value.substr(end);
2839
- event.target.selectionStart = start;
2840
- }
2841
- }
2842
-
2843
- const text = event.target.value;
2844
- const select_start = event.target.selectionStart;
2845
- this.OnTextChanged(decodeURIComponent(text), select_start);
2846
- };
2847
- }
2848
-
2849
- /**
2850
- * 重载LayoutView.SetId,为所设置的Id添加后缀_EditControlView
2851
- *
2852
- * @public
2853
- * @func SetId
2854
- * @memberof Forge.EditControlView
2855
- * @instance
2856
- * @param {string} id 原始id
2857
- * */
2858
- SetId(id) {
2859
- this.Id = `${id}_EditControlView`;
2860
- }
2861
-
2862
- /**
2863
- * 显示输入法
2864
- *
2865
- * @public
2866
- * @func showIme
2867
- * @memberof Forge.EditControlView
2868
- * @instance
2869
- * @param {Forge.TextInputType} input_type
2870
- * @param {string} text 显示字符串
2871
- * @param {int} cursor_pos 光标所在位置
2872
- * @param {int} selectionEnd 字符串选择stop位置,默认为文字的末尾
2873
- * */
2874
- showIme(input_type, text, cursor_pos) {
2875
- if (!this.Element) {
2876
- console.log("showIme but ele is null!");
2877
- return;
2878
- }
2879
- if (input_type === Forge.TextInputType.NONE) {
2880
- console.log("showIme input_type error");
2881
- return;
2882
- }
2883
- if (typeof cursor_pos === "undefined" || cursor_pos === null) {
2884
- cursor_pos = text.length > 0 ? text.length : 0;
2885
- }
2886
- if (cursor_pos < 0) {
2887
- cursor_pos = 0;
2888
- } else if (cursor_pos > text.length) {
2889
- cursor_pos = text.length > 0 ? text.length : 0;
2890
- }
2891
- this._InputType = input_type;
2892
- /* switch (input_type) {
2893
- case Forge.TextInputType.PASSWORD:
2894
- this.Element.type = "password";
2895
- break;
2896
- case Forge.TextInputType.NUMBER:
2897
- this.Element.type = "number";
2898
- break;
2899
- case Forge.TextInputType.TEXT:
2900
- default:
2901
- this.Element.type = "text";
2902
- break;
2903
- } */
2904
- // 浏览器端不对type做限制,(因为number/password类型时selectionStart为null)
2905
- this.Element.type = "text";
2906
- this.Element.value = text;
2907
- this.Element.focus();
2908
- this.Element.selectionStart = cursor_pos;
2909
- this.Element.selectionEnd = cursor_pos;
2910
- }
2911
-
2912
- /**
2913
- * 隐藏输入法
2914
- *
2915
- * @public
2916
- * @func hideIme
2917
- * @memberof Forge.EditControlView
2918
- * @instance
2919
- * */
2920
- hideIme() {
2921
- if (!this.Element) {
2922
- console.log("hideIme, but ele is null!");
2923
- return;
2924
- }
2925
- this.Element.blur();
2926
- }
2927
-
2928
- /**
2929
- * 更新光标位置
2930
- *
2931
- * @public
2932
- * @func updateCursorOffset
2933
- * @memberof Forge.EditControlView
2934
- *
2935
- * @instance
2936
- * @param {String} text 显示字符串
2937
- * @param {int} cursor_pos 光标所在位置
2938
- * */
2939
- updateCursorOffset(text, cursor_offset) {
2940
- if (!this.Element) {
2941
- console.log("updateCursorOffset, but ele is null!");
2942
- return;
2943
- }
2944
- this.Element.selectionStart = cursor_offset;
2945
- this.Element.selectionEnd = cursor_offset;
2946
- this.Element.value = text;
2947
- }
2948
-
2949
- /**
2950
- * 文字变更
2951
- * @param value
2952
- * @param {int} cursor_pos 光标所在位置
2953
- * @param {bool} moved 光标移动
2954
- * @constructor
2955
- */
2956
- OnTextChanged(value, cursor_pos, moved) {
2957
- // Override
2958
- console.log(`OnTextChanged value:${value}`);
2959
- }
2960
-
2961
- /**
2962
- * 状态变更
2963
- * @param status 输入法状态 1:'show'/0:'hide'
2964
- * @constructor
2965
- */
2966
- OnStatusChanged(status) {
2967
- // Override
2968
- }
2969
-
2970
- /**
2971
- * action 事件通知
2972
- * @param action
2973
- * @constructor
2974
- */
2975
- OnEditAction(action) {
2976
- // Override
2977
- }
2978
- }
2979
-
2980
- class FilterView extends Forge.LayoutView {
2981
- constructor(texture_setting, type = 1) {
2982
- super(texture_setting);
2983
- this._ViewType = 10;
2984
- this._FilterType = type
2985
- this.Id = "FilterView";
2986
- this.Element.style.filter = "grayscale(100%)"
2987
- }
2988
- FilterSwitch(enable) {
2989
- if (this.Element) {
2990
- this.Element.style.filter = enable ? "grayscale(100%)" : "";
2991
- }
2992
- }
2993
- SetId(id) {
2994
- this.Id = id + "_FilterView";
2995
- }
2996
- }
2997
- Forge.FilterView = FilterView;
2998
-
2999
- Forge.TextInputType = {
3000
- NONE: 0,
3001
- TEXT: 1,
3002
- PASSWORD: 2,
3003
- TEXT_AREA: 3,
3004
- CONTENT_EDITABLE: 4,
3005
- SEARCH: 5,
3006
- URL: 6,
3007
- EMAIL: 7,
3008
- TELEPHONE: 8,
3009
- NUMBER: 9,
3010
- };
3011
- Forge.EditControlView = EditControlView;
3012
- class JsvControl {
3013
- constructor(params_count) {
3014
- this._Current = new Array(params_count).fill(0);
3015
- this._Target = new Array(params_count).fill(0);
3016
- this._RepeatStart = new Array(params_count).fill(0);
3017
- this._JumpTarget = null;
3018
- this._Jumping = false;
3019
- this._ParameterCount = params_count;
3020
- this._StateIndex = 0; // 0: idle, 1:running
3021
- this._StateLocked = false;
3022
- this._StartSwitcher = false;
3023
- this._PausedCallback = null;
3024
- this._EndCallback = null;
3025
- this._NextEndCallback = null;
3026
- this._Token = 0;
3027
- this._Repeat = false;
3028
- this._OnRepeatCallback = null;
3029
- this._SpriteView = null;
3030
- this._AdvanceCallback = null;
3031
- }
3032
-
3033
- setRepeat(enable, repeat_callback) {
3034
- this._Repeat = enable;
3035
- if (enable) {
3036
- this._OnRepeatCallback = repeat_callback;
3037
- } else {
3038
- this._OnRepeatCallback = null;
3039
- }
3040
- return this;
3041
- }
3042
-
3043
- start(end_callback, advance_callback) {
3044
- // 取消旧的Callback
3045
- this._NextEndCallback = end_callback;
3046
- this._EndCallback = null;
3047
- this._AdvanceCallback = advance_callback;
3048
- this._StartSwitcher = true;
3049
- this._Jumping = false;
3050
- this._StateMachineNext();
3051
- }
3052
-
3053
- pause(paused_callback) {
3054
- this._AdvanceCallback = null;
3055
-
3056
- // 执行pause动作时,相当于取消start()动作,所以EndCallback同时也应该被取消
3057
- if (this._EndCallback !== null || this._NextEndCallback !== null) {
3058
- this._EndCallback = null;
3059
- this._NextEndCallback = null;
3060
- }
3061
-
3062
- // 根据当前状态,已经处于Pause则直接回调,否则发送pause指令
3063
- if (this._StateIndex === 0) {
3064
- if (paused_callback) {
3065
- this._CallbackWithCatch(this._Current, paused_callback);
3066
- }
3067
- } else {
3068
- if (paused_callback) {
3069
- this._PausedCallback = paused_callback;
3070
- }
3071
- this._StateMachineNext();
3072
- }
3073
- }
3074
-
3075
- jump() {
3076
- this._JumpTarget = [...this._Target];
3077
- this._Jumping = true;
3078
- this._StartSwitcher = true;
3079
- this._StateMachineNext();
3080
- }
3081
-
3082
- jumpSilent() {
3083
- this._JumpTarget = [...this._Target];
3084
- }
3085
-
3086
- startFpsTesting() {
3087
- Forge.sRenderBridge.SetStepFpsSwitch(true);
3088
- }
3089
-
3090
- stopFpsTesting() {
3091
- Forge.sRenderBridge.SetStepFpsSwitch(false);
3092
- }
3093
-
3094
- _WrapBuildAnimation(repeat_start_array, current_array, tos_array, act_jump) {
3095
- console.warn("Should Override");
3096
- }
3097
-
3098
- _WrapCallback(currents, callback) {
3099
- console.warn("Should Override");
3100
- }
3101
-
3102
- _CallbackWithCatch(currents, callback) {
3103
- try {
3104
- this._WrapCallback(currents, callback);
3105
- } catch (e) {
3106
- console.error("Error:in callback");
3107
- console.error(e);
3108
- }
3109
- }
3110
-
3111
- _StateMachineNext() {
3112
- if (this._StateLocked) {
3113
- // 内部处理进行中,暂停状态切换
3114
- return;
3115
- }
3116
-
3117
- if (this._StateIndex === 0) {
3118
- // Idle -> play, need switcher
3119
- if (this._StartSwitcher) {
3120
- this._StartSwitcher = false;
3121
- if (this._StartAnimation()) {
3122
- this._StateIndex = 1;
3123
- }
3124
- }
3125
- } else if (this._StateIndex === 1) {
3126
- // Play -> idle, no need switcher
3127
- this._StopAnimation();
3128
- }
3129
- }
3130
-
3131
- _StartAnimation() {
3132
- // 当动画开始后才进行回调设置,防止Pause过程中直接调用了新设置进的回调
3133
- this._EndCallback = this._NextEndCallback;
3134
- this._NextEndCallback = null;
3135
-
3136
- const froms = this._JumpTarget ? [...this._JumpTarget] : [...this._Current];
3137
- const tos = this._Target;
3138
- const repeat_starts = this._Repeat ? [...this._RepeatStart] : null;
3139
-
3140
- // const token = this._Token++;
3141
-
3142
- const anim = this._WrapBuildAnimation(
3143
- repeat_starts,
3144
- froms,
3145
- tos,
3146
- this._Jumping
3147
- );
3148
-
3149
- // clear jump status
3150
- this._JumpTarget = null;
3151
- this._Jumping = false;
3152
-
3153
- if (anim === null) {
3154
- return;
3155
- }
3156
-
3157
- // 生成OnFinalProgress处理监听,memo在 _WrapBuildAnimation()处理后生成,因为build处理中可能改变tos
3158
- const memo_tos = [...tos];
3159
- const that = this;
3160
- const listener = new Forge.AnimationListener()
3161
- .OnFinalProgress((progress) => {
3162
- that._OnPaused(
3163
- repeat_starts !== null ? repeat_starts : froms,
3164
- memo_tos,
3165
- progress
3166
- );
3167
- })
3168
- .OnAdvance((progress) => {
3169
- if (this._AdvanceCallback) {
3170
- this._AdvanceCallback(progress);
3171
- }
3172
- });
3173
-
3174
- if (this._OnRepeatCallback) {
3175
- listener.OnRepeat((times) => {
3176
- if (that._OnRepeatCallback) {
3177
- that._OnRepeatCallback(times);
3178
- }
3179
- });
3180
- }
3181
-
3182
- anim.AddAnimationListener(listener);
3183
- anim.Enable(Forge.AnimationEnable.KeepTransform);
3184
- if (this._Repeat) {
3185
- anim.EnableInfinite();
3186
- }
3187
- this._SpriteView.StartAnimation(anim);
3188
-
3189
- return true; // success
3190
- }
3191
-
3192
- _StopAnimation() {
3193
- this._SpriteView.StopAnimation();
3194
- }
3195
-
3196
- _OnPaused(froms, tos, progress) {
3197
- for (let i = 0; i < this._ParameterCount; i++) {
3198
- this._Current[i] = Math.floor((tos[i] - froms[i]) * progress + froms[i]);
3199
- }
3200
-
3201
- this._StateLocked = true;
3202
- // 换出callbacks,回调时可能加入新的callbacks
3203
- const paused_callback = this._PausedCallback;
3204
- const ended_callback = this._EndCallback;
3205
- this._PausedCallback = null;
3206
-
3207
- // 回调所有callback
3208
- if (paused_callback) {
3209
- // Paused callback
3210
- this._CallbackWithCatch(this._Current, paused_callback);
3211
- }
3212
- if (ended_callback && progress === 1) {
3213
- // Ended callback
3214
- this._EndCallback = null;
3215
- this._CallbackWithCatch(this._Current, ended_callback);
3216
- }
3217
-
3218
- this._StateLocked = false;
3219
-
3220
- this._StateIndex = 0; // mark idle
3221
- const that = this;
3222
- that._StateMachineNext(); // Trigger next start
3223
- }
3224
-
3225
- _SetView(jsv_view) {
3226
- this._SpriteView = jsv_view;
3227
- }
3228
- }
3229
- class DragTranslateControl extends JsvControl {
3230
- constructor() {
3231
- super(2); // targetX, targetY, accelerate, init velocity
3232
- this._Mode = 0; // 0: 匀速控制模式, 1: 加减速控制模式
3233
- this._Speed = 0; // pixel per second
3234
- this._VerlocityAcc = 0; // 加速度值
3235
- this._VerlocityInit = 0; // 初始速度
3236
- this._AccAlongX = true; // true 延X轴加速, false 延Y轴加速
3237
- this._AnimationRef = null;
3238
- this._AllowFrameStep = false; // 是否可以使用FrameStep模式,该模式下为了保证动画的平滑性,动画总运行时间会超过设定时间
3239
- }
3240
-
3241
- allowFrameStepMode(allow) {
3242
- this._AllowFrameStep = allow;
3243
- return this;
3244
- }
3245
-
3246
- selectMode(mode) {
3247
- switch (mode) {
3248
- case "UniformMotion":
3249
- this._Mode = 0;
3250
- break;
3251
- case "AcceleratedMotion":
3252
- this._Mode = 1;
3253
- this.setRepeat(false); // 加速模式不支持repeat
3254
- break;
3255
- default:
3256
- console.error(`Unsupported input=${mode}`);
3257
- }
3258
-
3259
- return this;
3260
- }
3261
-
3262
- targetX(new_x) {
3263
- // Take effect in next Start
3264
- this._Target[0] = new_x;
3265
- return this;
3266
- }
3267
-
3268
- targetY(new_y) {
3269
- // Take effect in next Start
3270
- this._Target[1] = new_y;
3271
- return this;
3272
- }
3273
-
3274
- target(new_x, new_y) {
3275
- // Take effect in next Start
3276
- this._Target[0] = new_x;
3277
- this._Target[1] = new_y;
3278
- return this;
3279
- }
3280
-
3281
- // start_x, start_y,必须要在当前位置到target的范围之外,范围之内目前不支持
3282
- enableRepeatFrom(start_x, start_y, repeat_callback) {
3283
- if (!this._ComfirmMode(0)) return;
3284
-
3285
- this.setRepeat(true, repeat_callback);
3286
- this._RepeatStart[0] = start_x;
3287
- this._RepeatStart[1] = start_y;
3288
- return this;
3289
- }
3290
-
3291
- speed(pixel_per_second) {
3292
- console.log(`speed, pixel_per_second:${pixel_per_second}`);
3293
- if (!this._ComfirmMode(0)) return;
3294
-
3295
- // Take effect in next Start
3296
- this._Speed = pixel_per_second;
3297
- return this;
3298
- }
3299
-
3300
- // Start后,从当前位置到目标位置后动画结束
3301
- accelerateX(acc_x, target_x) {
3302
- if (!this._ComfirmMode(1)) return;
3303
-
3304
- this._Target[0] = target_x;
3305
- this._VerlocityAcc = acc_x;
3306
- this._VerlocityInit = 0;
3307
- this._AccAlongX = true;
3308
- return this;
3309
- }
3310
-
3311
- accelerateY(acc_y, target_y) {
3312
- if (!this._ComfirmMode(1)) return;
3313
-
3314
- this._Target[1] = target_y;
3315
- this._VerlocityAcc = acc_y;
3316
- this._VerlocityInit = 0;
3317
- this._AccAlongX = false;
3318
- return this;
3319
- }
3320
-
3321
- decelerateX(acc_x, init_v_x) {
3322
- if (!this._ComfirmMode(1)) return;
3323
-
3324
- this._VerlocityAcc = acc_x;
3325
- this._VerlocityInit = init_v_x;
3326
- this._AccAlongX = true;
3327
- return this;
3328
- }
3329
-
3330
- decelerateY(acc_y, init_v_y) {
3331
- if (!this._ComfirmMode(1)) return;
3332
-
3333
- this._VerlocityAcc = acc_y;
3334
- this._VerlocityInit = init_v_y;
3335
- this._AccAlongX = false;
3336
- return this;
3337
- }
3338
-
3339
- // Start后,当减速到0时结束动画
3340
- decelerate(acc_x, acc_y, init_v_x, init_v_y) {
3341
- if (this._Mode !== 1) {
3342
- console.error("Error: mode error");
3343
- return;
3344
- }
3345
-
3346
- this._VerlocityAcc[0] = acc_x;
3347
- this._VerlocityAcc[1] = acc_y;
3348
- this._VerlocityInit[0] = init_v_x;
3349
- this._VerlocityInit[1] = init_v_y;
3350
- return this;
3351
- }
3352
-
3353
- _ComfirmMode(mode) {
3354
- if (this._Mode !== mode) {
3355
- console.error("Error: mode error");
3356
- return false;
3357
- }
3358
- return true;
3359
- }
3360
-
3361
- // Override
3362
- _WrapBuildAnimation(repeat_start_array, current_array, tos_array, act_jump) {
3363
- if (act_jump) {
3364
- this._AnimationRef = this._UniformMove(
3365
- null,
3366
- current_array,
3367
- tos_array,
3368
- act_jump
3369
- );
3370
- } else {
3371
- if (this._Mode === 0) {
3372
- this._AnimationRef = this._UniformMove(
3373
- repeat_start_array,
3374
- current_array,
3375
- tos_array,
3376
- false
3377
- );
3378
- } else if (this._Mode === 1) {
3379
- this._AnimationRef = this._AccelerMove(current_array, tos_array);
3380
- }
3381
- }
3382
- return this._AnimationRef;
3383
- }
3384
-
3385
- _UniformMove(repeat_start_array, current_array, tos_array, act_jump) {
3386
- let from_x = 0;
3387
- let from_y = 0;
3388
- let start_pos = 0.0;
3389
- let animate_time = 1;
3390
-
3391
- const current_x = current_array[0];
3392
- const current_y = current_array[1];
3393
- const to_x = tos_array[0];
3394
- const to_y = tos_array[1];
3395
-
3396
- if (repeat_start_array !== null) {
3397
- from_x = repeat_start_array[0];
3398
- from_y = repeat_start_array[1];
3399
- const distance = this._Distance(current_x, current_y, to_x, to_y);
3400
- const distance_total = this._Distance(from_x, from_y, to_x, to_y);
3401
- start_pos = (distance_total - distance) / distance_total;
3402
- if (!act_jump) {
3403
- animate_time = (distance_total * 1000) / this._Speed;
3404
- }
3405
- } else {
3406
- from_x = current_x;
3407
- from_y = current_y;
3408
- start_pos = 0.0;
3409
- if (!act_jump) {
3410
- animate_time =
3411
- (this._Distance(current_x, current_y, to_x, to_y) * 1000) /
3412
- this._Speed;
3413
- }
3414
- }
3415
-
3416
- if (!act_jump && animate_time === 0) {
3417
- console.warn("Discard starting request for no distance");
3418
- // 但动画仍然会执行,为了能正常触发回调
3419
- }
3420
-
3421
- let anim = null;
3422
- if (
3423
- (from_x === to_x || from_y === to_y) &&
3424
- !act_jump &&
3425
- this._AllowFrameStep &&
3426
- window.JsView
3427
- ) {
3428
- // 单轴动画时,使用Frame animation来提升平滑性
3429
- console.log("Using frame translate animation");
3430
- let position_from = 0;
3431
- let position_target = 0;
3432
- let affect_x = true;
3433
- if (from_x !== to_x) {
3434
- // X轴方向上的移动
3435
- position_from = from_x;
3436
- position_target = to_x;
3437
- affect_x = true;
3438
- } else {
3439
- // Y轴方向上的移动
3440
- position_from = from_y;
3441
- position_target = to_y;
3442
- affect_x = false;
3443
- }
3444
- anim = new Forge.TranslateFrameAnimation(
3445
- position_from,
3446
- position_target,
3447
- this._Speed,
3448
- affect_x
3449
- );
3450
- } else {
3451
- // 创建普通的平移动画
3452
- anim = new Forge.TranslateAnimation(
3453
- from_x,
3454
- to_x,
3455
- from_y,
3456
- to_y,
3457
- animate_time,
3458
- null
3459
- );
3460
- }
3461
-
3462
- if (start_pos !== 0) {
3463
- if (start_pos < 0) {
3464
- console.warn("Warning: start position out of repeating range");
3465
- } else {
3466
- anim.SetStartPos(start_pos);
3467
- }
3468
- }
3469
- return anim;
3470
- }
3471
-
3472
- _AccelerMove(current_array, tos_array) {
3473
- const current = this._AccAlongX ? current_array[0] : current_array[1];
3474
- const init_v = this._VerlocityInit;
3475
- const acc = this._VerlocityAcc;
3476
-
3477
- let target;
3478
- let time;
3479
- let is_acc_up = true;
3480
-
3481
- if (acc === 0) {
3482
- console.error("Error: no found acceleration");
3483
- return;
3484
- }
3485
-
3486
- if (init_v === 0) {
3487
- // 加速度运动,终点为target x,y
3488
- target = this._AccAlongX ? tos_array[0] : tos_array[1];
3489
-
3490
- // d = 0.5 * acc * time^2 ==> time = sqrt(d * 2 / acc)
3491
- time = Math.floor(
3492
- Math.sqrt((Math.abs(target - current) * 2) / acc) * 1000
3493
- );
3494
- is_acc_up = true;
3495
- } else {
3496
- // 减速运动
3497
- time = Math.floor((Math.abs(init_v) * 1000) / acc);
3498
- target = current + Math.floor(0.0005 * init_v * time);
3499
- is_acc_up = false;
3500
- }
3501
-
3502
- if (time === 0) {
3503
- // no move,但动画仍然会执行,为了能正常触发回调
3504
- console.warn("no moved...");
3505
- }
3506
-
3507
- // Update target memo
3508
- let target_x;
3509
- let target_y;
3510
- if (this._AccAlongX) {
3511
- target_x = target;
3512
- this._Target[0] = target_x;
3513
- target_y = this._Target[1];
3514
- } else {
3515
- target_x = this._Target[0];
3516
- target_y = target;
3517
- this._Target[1] = target_y;
3518
- }
3519
-
3520
- return new Forge.TranslateAnimation(
3521
- current_array[0],
3522
- target_x,
3523
- current_array[1],
3524
- target_y,
3525
- time,
3526
- is_acc_up ? Forge.Easing.Circular.In : Forge.Easing.Circular.Out
3527
- );
3528
- }
3529
-
3530
- _Distance(from_x, from_y, to_x, to_y) {
3531
- const dx = to_x - from_x;
3532
- const dy = to_y - from_y;
3533
- return Math.sqrt(dx * dx + dy * dy);
3534
- }
3535
-
3536
- // Override
3537
- _WrapCallback(currents, callback) {
3538
- this._AnimationRef = null; // un-reference
3539
- if (callback) {
3540
- callback(currents[0], currents[1]);
3541
- }
3542
- }
3543
- }
3544
-
3545
- Forge.DragTranslateControl = DragTranslateControl;