@shijiu/jsview-vue 0.9.254 → 0.9.267

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 (168) hide show
  1. package/dom/bin/package.json +11 -11
  2. package/dom/browser-root-style.css +21 -21
  3. package/loader/jsview-main.js +41 -41
  4. package/loader/jsview.config.default.js +37 -37
  5. package/loader/jsview.default.config.js +37 -37
  6. package/package.json +1 -5
  7. package/samples/AdvanceMetroWidget/App.vue +122 -122
  8. package/samples/AdvanceMetroWidget/Frame.vue +100 -100
  9. package/samples/AdvanceMetroWidget/Item.vue +57 -57
  10. package/samples/AdvanceMetroWidget/data.js +136 -136
  11. package/samples/AnimPicture/App.vue +223 -223
  12. package/samples/Basic/App.vue +128 -128
  13. package/samples/Basic/components/TitleBar.vue +28 -28
  14. package/samples/Basic/components/anim/AnimGroup.vue +67 -67
  15. package/samples/Basic/components/anim/AnimKeyframeBasic.vue +101 -101
  16. package/samples/Basic/components/anim/AnimKeyframeComposite.vue +52 -52
  17. package/samples/Basic/components/anim/AnimTransition.vue +116 -116
  18. package/samples/Basic/components/div/DivBackground.vue +14 -14
  19. package/samples/Basic/components/div/DivClip.vue +80 -80
  20. package/samples/Basic/components/div/DivCssScoped.vue +26 -26
  21. package/samples/Basic/components/div/DivCssVar.vue +49 -49
  22. package/samples/Basic/components/div/DivGroup1.vue +32 -32
  23. package/samples/Basic/components/div/DivGroup2.vue +40 -40
  24. package/samples/Basic/components/div/DivLayout.vue +11 -11
  25. package/samples/Basic/components/div/DivRadius.vue +46 -46
  26. package/samples/Basic/components/text/TextAlign.vue +47 -47
  27. package/samples/Basic/components/text/TextFontStyle.vue +57 -57
  28. package/samples/Basic/components/text/TextGroup.vue +31 -31
  29. package/samples/Basic/components/text/TextOverflow.vue +77 -77
  30. package/samples/BasicFocusControl/App.vue +124 -124
  31. package/samples/BasicFocusControl/components/BaseBlock.vue +50 -50
  32. package/samples/BasicFocusControl/components/MainArea.vue +97 -97
  33. package/samples/BasicFocusControl/components/MainAreaLeftBlock.vue +20 -20
  34. package/samples/BasicFocusControl/components/MainAreaRightBlock.vue +29 -29
  35. package/samples/BasicFocusControl/components/SideBar.vue +72 -72
  36. package/samples/BasicFocusControl/components/SideBarBlock.vue +29 -29
  37. package/samples/ClassNameDemo/App.vue +119 -119
  38. package/samples/ClassNameDemo/components/ContentItem.vue +252 -252
  39. package/samples/ClassNameDemo/components/LoadingView.vue +43 -43
  40. package/samples/ClassNameDemo/components/TitleView.vue +24 -24
  41. package/samples/ClassNameDemo/data.js +24 -24
  42. package/samples/ColorSpace/App.vue +134 -134
  43. package/samples/DemoHomepage/App.vue +31 -31
  44. package/samples/DemoHomepage/components/BodyFrame.vue +81 -81
  45. package/samples/DemoHomepage/components/Dialog.vue +93 -93
  46. package/samples/DemoHomepage/components/Item.vue +76 -76
  47. package/samples/DemoHomepage/components/TabFrame.vue +86 -86
  48. package/samples/DemoHomepage/router.js +132 -132
  49. package/samples/DemoHomepage/views/Homepage.vue +186 -186
  50. package/samples/FlipCard/App.vue +80 -80
  51. package/samples/FlipCard/FlipCard.vue +123 -123
  52. package/samples/FlipCard/data.js +12 -12
  53. package/samples/FlowMultiWidget/App.vue +90 -90
  54. package/samples/FlowMultiWidget/components/Block.vue +106 -106
  55. package/samples/FlowMultiWidget/components/FlowPage.vue +59 -59
  56. package/samples/FlowMultiWidget/components/Item.vue +102 -102
  57. package/samples/FlowMultiWidget/components/MenuItem.vue +71 -71
  58. package/samples/FlowMultiWidget/components/MyMenu.vue +89 -89
  59. package/samples/FlowMultiWidget/data.js +446 -446
  60. package/samples/HashHistory/App.vue +124 -124
  61. package/samples/HashHistory/components/HorizontalButtonList.vue +113 -113
  62. package/samples/HashHistory/components/Item.vue +73 -73
  63. package/samples/HashHistory/router.js +29 -29
  64. package/samples/HashHistory/views/BasePage.vue +18 -18
  65. package/samples/HashHistory/views/MainPage.vue +67 -67
  66. package/samples/HashHistory/views/SubPage.vue +78 -78
  67. package/samples/HashHistory/views/SubPageFirst.vue +9 -9
  68. package/samples/HashHistory/views/SubPageSecond.vue +9 -9
  69. package/samples/LongImage/App.vue +96 -96
  70. package/samples/LongImage/Button.vue +153 -153
  71. package/samples/LongImage/LongImageScroll.vue +126 -126
  72. package/samples/LongImage/Scroll.vue +15 -15
  73. package/samples/LongText/App.vue +111 -111
  74. package/samples/LongText/Button.vue +153 -153
  75. package/samples/LongText/LongTextScroll.vue +224 -224
  76. package/samples/LongText/Scroll.vue +15 -15
  77. package/samples/Preload/App.vue +145 -145
  78. package/samples/Preload/data.js +22 -22
  79. package/samples/Preload/preloadItem.vue +21 -21
  80. package/samples/QrcodeDemo/App.vue +72 -72
  81. package/samples/SimpleWidgetDemo/App.vue +203 -203
  82. package/samples/SimpleWidgetDemo/Item.vue +82 -82
  83. package/samples/SimpleWidgetDemo/components/ContentItem.vue +411 -411
  84. package/samples/SimpleWidgetDemo/components/MyTab.vue +116 -116
  85. package/samples/SimpleWidgetDemo/data.js +110 -110
  86. package/samples/SprayView/App.vue +269 -269
  87. package/samples/SpriteImage/App.vue +174 -174
  88. package/samples/SpriteImage/images/egg_break.json +116 -116
  89. package/samples/TextBox/App.vue +178 -178
  90. package/samples/TextBox/RenderCenter.vue +108 -108
  91. package/samples/TextBox/RenderLeft.vue +108 -108
  92. package/samples/TextBox/RenderOneLine.vue +119 -119
  93. package/samples/TextBox/RenderRight.vue +106 -106
  94. package/samples/TextShadowDemo/App.vue +97 -97
  95. package/samples/TextureSize/App.vue +141 -141
  96. package/samples/ThrowMoveDemo/AccelerateDemo.vue +117 -117
  97. package/samples/ThrowMoveDemo/App.vue +113 -113
  98. package/samples/ThrowMoveDemo/LRParabolicDemo.vue +115 -115
  99. package/samples/ThrowMoveDemo/TargetDemo.vue +116 -116
  100. package/samples/ThrowMoveDemo/UDParabolicDemo.vue +121 -121
  101. package/samples/TransitPage/App.vue +40 -40
  102. package/samples/VideoDemo/App.vue +137 -137
  103. package/samples/VideoDemo/components/Button.vue +68 -68
  104. package/samples/VideoDemo/components/Controllor.vue +195 -195
  105. package/samples/VideoDemo/components/VideoFrame.vue +152 -152
  106. package/scripts/common.js +57 -115
  107. package/scripts/jsview-install-local-packages.js +73 -73
  108. package/scripts/jsview-post-build.js +127 -127
  109. package/scripts/jsview-post-install.js +78 -78
  110. package/scripts/jsview-run-android.js +64 -64
  111. package/utils/JsViewEngineWidget/bin/index.js +1 -1
  112. package/utils/JsViewEngineWidget/bin/package.json +11 -11
  113. package/utils/JsViewVueTools/JsvHashHistory.js +111 -111
  114. package/utils/JsViewVueTools/JsvRuntimeBridge.js +417 -417
  115. package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserPreload.vue +80 -80
  116. package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserQrcode.vue +147 -147
  117. package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserSpray.vue +54 -54
  118. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/ApicDataBase.js +28 -28
  119. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/BrowserApic.vue +123 -123
  120. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/GifData.js +83 -83
  121. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/LoopToolBase.js +25 -25
  122. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/NormalLoopTool.js +61 -61
  123. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/PartLoopTool.js +119 -119
  124. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/Viewer.js +106 -106
  125. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/WebpData.js +141 -141
  126. package/utils/JsViewVueWidget/BrowserDebugWidget/WidgetLoader.js +20 -20
  127. package/utils/JsViewVueWidget/JsvActorMove/ActorControlBase.js +204 -204
  128. package/utils/JsViewVueWidget/JsvActorMove/JsvActorMove.vue +63 -63
  129. package/utils/JsViewVueWidget/JsvActorMove/JsvActorMoveControl.js +426 -426
  130. package/utils/JsViewVueWidget/JsvActorMove/index.js +12 -12
  131. package/utils/JsViewVueWidget/JsvApic/JsvApic.vue +178 -178
  132. package/utils/JsViewVueWidget/JsvApic/index.js +17 -17
  133. package/utils/JsViewVueWidget/JsvMarquee.vue +196 -196
  134. package/utils/JsViewVueWidget/JsvNinePatch.vue +76 -76
  135. package/utils/JsViewVueWidget/JsvPreload/JsvPreload.vue +350 -350
  136. package/utils/JsViewVueWidget/JsvPreload/index.js +21 -21
  137. package/utils/JsViewVueWidget/JsvQrcode/JsvQrcode.vue +140 -140
  138. package/utils/JsViewVueWidget/JsvQrcode/index.js +18 -18
  139. package/utils/JsViewVueWidget/JsvSpray/JsvSpray.vue +139 -139
  140. package/utils/JsViewVueWidget/JsvSpray/index.js +14 -14
  141. package/utils/JsViewVueWidget/JsvSpriteAnim/JsvSpriteAnim.vue +447 -447
  142. package/utils/JsViewVueWidget/JsvSpriteAnim/SpriteController.js +56 -56
  143. package/utils/JsViewVueWidget/JsvSpriteAnim/index.js +6 -6
  144. package/utils/JsViewVueWidget/JsvSwiper/Indicator.vue +34 -34
  145. package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue +494 -494
  146. package/utils/JsViewVueWidget/JsvSwiper/index.js +9 -9
  147. package/utils/JsViewVueWidget/JsvSwiper3D/Indicator.vue +34 -34
  148. package/utils/JsViewVueWidget/JsvSwiper3D/JsvSwiper.vue +403 -403
  149. package/utils/JsViewVueWidget/JsvSwiper3D/index.js +9 -9
  150. package/utils/JsViewVueWidget/JsvTextBox.vue +110 -110
  151. package/utils/JsViewVueWidget/JsvVideo.vue +35 -35
  152. package/patches/node_modules/@babel/preset-env/lib/available-plugins.js +0 -219
  153. package/patches/node_modules/@vue/cli-plugin-typescript/index.js +0 -100
  154. package/patches/node_modules/@vue/cli-service/lib/commands/serve.js +0 -395
  155. package/patches/node_modules/@vue/cli-service/lib/config/app.js +0 -272
  156. package/patches/node_modules/@vue/cli-service/lib/config/assets.js +0 -70
  157. package/patches/node_modules/@vue/cli-service/lib/config/base.js +0 -212
  158. package/patches/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js +0 -2566
  159. package/patches/node_modules/@vue/compiler-sfc/dist/jsview-css-to-js.js +0 -274
  160. package/patches/node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js +0 -1596
  161. package/patches/node_modules/postcss-js/objectifier.js +0 -90
  162. package/patches/node_modules/vue-loader/dist/resolveScript.js +0 -70
  163. package/scripts/deploy-fast-pack.js +0 -17
  164. package/scripts/deploy-fast-publish.js +0 -44
  165. package/scripts/deploy-git-commit-empty.js +0 -21
  166. package/scripts/deploy-prepare.js +0 -56
  167. package/scripts/make-js.sh +0 -181
  168. package/vetur.config.js +0 -5
@@ -1,448 +1,448 @@
1
- <!--
2
- * 【模块 export 内容】
3
- * JsvSpriteAnim: React高阶组件,描画动态的精灵图(雪碧图)
4
- * prop说明:
5
- * spriteInfo {object} (必需)精灵图配置信息
6
- * { frames: [
7
- * {
8
- * source:{w,h},
9
- * target:{w,h},
10
- * },
11
- * ...
12
- * ],
13
- * meta:{w,h}
14
- * }
15
- * viewSize {object} (必需){w:0, h:0}
16
- * imageUrl {string} (必需)图片地址,另外,为了减小无效的解析处理,规定只有image的URL变更时才重新解析spriteInfo
17
- * duration {float} (动图必需)动图的时间
18
- * onAnimEnd {function} 动图结束回调
19
- * autostart {string} 启动动图,默认none,
20
- * 传入为bool类型时,兼容老版本:true为start、false为none
21
- * 自动启动模式:start:精灵图自动启动,结束后显示第一帧内容、
22
- * end:精灵图自动启动,结束后显示最后一帧内容,
23
- * none:不自动启动
24
- * loop {string} 动图的循环次数 infinite/数字,默认为infinite
25
- * spriteName {string} 动图的名称,默认为null
26
- * controller {SpriteController} 控制动图start,stop的对象
27
- *
28
- * SpriteController: 面向对象类,精灵图动作控制器
29
- * 功能函数:(参数说明见函数本体)
30
- * start()
31
- * 功能: 启动精灵图动画
32
- * stop(end_frame)
33
- * 功能: 停止精灵图动画,可选择静止在第一帧或最后一帧
34
- -->
35
- <script>
36
- import {Options, Vue} from "vue-class-component";
37
- import { getKeyFramesGroup } from '../../JsViewVueTools/JsvDynamicKeyFrames.js'
38
-
39
-
40
-
41
- function _getTransformInfo(source_obj, target_obj, canvas_width, canvas_height) {
42
- const result = { csw: 1, csh: 1, cx: 0, cy: 0, sw: 1, sh: 1, x: 0, y: 0 };
43
-
44
- // Clip在Canvas div之内,以Canvas为基准进行缩放和平移
45
- // 图形左上角远离原点后再缩放,所以需要进行缩放补偿
46
- const clip_scale_w = target_obj.w / canvas_width;
47
- const clip_scale_h = target_obj.h / canvas_height;
48
- result.csw = clip_scale_w;
49
- result.csh = clip_scale_h;
50
- result.cx = target_obj.x / clip_scale_w;
51
- result.cy = target_obj.y / clip_scale_h;
52
-
53
- // Image在Clip div之内,所以以Clip为基准进行缩放和平移, 对clip的缩放进行反处理以还原尺寸
54
- // 将子图左上角对齐原点后再缩放,所以x,y不需要进行举例缩放补偿
55
- result.sw = source_obj.w / target_obj.w / clip_scale_w;
56
- result.sh = source_obj.h / target_obj.h / clip_scale_h;
57
- result.x = -source_obj.x;
58
- result.y = -source_obj.y;
59
-
60
- return result;
61
- }
62
-
63
- function _createTransformStyle(w_scale, h_scale, x, y) {
64
- let output = "";
65
- output = `${output}scale3d(${
66
- parseFloat(w_scale).toPrecision(5)},${
67
- parseFloat(h_scale).toPrecision(5)},1) `
68
- + `translate3d(${
69
- parseFloat(x).toPrecision(5)}px,${
70
- parseFloat(y).toPrecision(5)}px,0)`;
71
- return output;
72
- }
73
-
74
- @Options({
75
- props: {
76
- spriteInfo: Object,
77
- viewSize: Object,
78
- imageUrl: String,
79
- duration: Number,
80
- onAnimEnd: Function,
81
- autostart: [Boolean, String],
82
- loop: Number,
83
- spriteName: String,
84
- controller: Object,
85
- }
86
- })
87
- class JsvSpriteAnim extends Vue {
88
- constructor(props) {
89
- super(props);
90
- let stopFrame = "start";
91
- if (typeof this.$props.autostart === "string" && this.$props.autostart !== "none") {
92
- stopFrame = this.$props.autostart;
93
- }
94
- this.TRANSFORM_ORIGIN_LEFT_TOP = "left top";
95
- this.keyFrameNames = {
96
- clip: null,
97
- image: null,
98
- valid: false
99
- };
100
- this.frozeFrameCache = {
101
- clipStyle: {},
102
- transStyle: {},
103
- imageStyle: {
104
- backgroundImage: null,
105
- }
106
- };
107
- this.animateFrameCache = {
108
- clipStyle: {},
109
- transStyle: {},
110
- imageStyle: {
111
- backgroundImage: null,
112
- },
113
- clipAnimName: null,
114
- imageAnimName: null,
115
- };
116
- this.keyFrameStyleSheet = getKeyFramesGroup(null);
117
- this.innerId = 0;
118
- this.stopped = false;
119
- this.spriteDuration = this.$props.duration;
120
- this.stopFrame = stopFrame;
121
- this.blinkAnim = null;
122
- this.blinkAnimCache = null;
123
- this.transform_style = this._AnalyzeProp();
124
- this.sAnimationToken = 0;
125
- }
126
-
127
- stop(end_frame) {
128
- if (this.$props.spriteInfo.frames && this.$props.spriteInfo.frames.length === 1) {
129
- return;
130
- }
131
- this.stopped = true;
132
- this.stopFrame = end_frame || this.stopFrame;
133
- }
134
-
135
- start(end_frame, duration) {
136
- if (this.$props.spriteInfo.frames && this.$props.spriteInfo.frames.length === 1) {
137
- return;
138
- }
139
- this.innerId += 1;
140
- this.stopped = false;
141
- this.spriteDuration = duration || this.$props.duration;
142
- this.stopFrame = end_frame || this.stopFrame;
143
- }
144
-
145
- blink(alphas, duration, ease, delay, repeat) {
146
- // 注意:比较数组是否相同仅在此场景下使用toString,其他场景
147
- if (!this.blinkAnimCache
148
- || (this.blinkAnimCache.alphas.toString() !== alphas.toString()
149
- || this.blinkAnimCache.duration !== duration
150
- || this.blinkAnimCache.ease !== ease
151
- || this.blinkAnimCache.delay !== delay
152
- || this.blinkAnimCache.repeat !== repeat)) {
153
- const anim_name_base = this._getAnimNameBase();
154
- const anim_name_blink = `${anim_name_base}-blink`;
155
- let image_keyframs = `@keyframes ${anim_name_blink} {`;
156
- const frame_percent = 1 / (alphas.length);
157
- for (let i = 0; i < alphas.length; i++) {
158
- const alpha = alphas[i];
159
- let header;
160
- if (i !== alphas.length - 1) {
161
- header = `${parseFloat(frame_percent * i * 100).toFixed(2)}% {`;
162
- } else {
163
- header = '100% {';
164
- }
165
- image_keyframs += header;
166
-
167
- if (alpha) {
168
- const tr_str = ` opacity:${alpha};`;
169
- image_keyframs += tr_str;
170
- }
171
-
172
- image_keyframs += '}';
173
- image_keyframs += "\n";
174
- }
175
- image_keyframs += '}';
176
- if (this.keyFrameStyleSheet) {
177
- this.keyFrameStyleSheet.insertRule(image_keyframs);
178
- }
179
- this.blinkAnimCache = {
180
- alphas,
181
- duration,
182
- ease,
183
- delay,
184
- repeat,
185
- blinkAnimName: anim_name_blink
186
- };
187
- }
188
-
189
- // 参数格式化
190
- ease = ease || "";
191
- delay = delay || 0;
192
- repeat = (repeat === -1) ? "infinite" : (repeat || 1);
193
-
194
- const animName = `${this.blinkAnimCache.blinkAnimName} ${duration}s ${ease} ${delay}s ${repeat}`;
195
- this.blinkAnim = animName;
196
- this.stopped = true;
197
- }
198
-
199
- _getAnimNameBase() {
200
- return this.$props.spriteName ? this.$props.spriteName : `sprite-anim-name-${this.sAnimationToken++}`;
201
- }
202
-
203
- _updateFrozeFrameCache(image_url, frame_info_list,
204
- canvas_width, canvas_height,
205
- source_width, source_height) {
206
- const cache = this.frozeFrameCache;
207
-
208
- const index = this.stopFrame === "start" ? 0 : frame_info_list.length - 1;
209
- const tr = _getTransformInfo(
210
- frame_info_list[index].source,
211
- frame_info_list[index].target,
212
- canvas_width,
213
- canvas_height
214
- );
215
-
216
- cache.clipStyle = {
217
- transform: _createTransformStyle(tr.csw, tr.csh, tr.cx, tr.cy),
218
- transformOrigin: this.TRANSFORM_ORIGIN_LEFT_TOP,
219
- overflow: "hidden",
220
- left: 0,
221
- top: 0,
222
- width: canvas_width,
223
- height: canvas_height,
224
- };
225
-
226
- cache.transStyle = {
227
- transformOrigin: this.TRANSFORM_ORIGIN_LEFT_TOP,
228
- transform: _createTransformStyle(tr.sw, tr.sh, tr.x, tr.y),
229
- width: source_width,
230
- height: source_height,
231
- };
232
-
233
- cache.imageStyle = {
234
- backgroundImage: image_url,
235
- width: source_width,
236
- height: source_height,
237
- };
238
- }
239
-
240
- _updateAnimateFrameCache(image_url, frame_info_list,
241
- canvas_width, canvas_height,
242
- source_width, source_height) {
243
- this._clearExpiredKeyFrames();
244
-
245
- if (!frame_info_list) { return; }
246
- const anim_name_base = this._getAnimNameBase();
247
- const frame_percent = 1 / (frame_info_list.length);
248
- const anim_name_clip = `${anim_name_base}-clip`;
249
- const anim_name_image = `${anim_name_base}-image`;
250
- let image_keyframs = `@keyframes ${anim_name_image} {`;
251
- let clip_keyframs = `@keyframes ${anim_name_clip} {`;
252
-
253
- for (let i = 0; i < frame_info_list.length + 1; i++) {
254
- let item;
255
- if (i !== frame_info_list.length) {
256
- item = frame_info_list[i];
257
- } else {
258
- // 追加一个最后一帧以保证最后一帧可见
259
- item = frame_info_list[frame_info_list.length - 1];
260
- }
261
-
262
- // Header
263
- let header;
264
- if (i !== frame_info_list.length) {
265
- header = `${parseFloat(frame_percent * i * 100).toFixed(2)}% {`;
266
- } else {
267
- header = '100% {';
268
- }
269
- image_keyframs += header;
270
- clip_keyframs += header;
271
-
272
- if (item.source) {
273
- const tr = _getTransformInfo(item.source, item.target, canvas_width, canvas_height);
274
- const clip_trans = _createTransformStyle(tr.csw, tr.csh, tr.cx, tr.cy);
275
- const image_trans = _createTransformStyle(tr.sw, tr.sh, tr.x, tr.y);
276
-
277
- let tr_str = "";
278
- tr_str = `${tr_str}transform:${clip_trans};transform-origin:left top;`;
279
- clip_keyframs += tr_str;
280
-
281
- tr_str = "";
282
- tr_str = `${tr_str}transform:${image_trans};transform-origin:left top;`;
283
- image_keyframs += tr_str;
284
- }
285
-
286
- image_keyframs += '}';
287
- clip_keyframs += '}';
288
- }
289
-
290
- image_keyframs += '}';
291
- clip_keyframs += '}';
292
-
293
- if (this.keyFrameStyleSheet) {
294
- this.keyFrameStyleSheet.insertRule(image_keyframs);
295
- this.keyFrameStyleSheet.insertRule(clip_keyframs);
296
-
297
- // 记录Keyframe设置,以便于界面关闭时进行清理
298
- this.keyFrameNames.clip = anim_name_clip;
299
- this.keyFrameNames.image = anim_name_image;
300
- this.keyFrameNames.valid = true;
301
- }
302
- const cache = this.animateFrameCache;
303
-
304
- cache.clipAnimName = `${anim_name_base}-clip`;
305
- cache.imageAnimName = `${anim_name_base}-image`;
306
-
307
- cache.clipStyle = {
308
- overflow: "hidden",
309
- width: canvas_width,
310
- height: canvas_height,
311
- transform: null, // 重置 transform,以免影响keyframe动画
312
- transformOrigin: this.TRANSFORM_ORIGIN_LEFT_TOP,
313
- animation: null, // 外部设置,需要时间和loop信息
314
- };
315
-
316
- cache.transStyle = {
317
- transform: null, // 重置 transform,以免影响keyframe动画
318
- transformOrigin: this.TRANSFORM_ORIGIN_LEFT_TOP,
319
- animation: null, // 外部设置,需要时间和loop信息
320
- width: source_width,
321
- height: source_height,
322
- };
323
-
324
- cache.imageStyle = {
325
- backgroundImage: image_url,
326
- width: source_width,
327
- height: source_height,
328
- };
329
- }
330
-
331
- _clearExpiredKeyFrames() {
332
- if (this.keyFrameNames.valid) {
333
- this._removeKeyFrame([this.keyFrameNames.clip, this.keyFrameNames.image]);
334
- this.keyFrameNames.valid = false;
335
- }
336
- }
337
-
338
- _removeKeyFrame(names_array) {
339
- if (this.keyFrameStyleSheet) {
340
- this.keyFrameStyleSheet.removeMultiRules(names_array);
341
- }
342
- }
343
-
344
- _IsAutoStart() {
345
- let autoStart = false;
346
- if (typeof this.$props.autostart === "boolean") {
347
- autoStart = this.$props.autostart;
348
- } if (typeof this.$props.autostart === "string" && this.$props.autostart !== "none") {
349
- autoStart = true;
350
- }
351
- return autoStart;
352
- }
353
-
354
- _AnalyzeProp() {
355
- const used = this.$props.controller && this.$props.controller.Used;
356
- if (this.$props.spriteInfo.frames.length === 1 || (!used && !this._IsAutoStart()) || this.stopped) {
357
- // 单图模式
358
- // 解析图片信息
359
- this._updateFrozeFrameCache(
360
- this.$props.imageUrl,
361
- this.$props.spriteInfo.frames,
362
- this.$props.viewSize.w,
363
- this.$props.viewSize.h,
364
- this.$props.spriteInfo.meta.size.w,
365
- this.$props.spriteInfo.meta.size.h
366
- );
367
-
368
- return {
369
- clipStyle: this.frozeFrameCache.clipStyle,
370
- transStyle: this.frozeFrameCache.transStyle,
371
- imageStyle: this.frozeFrameCache.imageStyle,
372
- };
373
- }
374
-
375
-
376
- // 动画模式
377
- if (this.animateFrameCache.imageStyle.backgroundImage !== this.$props.imageUrl) {
378
- // 解析图片信息
379
- this._updateAnimateFrameCache(
380
- this.$props.imageUrl,
381
- this.$props.spriteInfo.frames,
382
- this.$props.viewSize.w,
383
- this.$props.viewSize.h,
384
- this.$props.spriteInfo.meta.size.w,
385
- this.$props.spriteInfo.meta.size.h
386
- );
387
- }
388
-
389
- // 使用duration和loop信息更新动画设定
390
- this.animateFrameCache.clipStyle.animation =
391
- `${this.animateFrameCache.clipAnimName} ${this.spriteDuration}s steps(1,end) ${this.$props.loop}`;
392
- this.animateFrameCache.transStyle.animation =
393
- `${this.animateFrameCache.imageAnimName} ${this.spriteDuration}s steps(1,end) ${this.$props.loop}`;
394
-
395
- return {
396
- clipStyle: this.animateFrameCache.clipStyle,
397
- transStyle: this.animateFrameCache.transStyle,
398
- imageStyle: this.animateFrameCache.imageStyle,
399
- };
400
- }
401
-
402
- // shouldComponentUpdate(next_props, next_state) {
403
- // return (
404
- // (this.$props.imageUrl !== next_props.imageUrl)
405
- // || (this.$props.onAnimEnd !== next_props.onAnimEnd)
406
- // || (this.$props.loop !== next_props.loop)
407
- // || (this.spriteDuration !== next_state.duration)
408
- // || (this.$props.autostart !== next_props.autostart)
409
- // || this.innerId !== next_state.innerId
410
- // || this.stopped !== next_state.stopped
411
- // || this.blinkAnim !== next_state.blinkAnim
412
- // );
413
- // }
414
-
415
- onAnimEndDelegate() {
416
- // 在onAnimEnd之前进行Stop,以防onAnimEnd内部继续发生别的操作
417
- this.stopped = true;
418
- if (this.$props.onAnimEnd) {
419
- this.$props.onAnimEnd();
420
- }
421
- }
422
-
423
- onBlinkAnimEnd() {
424
- // 在onAnimEnd之前进行Stop,以防onAnimEnd内部继续发生别的操作
425
- this.blinkAnim = null;
426
- }
427
-
428
- unmounted() {
429
- this._clearExpiredKeyFrames();
430
- }
431
-
432
- }
433
- export default JsvSpriteAnim;
434
- </script>
435
-
436
- <template>
437
- <div id="canvas">
438
- <div id="clip" :style="{...transform_style.clipStyle}">
439
- <div id="trans" :style="{...transform_style.transStyle}" :onAnimationEnd="onAnimEndDelegate">
440
- <div id="image" :style="{...transform_style.imageStyle, animation: blinkAnim}" :onAnimationEnd="onBlinkAnimEnd"></div>
441
- </div>
442
- </div>
443
- </div>
444
- </template>
445
-
446
- <style scoped>
447
- @keyframes sprite-tag{}
1
+ <!--
2
+ * 【模块 export 内容】
3
+ * JsvSpriteAnim: React高阶组件,描画动态的精灵图(雪碧图)
4
+ * prop说明:
5
+ * spriteInfo {object} (必需)精灵图配置信息
6
+ * { frames: [
7
+ * {
8
+ * source:{w,h},
9
+ * target:{w,h},
10
+ * },
11
+ * ...
12
+ * ],
13
+ * meta:{w,h}
14
+ * }
15
+ * viewSize {object} (必需){w:0, h:0}
16
+ * imageUrl {string} (必需)图片地址,另外,为了减小无效的解析处理,规定只有image的URL变更时才重新解析spriteInfo
17
+ * duration {float} (动图必需)动图的时间
18
+ * onAnimEnd {function} 动图结束回调
19
+ * autostart {string} 启动动图,默认none,
20
+ * 传入为bool类型时,兼容老版本:true为start、false为none
21
+ * 自动启动模式:start:精灵图自动启动,结束后显示第一帧内容、
22
+ * end:精灵图自动启动,结束后显示最后一帧内容,
23
+ * none:不自动启动
24
+ * loop {string} 动图的循环次数 infinite/数字,默认为infinite
25
+ * spriteName {string} 动图的名称,默认为null
26
+ * controller {SpriteController} 控制动图start,stop的对象
27
+ *
28
+ * SpriteController: 面向对象类,精灵图动作控制器
29
+ * 功能函数:(参数说明见函数本体)
30
+ * start()
31
+ * 功能: 启动精灵图动画
32
+ * stop(end_frame)
33
+ * 功能: 停止精灵图动画,可选择静止在第一帧或最后一帧
34
+ -->
35
+ <script>
36
+ import {Options, Vue} from "vue-class-component";
37
+ import { getKeyFramesGroup } from '../../JsViewVueTools/JsvDynamicKeyFrames.js'
38
+
39
+
40
+
41
+ function _getTransformInfo(source_obj, target_obj, canvas_width, canvas_height) {
42
+ const result = { csw: 1, csh: 1, cx: 0, cy: 0, sw: 1, sh: 1, x: 0, y: 0 };
43
+
44
+ // Clip在Canvas div之内,以Canvas为基准进行缩放和平移
45
+ // 图形左上角远离原点后再缩放,所以需要进行缩放补偿
46
+ const clip_scale_w = target_obj.w / canvas_width;
47
+ const clip_scale_h = target_obj.h / canvas_height;
48
+ result.csw = clip_scale_w;
49
+ result.csh = clip_scale_h;
50
+ result.cx = target_obj.x / clip_scale_w;
51
+ result.cy = target_obj.y / clip_scale_h;
52
+
53
+ // Image在Clip div之内,所以以Clip为基准进行缩放和平移, 对clip的缩放进行反处理以还原尺寸
54
+ // 将子图左上角对齐原点后再缩放,所以x,y不需要进行举例缩放补偿
55
+ result.sw = source_obj.w / target_obj.w / clip_scale_w;
56
+ result.sh = source_obj.h / target_obj.h / clip_scale_h;
57
+ result.x = -source_obj.x;
58
+ result.y = -source_obj.y;
59
+
60
+ return result;
61
+ }
62
+
63
+ function _createTransformStyle(w_scale, h_scale, x, y) {
64
+ let output = "";
65
+ output = `${output}scale3d(${
66
+ parseFloat(w_scale).toPrecision(5)},${
67
+ parseFloat(h_scale).toPrecision(5)},1) `
68
+ + `translate3d(${
69
+ parseFloat(x).toPrecision(5)}px,${
70
+ parseFloat(y).toPrecision(5)}px,0)`;
71
+ return output;
72
+ }
73
+
74
+ @Options({
75
+ props: {
76
+ spriteInfo: Object,
77
+ viewSize: Object,
78
+ imageUrl: String,
79
+ duration: Number,
80
+ onAnimEnd: Function,
81
+ autostart: [Boolean, String],
82
+ loop: Number,
83
+ spriteName: String,
84
+ controller: Object,
85
+ }
86
+ })
87
+ class JsvSpriteAnim extends Vue {
88
+ constructor(props) {
89
+ super(props);
90
+ let stopFrame = "start";
91
+ if (typeof this.$props.autostart === "string" && this.$props.autostart !== "none") {
92
+ stopFrame = this.$props.autostart;
93
+ }
94
+ this.TRANSFORM_ORIGIN_LEFT_TOP = "left top";
95
+ this.keyFrameNames = {
96
+ clip: null,
97
+ image: null,
98
+ valid: false
99
+ };
100
+ this.frozeFrameCache = {
101
+ clipStyle: {},
102
+ transStyle: {},
103
+ imageStyle: {
104
+ backgroundImage: null,
105
+ }
106
+ };
107
+ this.animateFrameCache = {
108
+ clipStyle: {},
109
+ transStyle: {},
110
+ imageStyle: {
111
+ backgroundImage: null,
112
+ },
113
+ clipAnimName: null,
114
+ imageAnimName: null,
115
+ };
116
+ this.keyFrameStyleSheet = getKeyFramesGroup(null);
117
+ this.innerId = 0;
118
+ this.stopped = false;
119
+ this.spriteDuration = this.$props.duration;
120
+ this.stopFrame = stopFrame;
121
+ this.blinkAnim = null;
122
+ this.blinkAnimCache = null;
123
+ this.transform_style = this._AnalyzeProp();
124
+ this.sAnimationToken = 0;
125
+ }
126
+
127
+ stop(end_frame) {
128
+ if (this.$props.spriteInfo.frames && this.$props.spriteInfo.frames.length === 1) {
129
+ return;
130
+ }
131
+ this.stopped = true;
132
+ this.stopFrame = end_frame || this.stopFrame;
133
+ }
134
+
135
+ start(end_frame, duration) {
136
+ if (this.$props.spriteInfo.frames && this.$props.spriteInfo.frames.length === 1) {
137
+ return;
138
+ }
139
+ this.innerId += 1;
140
+ this.stopped = false;
141
+ this.spriteDuration = duration || this.$props.duration;
142
+ this.stopFrame = end_frame || this.stopFrame;
143
+ }
144
+
145
+ blink(alphas, duration, ease, delay, repeat) {
146
+ // 注意:比较数组是否相同仅在此场景下使用toString,其他场景
147
+ if (!this.blinkAnimCache
148
+ || (this.blinkAnimCache.alphas.toString() !== alphas.toString()
149
+ || this.blinkAnimCache.duration !== duration
150
+ || this.blinkAnimCache.ease !== ease
151
+ || this.blinkAnimCache.delay !== delay
152
+ || this.blinkAnimCache.repeat !== repeat)) {
153
+ const anim_name_base = this._getAnimNameBase();
154
+ const anim_name_blink = `${anim_name_base}-blink`;
155
+ let image_keyframs = `@keyframes ${anim_name_blink} {`;
156
+ const frame_percent = 1 / (alphas.length);
157
+ for (let i = 0; i < alphas.length; i++) {
158
+ const alpha = alphas[i];
159
+ let header;
160
+ if (i !== alphas.length - 1) {
161
+ header = `${parseFloat(frame_percent * i * 100).toFixed(2)}% {`;
162
+ } else {
163
+ header = '100% {';
164
+ }
165
+ image_keyframs += header;
166
+
167
+ if (alpha) {
168
+ const tr_str = ` opacity:${alpha};`;
169
+ image_keyframs += tr_str;
170
+ }
171
+
172
+ image_keyframs += '}';
173
+ image_keyframs += "\n";
174
+ }
175
+ image_keyframs += '}';
176
+ if (this.keyFrameStyleSheet) {
177
+ this.keyFrameStyleSheet.insertRule(image_keyframs);
178
+ }
179
+ this.blinkAnimCache = {
180
+ alphas,
181
+ duration,
182
+ ease,
183
+ delay,
184
+ repeat,
185
+ blinkAnimName: anim_name_blink
186
+ };
187
+ }
188
+
189
+ // 参数格式化
190
+ ease = ease || "";
191
+ delay = delay || 0;
192
+ repeat = (repeat === -1) ? "infinite" : (repeat || 1);
193
+
194
+ const animName = `${this.blinkAnimCache.blinkAnimName} ${duration}s ${ease} ${delay}s ${repeat}`;
195
+ this.blinkAnim = animName;
196
+ this.stopped = true;
197
+ }
198
+
199
+ _getAnimNameBase() {
200
+ return this.$props.spriteName ? this.$props.spriteName : `sprite-anim-name-${this.sAnimationToken++}`;
201
+ }
202
+
203
+ _updateFrozeFrameCache(image_url, frame_info_list,
204
+ canvas_width, canvas_height,
205
+ source_width, source_height) {
206
+ const cache = this.frozeFrameCache;
207
+
208
+ const index = this.stopFrame === "start" ? 0 : frame_info_list.length - 1;
209
+ const tr = _getTransformInfo(
210
+ frame_info_list[index].source,
211
+ frame_info_list[index].target,
212
+ canvas_width,
213
+ canvas_height
214
+ );
215
+
216
+ cache.clipStyle = {
217
+ transform: _createTransformStyle(tr.csw, tr.csh, tr.cx, tr.cy),
218
+ transformOrigin: this.TRANSFORM_ORIGIN_LEFT_TOP,
219
+ overflow: "hidden",
220
+ left: 0,
221
+ top: 0,
222
+ width: canvas_width,
223
+ height: canvas_height,
224
+ };
225
+
226
+ cache.transStyle = {
227
+ transformOrigin: this.TRANSFORM_ORIGIN_LEFT_TOP,
228
+ transform: _createTransformStyle(tr.sw, tr.sh, tr.x, tr.y),
229
+ width: source_width,
230
+ height: source_height,
231
+ };
232
+
233
+ cache.imageStyle = {
234
+ backgroundImage: image_url,
235
+ width: source_width,
236
+ height: source_height,
237
+ };
238
+ }
239
+
240
+ _updateAnimateFrameCache(image_url, frame_info_list,
241
+ canvas_width, canvas_height,
242
+ source_width, source_height) {
243
+ this._clearExpiredKeyFrames();
244
+
245
+ if (!frame_info_list) { return; }
246
+ const anim_name_base = this._getAnimNameBase();
247
+ const frame_percent = 1 / (frame_info_list.length);
248
+ const anim_name_clip = `${anim_name_base}-clip`;
249
+ const anim_name_image = `${anim_name_base}-image`;
250
+ let image_keyframs = `@keyframes ${anim_name_image} {`;
251
+ let clip_keyframs = `@keyframes ${anim_name_clip} {`;
252
+
253
+ for (let i = 0; i < frame_info_list.length + 1; i++) {
254
+ let item;
255
+ if (i !== frame_info_list.length) {
256
+ item = frame_info_list[i];
257
+ } else {
258
+ // 追加一个最后一帧以保证最后一帧可见
259
+ item = frame_info_list[frame_info_list.length - 1];
260
+ }
261
+
262
+ // Header
263
+ let header;
264
+ if (i !== frame_info_list.length) {
265
+ header = `${parseFloat(frame_percent * i * 100).toFixed(2)}% {`;
266
+ } else {
267
+ header = '100% {';
268
+ }
269
+ image_keyframs += header;
270
+ clip_keyframs += header;
271
+
272
+ if (item.source) {
273
+ const tr = _getTransformInfo(item.source, item.target, canvas_width, canvas_height);
274
+ const clip_trans = _createTransformStyle(tr.csw, tr.csh, tr.cx, tr.cy);
275
+ const image_trans = _createTransformStyle(tr.sw, tr.sh, tr.x, tr.y);
276
+
277
+ let tr_str = "";
278
+ tr_str = `${tr_str}transform:${clip_trans};transform-origin:left top;`;
279
+ clip_keyframs += tr_str;
280
+
281
+ tr_str = "";
282
+ tr_str = `${tr_str}transform:${image_trans};transform-origin:left top;`;
283
+ image_keyframs += tr_str;
284
+ }
285
+
286
+ image_keyframs += '}';
287
+ clip_keyframs += '}';
288
+ }
289
+
290
+ image_keyframs += '}';
291
+ clip_keyframs += '}';
292
+
293
+ if (this.keyFrameStyleSheet) {
294
+ this.keyFrameStyleSheet.insertRule(image_keyframs);
295
+ this.keyFrameStyleSheet.insertRule(clip_keyframs);
296
+
297
+ // 记录Keyframe设置,以便于界面关闭时进行清理
298
+ this.keyFrameNames.clip = anim_name_clip;
299
+ this.keyFrameNames.image = anim_name_image;
300
+ this.keyFrameNames.valid = true;
301
+ }
302
+ const cache = this.animateFrameCache;
303
+
304
+ cache.clipAnimName = `${anim_name_base}-clip`;
305
+ cache.imageAnimName = `${anim_name_base}-image`;
306
+
307
+ cache.clipStyle = {
308
+ overflow: "hidden",
309
+ width: canvas_width,
310
+ height: canvas_height,
311
+ transform: null, // 重置 transform,以免影响keyframe动画
312
+ transformOrigin: this.TRANSFORM_ORIGIN_LEFT_TOP,
313
+ animation: null, // 外部设置,需要时间和loop信息
314
+ };
315
+
316
+ cache.transStyle = {
317
+ transform: null, // 重置 transform,以免影响keyframe动画
318
+ transformOrigin: this.TRANSFORM_ORIGIN_LEFT_TOP,
319
+ animation: null, // 外部设置,需要时间和loop信息
320
+ width: source_width,
321
+ height: source_height,
322
+ };
323
+
324
+ cache.imageStyle = {
325
+ backgroundImage: image_url,
326
+ width: source_width,
327
+ height: source_height,
328
+ };
329
+ }
330
+
331
+ _clearExpiredKeyFrames() {
332
+ if (this.keyFrameNames.valid) {
333
+ this._removeKeyFrame([this.keyFrameNames.clip, this.keyFrameNames.image]);
334
+ this.keyFrameNames.valid = false;
335
+ }
336
+ }
337
+
338
+ _removeKeyFrame(names_array) {
339
+ if (this.keyFrameStyleSheet) {
340
+ this.keyFrameStyleSheet.removeMultiRules(names_array);
341
+ }
342
+ }
343
+
344
+ _IsAutoStart() {
345
+ let autoStart = false;
346
+ if (typeof this.$props.autostart === "boolean") {
347
+ autoStart = this.$props.autostart;
348
+ } if (typeof this.$props.autostart === "string" && this.$props.autostart !== "none") {
349
+ autoStart = true;
350
+ }
351
+ return autoStart;
352
+ }
353
+
354
+ _AnalyzeProp() {
355
+ const used = this.$props.controller && this.$props.controller.Used;
356
+ if (this.$props.spriteInfo.frames.length === 1 || (!used && !this._IsAutoStart()) || this.stopped) {
357
+ // 单图模式
358
+ // 解析图片信息
359
+ this._updateFrozeFrameCache(
360
+ this.$props.imageUrl,
361
+ this.$props.spriteInfo.frames,
362
+ this.$props.viewSize.w,
363
+ this.$props.viewSize.h,
364
+ this.$props.spriteInfo.meta.size.w,
365
+ this.$props.spriteInfo.meta.size.h
366
+ );
367
+
368
+ return {
369
+ clipStyle: this.frozeFrameCache.clipStyle,
370
+ transStyle: this.frozeFrameCache.transStyle,
371
+ imageStyle: this.frozeFrameCache.imageStyle,
372
+ };
373
+ }
374
+
375
+
376
+ // 动画模式
377
+ if (this.animateFrameCache.imageStyle.backgroundImage !== this.$props.imageUrl) {
378
+ // 解析图片信息
379
+ this._updateAnimateFrameCache(
380
+ this.$props.imageUrl,
381
+ this.$props.spriteInfo.frames,
382
+ this.$props.viewSize.w,
383
+ this.$props.viewSize.h,
384
+ this.$props.spriteInfo.meta.size.w,
385
+ this.$props.spriteInfo.meta.size.h
386
+ );
387
+ }
388
+
389
+ // 使用duration和loop信息更新动画设定
390
+ this.animateFrameCache.clipStyle.animation =
391
+ `${this.animateFrameCache.clipAnimName} ${this.spriteDuration}s steps(1,end) ${this.$props.loop}`;
392
+ this.animateFrameCache.transStyle.animation =
393
+ `${this.animateFrameCache.imageAnimName} ${this.spriteDuration}s steps(1,end) ${this.$props.loop}`;
394
+
395
+ return {
396
+ clipStyle: this.animateFrameCache.clipStyle,
397
+ transStyle: this.animateFrameCache.transStyle,
398
+ imageStyle: this.animateFrameCache.imageStyle,
399
+ };
400
+ }
401
+
402
+ // shouldComponentUpdate(next_props, next_state) {
403
+ // return (
404
+ // (this.$props.imageUrl !== next_props.imageUrl)
405
+ // || (this.$props.onAnimEnd !== next_props.onAnimEnd)
406
+ // || (this.$props.loop !== next_props.loop)
407
+ // || (this.spriteDuration !== next_state.duration)
408
+ // || (this.$props.autostart !== next_props.autostart)
409
+ // || this.innerId !== next_state.innerId
410
+ // || this.stopped !== next_state.stopped
411
+ // || this.blinkAnim !== next_state.blinkAnim
412
+ // );
413
+ // }
414
+
415
+ onAnimEndDelegate() {
416
+ // 在onAnimEnd之前进行Stop,以防onAnimEnd内部继续发生别的操作
417
+ this.stopped = true;
418
+ if (this.$props.onAnimEnd) {
419
+ this.$props.onAnimEnd();
420
+ }
421
+ }
422
+
423
+ onBlinkAnimEnd() {
424
+ // 在onAnimEnd之前进行Stop,以防onAnimEnd内部继续发生别的操作
425
+ this.blinkAnim = null;
426
+ }
427
+
428
+ unmounted() {
429
+ this._clearExpiredKeyFrames();
430
+ }
431
+
432
+ }
433
+ export default JsvSpriteAnim;
434
+ </script>
435
+
436
+ <template>
437
+ <div id="canvas">
438
+ <div id="clip" :style="{...transform_style.clipStyle}">
439
+ <div id="trans" :style="{...transform_style.transStyle}" :onAnimationEnd="onAnimEndDelegate">
440
+ <div id="image" :style="{...transform_style.imageStyle, animation: blinkAnim}" :onAnimationEnd="onBlinkAnimEnd"></div>
441
+ </div>
442
+ </div>
443
+ </div>
444
+ </template>
445
+
446
+ <style scoped>
447
+ @keyframes sprite-tag{}
448
448
  </style>