@shijiu/jsview-vue 0.9.246 → 0.9.254

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 (173) 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 +6 -6
  7. package/patches/node_modules/@babel/preset-env/lib/available-plugins.js +218 -218
  8. package/patches/node_modules/@vue/cli-plugin-typescript/index.js +100 -100
  9. package/patches/node_modules/@vue/cli-service/lib/commands/serve.js +395 -395
  10. package/patches/node_modules/@vue/cli-service/lib/config/app.js +272 -272
  11. package/patches/node_modules/@vue/cli-service/lib/config/assets.js +70 -70
  12. package/patches/node_modules/@vue/cli-service/lib/config/base.js +212 -212
  13. package/patches/node_modules/postcss-js/objectifier.js +90 -90
  14. package/patches/node_modules/vue-loader/dist/resolveScript.js +70 -70
  15. package/samples/AdvanceMetroWidget/App.vue +122 -122
  16. package/samples/AdvanceMetroWidget/Frame.vue +100 -100
  17. package/samples/AdvanceMetroWidget/Item.vue +57 -57
  18. package/samples/AdvanceMetroWidget/data.js +136 -136
  19. package/samples/AnimPicture/App.vue +223 -223
  20. package/samples/Basic/App.vue +128 -128
  21. package/samples/Basic/components/TitleBar.vue +28 -28
  22. package/samples/Basic/components/anim/AnimGroup.vue +67 -67
  23. package/samples/Basic/components/anim/AnimKeyframeBasic.vue +101 -101
  24. package/samples/Basic/components/anim/AnimKeyframeComposite.vue +52 -52
  25. package/samples/Basic/components/anim/AnimTransition.vue +116 -116
  26. package/samples/Basic/components/div/DivBackground.vue +14 -14
  27. package/samples/Basic/components/div/DivClip.vue +80 -80
  28. package/samples/Basic/components/div/DivCssScoped.vue +26 -26
  29. package/samples/Basic/components/div/DivCssVar.vue +49 -49
  30. package/samples/Basic/components/div/DivGroup1.vue +32 -32
  31. package/samples/Basic/components/div/DivGroup2.vue +40 -40
  32. package/samples/Basic/components/div/DivLayout.vue +11 -11
  33. package/samples/Basic/components/div/DivRadius.vue +46 -46
  34. package/samples/Basic/components/text/TextAlign.vue +47 -47
  35. package/samples/Basic/components/text/TextFontStyle.vue +57 -57
  36. package/samples/Basic/components/text/TextGroup.vue +31 -31
  37. package/samples/Basic/components/text/TextOverflow.vue +77 -77
  38. package/samples/BasicFocusControl/App.vue +124 -124
  39. package/samples/BasicFocusControl/components/BaseBlock.vue +50 -50
  40. package/samples/BasicFocusControl/components/MainArea.vue +97 -97
  41. package/samples/BasicFocusControl/components/MainAreaLeftBlock.vue +20 -20
  42. package/samples/BasicFocusControl/components/MainAreaRightBlock.vue +29 -29
  43. package/samples/BasicFocusControl/components/SideBar.vue +72 -72
  44. package/samples/BasicFocusControl/components/SideBarBlock.vue +29 -29
  45. package/samples/ClassNameDemo/App.vue +119 -119
  46. package/samples/ClassNameDemo/components/ContentItem.vue +252 -252
  47. package/samples/ClassNameDemo/components/LoadingView.vue +43 -43
  48. package/samples/ClassNameDemo/components/TitleView.vue +24 -24
  49. package/samples/ClassNameDemo/data.js +24 -24
  50. package/samples/ColorSpace/App.vue +134 -134
  51. package/samples/DemoHomepage/App.vue +31 -31
  52. package/samples/DemoHomepage/components/BodyFrame.vue +81 -81
  53. package/samples/DemoHomepage/components/Dialog.vue +93 -93
  54. package/samples/DemoHomepage/components/Item.vue +76 -76
  55. package/samples/DemoHomepage/components/TabFrame.vue +86 -86
  56. package/samples/DemoHomepage/router.js +132 -132
  57. package/samples/DemoHomepage/views/Homepage.vue +186 -186
  58. package/samples/FlipCard/App.vue +80 -80
  59. package/samples/FlipCard/FlipCard.vue +123 -123
  60. package/samples/FlipCard/data.js +12 -12
  61. package/samples/FlowMultiWidget/App.vue +90 -90
  62. package/samples/FlowMultiWidget/components/Block.vue +106 -106
  63. package/samples/FlowMultiWidget/components/FlowPage.vue +59 -59
  64. package/samples/FlowMultiWidget/components/Item.vue +102 -102
  65. package/samples/FlowMultiWidget/components/MenuItem.vue +71 -71
  66. package/samples/FlowMultiWidget/components/MyMenu.vue +89 -89
  67. package/samples/FlowMultiWidget/data.js +446 -446
  68. package/samples/HashHistory/App.vue +124 -124
  69. package/samples/HashHistory/components/HorizontalButtonList.vue +113 -113
  70. package/samples/HashHistory/components/Item.vue +73 -73
  71. package/samples/HashHistory/router.js +29 -29
  72. package/samples/HashHistory/views/BasePage.vue +18 -18
  73. package/samples/HashHistory/views/MainPage.vue +67 -67
  74. package/samples/HashHistory/views/SubPage.vue +78 -78
  75. package/samples/HashHistory/views/SubPageFirst.vue +9 -9
  76. package/samples/HashHistory/views/SubPageSecond.vue +9 -9
  77. package/samples/LongImage/App.vue +96 -96
  78. package/samples/LongImage/Button.vue +153 -153
  79. package/samples/LongImage/LongImageScroll.vue +126 -126
  80. package/samples/LongImage/Scroll.vue +15 -15
  81. package/samples/LongText/App.vue +111 -111
  82. package/samples/LongText/Button.vue +153 -153
  83. package/samples/LongText/LongTextScroll.vue +224 -224
  84. package/samples/LongText/Scroll.vue +15 -15
  85. package/samples/Preload/App.vue +145 -145
  86. package/samples/Preload/data.js +22 -22
  87. package/samples/Preload/preloadItem.vue +21 -21
  88. package/samples/QrcodeDemo/App.vue +72 -72
  89. package/samples/SimpleWidgetDemo/App.vue +203 -203
  90. package/samples/SimpleWidgetDemo/Item.vue +82 -82
  91. package/samples/SimpleWidgetDemo/components/ContentItem.vue +411 -411
  92. package/samples/SimpleWidgetDemo/components/MyTab.vue +116 -116
  93. package/samples/SimpleWidgetDemo/data.js +110 -110
  94. package/samples/SprayView/App.vue +269 -269
  95. package/samples/SpriteImage/App.vue +174 -174
  96. package/samples/SpriteImage/images/egg_break.json +116 -116
  97. package/samples/TextBox/App.vue +178 -178
  98. package/samples/TextBox/RenderCenter.vue +108 -108
  99. package/samples/TextBox/RenderLeft.vue +108 -108
  100. package/samples/TextBox/RenderOneLine.vue +119 -119
  101. package/samples/TextBox/RenderRight.vue +106 -106
  102. package/samples/TextShadowDemo/App.vue +97 -97
  103. package/samples/TextureSize/App.vue +141 -141
  104. package/samples/ThrowMoveDemo/AccelerateDemo.vue +117 -117
  105. package/samples/ThrowMoveDemo/App.vue +113 -113
  106. package/samples/ThrowMoveDemo/LRParabolicDemo.vue +115 -115
  107. package/samples/ThrowMoveDemo/TargetDemo.vue +116 -116
  108. package/samples/ThrowMoveDemo/UDParabolicDemo.vue +121 -121
  109. package/samples/TransitPage/App.vue +40 -40
  110. package/samples/VideoDemo/App.vue +137 -137
  111. package/samples/VideoDemo/components/Button.vue +68 -68
  112. package/samples/VideoDemo/components/Controllor.vue +195 -195
  113. package/samples/VideoDemo/components/VideoFrame.vue +152 -152
  114. package/scripts/common.js +115 -92
  115. package/scripts/deploy-fast-pack.js +17 -0
  116. package/scripts/deploy-fast-publish.js +44 -0
  117. package/scripts/{git-commit-empty.js → deploy-git-commit-empty.js} +21 -21
  118. package/scripts/{pre-pack.js → deploy-prepare.js} +56 -39
  119. package/scripts/{install-local-packages.js → jsview-install-local-packages.js} +73 -73
  120. package/scripts/{post-build.js → jsview-post-build.js} +127 -127
  121. package/scripts/{post-install.js → jsview-post-install.js} +78 -78
  122. package/scripts/{run-android.js → jsview-run-android.js} +64 -64
  123. package/scripts/make-js.sh +181 -181
  124. package/utils/JsViewEngineWidget/bin/index.js +1 -1
  125. package/utils/JsViewEngineWidget/bin/package.json +11 -11
  126. package/utils/JsViewVueTools/JsvHashHistory.js +111 -111
  127. package/utils/JsViewVueTools/JsvRuntimeBridge.js +417 -417
  128. package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserPreload.vue +80 -80
  129. package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserQrcode.vue +147 -147
  130. package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserSpray.vue +54 -54
  131. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/ApicDataBase.js +28 -28
  132. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/BrowserApic.vue +123 -123
  133. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/GifData.js +83 -83
  134. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/LoopToolBase.js +25 -25
  135. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/NormalLoopTool.js +61 -61
  136. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/PartLoopTool.js +119 -119
  137. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/Viewer.js +106 -106
  138. package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/WebpData.js +141 -141
  139. package/utils/JsViewVueWidget/BrowserDebugWidget/WidgetLoader.js +20 -20
  140. package/utils/JsViewVueWidget/JsvActorMove/ActorControlBase.js +204 -204
  141. package/utils/JsViewVueWidget/JsvActorMove/JsvActorMove.vue +63 -63
  142. package/utils/JsViewVueWidget/JsvActorMove/JsvActorMoveControl.js +426 -426
  143. package/utils/JsViewVueWidget/JsvActorMove/index.js +12 -12
  144. package/utils/JsViewVueWidget/JsvApic/JsvApic.vue +178 -178
  145. package/utils/JsViewVueWidget/JsvApic/index.js +17 -17
  146. package/utils/JsViewVueWidget/JsvMarquee.vue +196 -196
  147. package/utils/JsViewVueWidget/JsvNinePatch.vue +76 -76
  148. package/utils/JsViewVueWidget/JsvPreload/JsvPreload.vue +350 -350
  149. package/utils/JsViewVueWidget/JsvPreload/index.js +21 -21
  150. package/utils/JsViewVueWidget/JsvQrcode/JsvQrcode.vue +140 -140
  151. package/utils/JsViewVueWidget/JsvQrcode/index.js +18 -18
  152. package/utils/JsViewVueWidget/JsvSpray/JsvSpray.vue +139 -139
  153. package/utils/JsViewVueWidget/JsvSpray/index.js +14 -14
  154. package/utils/JsViewVueWidget/JsvSpriteAnim/JsvSpriteAnim.vue +447 -447
  155. package/utils/JsViewVueWidget/JsvSpriteAnim/SpriteController.js +56 -56
  156. package/utils/JsViewVueWidget/JsvSpriteAnim/index.js +6 -6
  157. package/utils/JsViewVueWidget/JsvSwiper/Indicator.vue +34 -34
  158. package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue +494 -494
  159. package/utils/JsViewVueWidget/JsvSwiper/index.js +9 -9
  160. package/utils/JsViewVueWidget/JsvSwiper3D/Indicator.vue +34 -34
  161. package/utils/JsViewVueWidget/JsvSwiper3D/JsvSwiper.vue +403 -403
  162. package/utils/JsViewVueWidget/JsvSwiper3D/index.js +9 -9
  163. package/utils/JsViewVueWidget/JsvTextBox.vue +110 -110
  164. package/utils/JsViewVueWidget/JsvVideo.vue +35 -35
  165. package/vetur.config.js +5 -5
  166. package/.gitmodules +0 -6
  167. package/README.md +0 -15
  168. package/doc/IMPORT_CHANGE_LOG.txt +0 -3
  169. package/doc/about-project-postinstall.md +0 -0
  170. package/doc/git_commit.md +0 -15
  171. package/doc/test_version_up.txt +0 -1
  172. package/scripts/update-version.js +0 -32
  173. package/shijiu-jsview-vue-0.9.246.tgz +0 -0
@@ -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>