@shijiu/jsview-vue 2.0.1106 → 2.0.1127-next-vue.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shijiu/jsview-vue",
3
- "version": "2.0.1106",
3
+ "version": "2.0.1127-next-vue.0",
4
4
  "license": "MIT",
5
5
  "repository": "system/jsview-framework",
6
6
  "author": "mengxk",
@@ -21,6 +21,7 @@ let MediaPluginInfo = getPluginInfo();
21
21
  var mediaArray = [];
22
22
 
23
23
  var pluginLoadListener = [];
24
+ var PluginEventKey = "JsvPlayer";
24
25
 
25
26
  let LOG_LEVEL_FATAL = 5;
26
27
  let LOG_LEVEL_ERROR = 4;
@@ -69,7 +70,7 @@ function setLogLevel(level){
69
70
  */
70
71
  var pluginLoadState = 0;
71
72
 
72
- window.top.JsvPlayerPluginStatus = function(status){
73
+ function JsvPlayerPluginStatus(status){
73
74
  logDebug("JsvPlayerPluginStatus: "+status);
74
75
  let ret = JSON.parse(status);
75
76
 
@@ -86,7 +87,11 @@ window.top.JsvPlayerPluginStatus = function(status){
86
87
  }
87
88
  }
88
89
 
89
- window.top.JsvPlayerPluginLoadResult = function (result) {
90
+ window.top.JsvPlayerPluginStatus = function(status){
91
+ JsvPlayerPluginStatus(status);
92
+ }
93
+
94
+ function JsvPlayerPluginLoadResult(result){
90
95
  logDebug("JsvPlayerPluginLoadResult: "+result);
91
96
  var ret_obj = JSON.parse(result)
92
97
  let plugin_status = 1;
@@ -103,6 +108,8 @@ window.top.JsvPlayerPluginLoadResult = function (result) {
103
108
  if(pluginLoadState === 5){
104
109
  logFatal("*************************JsvPlayer plugin load failed, error code is "+ret_obj.status+"*************************");
105
110
  }
111
+
112
+ UnregisterJsvPlayerPluginEvent();
106
113
 
107
114
  for(let i=0; i<mediaArray.length; i++){
108
115
  mediaArray[i].buildPlatformInstance();
@@ -113,6 +120,10 @@ window.top.JsvPlayerPluginLoadResult = function (result) {
113
120
  }
114
121
  }
115
122
 
123
+ window.top.JsvPlayerPluginLoadResult = function (result) {
124
+ JsvPlayerPluginLoadResult(result);
125
+ }
126
+
116
127
  window.top.CreatePlayerResult = function (result) {
117
128
  logDebug("CreatePlayerResult: "+result);
118
129
  let result_obj = JSON.parse(result);
@@ -128,15 +139,59 @@ window.top.CreatePlayerResult = function (result) {
128
139
  }
129
140
  }.bind(this);
130
141
 
142
+ function JsvPlayerPluginEvent(data){
143
+ console.log("LoadPlugin2 result: "+data);
144
+ let obj = JSON.parse(data);
145
+ let event_obj = JSON.parse(obj.param);
146
+ let type = event_obj.type;
147
+ let param = event_obj.param;
148
+ if(type === 1){
149
+ JsvPlayerPluginStatus(param)
150
+ }else if(type === 2){
151
+ JsvPlayerPluginLoadResult(param);
152
+ }else{
153
+ logError("Invalid type: "+type);
154
+ }
155
+ }
156
+
157
+ function RegisterJsvPlayerPluginEvent(){
158
+ window.JMD.subscribe(PluginEventKey, JsvPlayerPluginEvent);
159
+ }
160
+
161
+ function UnregisterJsvPlayerPluginEvent(){
162
+ window.JMD.unsubscribe(PluginEventKey, JsvPlayerPluginEvent);
163
+ }
164
+
131
165
  /**
132
166
  * listener回调处理中参数信息的说明:
133
167
  * 插件加载状态回调。
134
168
  * 回调函数的参数定义如下:
135
- * 1:无法正常加载插件。
136
- * 2:正在加载旧插件,此时插件加载过程很短,可以不用出现用户提示界面。
137
- * 3:正在加载新插件,此时插件需要经历下载、解压等过程,用时较长,可以考虑给用户相关提示。
138
- * 4:插件加载完成。
139
- * 5:已加载不同版本的插件,此版本无法加载。
169
+ * object结构,包含status和code两个变量:
170
+ * 1)开始加载插件:
171
+ * obj.status=1;
172
+ * obj.code表示是否是首次加载:1:首次加载,此时插件需要经历下载、解压等过程,用时较长,可以考虑给用户相关提示;
173
+ * 2:非首次加载,此时插件加载过程很短,可以不用出现用户提示界面。
174
+ * 2)插件加载中,只在加载新插件时才会上报此状态:
175
+ * obj.status=2;
176
+ * obj.code表示加载过程中的状态:1:插件下载完成;2:插件解压完成;3:插件dexload完成。
177
+ * 3)插件加载成功
178
+ * obj.status=3;
179
+ * obj.code无效。
180
+ * 4)插件加载失败
181
+ * obj.status=4;
182
+ * obj.code表示插件加载失败原因:1:插件管理模块不存在(未真正开始加载插件),下面的负值为插件管理模块返回的错误;
183
+ * -1:请求插件加载的参数不正确,需要确认构造的PluginInfo内容;
184
+ * -2:未找到插件更新链接;
185
+ * -3:插件HTTP请求失败;
186
+ * -4:插件下载失败;
187
+ * -5:插件MD5校验失败;
188
+ * -6:解压失败;
189
+ * -7:文件大小为0;
190
+ * -8:未找到dex文件;
191
+ * -9:dex文件load失败;
192
+ * -10:插件初始化失败;
193
+ * -11:取消插件下载;
194
+ * -12:版本检查失败,比如已经加载了其他版本,此版本不能再加载。
140
195
  *
141
196
  * 备注:不管插件加载处于什么状态,都可以正常使用播放器组件,播放器对象在插件未加载完成的情况下,会把相关状态保存,等完成加载后再自动下发。
142
197
  */
@@ -171,7 +226,13 @@ function globalLoadJsvPlayerPlugin(listener){
171
226
  }
172
227
  pluginLoadState = 1;
173
228
 
174
- window.jPluginManagerBridge.LoadPlugin(JSON.stringify(MediaPluginInfo));
229
+ RegisterJsvPlayerPluginEvent();
230
+
231
+ if(typeof window.jPluginManagerBridge.LoadPlugin2 !== "undefined"){
232
+ window.jPluginManagerBridge.LoadPlugin2(PluginEventKey, JSON.stringify(MediaPluginInfo));
233
+ }else{
234
+ window.jPluginManagerBridge.LoadPlugin(JSON.stringify(MediaPluginInfo));
235
+ }
175
236
  }
176
237
 
177
238
  /**
@@ -207,6 +268,7 @@ class JsvBaseMedia {
207
268
  rate: 1.0,
208
269
  volume: 1.0,
209
270
  chromaKey: null,
271
+ audioTrack: 0,
210
272
  };
211
273
 
212
274
  this.local = {
@@ -267,10 +329,25 @@ class JsvBaseMedia {
267
329
 
268
330
  let share_view = true;
269
331
 
270
- let result = window.jsvPlayerBridge.CreatePlayer(this.key, this.windowMode, this.holeId, this.background, this.designMapWidth, share_view, this.playerType, this.decodeType, "top.CreatePlayerResult");
271
- if(result > 0){
272
- this.initPlayer();
273
- }
332
+ window.jsvPlayerBridge.CreatePlayer2(this.key, this.windowMode, this.holeId, this.background, this.designMapWidth, share_view, this.playerType, this.decodeType).then(
333
+ result=>{
334
+ logDebug("CreatePlayerResult: "+result);
335
+ let result_obj = JSON.parse(result);
336
+ if(result_obj.code == 0){
337
+ //当播放器释放后,不需要进一步进行初始化,所以这里做了查找过程,没有直接调用initPlayer接口。
338
+ for(var i=0; i<mediaArray.length; i++){
339
+ if(mediaArray[i].key === result_obj.key){
340
+ mediaArray[i].initPlayer();
341
+ break;
342
+ }
343
+ }
344
+ }else{
345
+ logError("Create player failed, key="+result_obj.key);
346
+ }
347
+ }, data=>{
348
+ logError("Create player failed, reject("+data+")");
349
+ }
350
+ );
274
351
  }
275
352
 
276
353
  /**
@@ -347,6 +424,10 @@ class JsvBaseMedia {
347
424
  if(this.state["chromaKey"]){
348
425
  this.setState("chromaKey", this.state["chromaKey"], "string");
349
426
  }
427
+
428
+ if(this.state["audioTrack"] !== 0){
429
+ this.setState("audioTrack", this.state["audioTrack"], "number");
430
+ }
350
431
  }
351
432
 
352
433
  onVisibilityChangeCallBack(){
@@ -976,6 +1057,35 @@ class JsvBaseMedia {
976
1057
  }
977
1058
  }
978
1059
 
1060
+ /**
1061
+ * 获取AudioTrack个数
1062
+ * @returns total number of audio track.
1063
+ */
1064
+ getAudioTrackCount(){
1065
+ let count = this.getProperty("audioTrackCount");
1066
+ if(count === null){
1067
+ return 1;
1068
+ }
1069
+
1070
+ return count;
1071
+ }
1072
+
1073
+ /**
1074
+ * 获取当前使用的audio track
1075
+ * @returns the current playing track
1076
+ */
1077
+ getSelectedAudioTrack(){
1078
+ return this.getState("audioTrack");
1079
+ }
1080
+
1081
+ /**
1082
+ * 选择audio track
1083
+ * @param {*} track audio track index
1084
+ */
1085
+ selectAudioTrack(track){
1086
+ this.setState("audioTrack", track, "number");
1087
+ }
1088
+
979
1089
  /**
980
1090
  * 停止视频流。
981
1091
  */
@@ -1002,6 +1112,11 @@ class JsvBaseMedia {
1002
1112
  */
1003
1113
  joinChannel(mixNo){
1004
1114
  logTrace("joinChannel, key="+this.key+", mixNo="+mixNo);
1115
+ if(this.type === "audio"){
1116
+ logWarning("Audio player do not support joinChannel.");
1117
+ return 0;
1118
+ }
1119
+
1005
1120
  let ret = this.joinChannelPrivate(mixNo);
1006
1121
  if(ret >= 0){
1007
1122
  this.currentEventStatus = EVENT_STATUS_NONE;
@@ -1011,6 +1126,11 @@ class JsvBaseMedia {
1011
1126
  }
1012
1127
 
1013
1128
  joinChannelPrivate(mixNo){
1129
+ if(this.type === "audio"){
1130
+ logWarning("Audio player do not support joinChannelPrivate.");
1131
+ return 0;
1132
+ }
1133
+
1014
1134
  if(mixNo <= 0){
1015
1135
  return -1;
1016
1136
  }
@@ -1040,6 +1160,11 @@ class JsvBaseMedia {
1040
1160
  */
1041
1161
  leaveChannel(){
1042
1162
  logTrace("leaveChannel, key="+this.key+", channelID="+this.channelID);
1163
+ if(this.type === "audio"){
1164
+ logWarning("Audio player do not support leaveChannel.");
1165
+ return 0;
1166
+ }
1167
+
1043
1168
  let ret = this.leaveChannelPrivate();
1044
1169
 
1045
1170
  this.currentEventStatus = EVENT_STATUS_NONE;
@@ -1049,6 +1174,11 @@ class JsvBaseMedia {
1049
1174
 
1050
1175
  leaveChannelPrivate(){
1051
1176
  let ret = 0;
1177
+ if(this.type === "audio"){
1178
+ logWarning("Audio player do not support leaveChannelPrivate.");
1179
+ return ret;
1180
+ }
1181
+
1052
1182
  if(this.playerCreate && this.appVisible){
1053
1183
  ret = window.jsvPlayerBridge.leaveChannel(this.key);
1054
1184
  }
@@ -1073,6 +1203,17 @@ class JsvBaseMedia {
1073
1203
  // this.setState("fastForward", value, "number");
1074
1204
  // }
1075
1205
 
1206
+ /**
1207
+ * 当流停止后,不需要显示最后一帧,调用此接口清除。
1208
+ */
1209
+ clearLastFrame(){
1210
+ logTrace("clearLastFrame, key="+this.key);
1211
+ if(typeof window.jsvPlayerBridge !== "undefined"){
1212
+ window.jsvPlayerBridge.clearLastFrame(this.key);
1213
+ }
1214
+
1215
+ return;
1216
+ }
1076
1217
  /**
1077
1218
  * @return {int} 当前音量,0-100。
1078
1219
  * */
@@ -1174,6 +1315,10 @@ class JsvBaseMedia {
1174
1315
  */
1175
1316
  setTimeShift(time){
1176
1317
  logTrace("setTimeShift, key="+this.key+", time="+time);
1318
+ if(this.type === "audio"){
1319
+ logWarning("Audio player do not support setTimeShift.");
1320
+ return;
1321
+ }
1177
1322
  if(this.playerCreate && this.appVisible){
1178
1323
  window.jsvPlayerBridge.setTimeShift(this.key, time);
1179
1324
  }
@@ -1190,6 +1335,10 @@ class JsvBaseMedia {
1190
1335
  */
1191
1336
  setChromaKey(chromaKey){
1192
1337
  logTrace("setChromaKey, key="+this.key+", chroma key="+JSON.stringify(chromaKey));
1338
+ if(this.type === "audio"){
1339
+ logWarning("Audio player do not support setChromaKey.");
1340
+ return;
1341
+ }
1193
1342
  this.setState("chromaKey", JSON.stringify(chromaKey), "string");
1194
1343
  }
1195
1344
 
@@ -1275,8 +1424,8 @@ class JsvMedia extends JsvBaseMedia {
1275
1424
  }
1276
1425
 
1277
1426
  class JsvMediaAudio extends JsvMedia {
1278
- constructor() {
1279
- super("audio", "resizable", null, null, null, null, null, 0);
1427
+ constructor(key, design_map_width) {
1428
+ super("audio", "resizable", 0, 3, key, true, design_map_width, 0);
1280
1429
  }
1281
1430
  }
1282
1431
 
@@ -1,5 +1,5 @@
1
1
  <script>
2
- import {JsvMediaVideo, findMediaObjectByKey, logDebug} from './JsvMedia'
2
+ import {JsvMediaVideo, JsvMediaAudio, findMediaObjectByKey, logDebug} from './JsvMedia'
3
3
  import JsvNativeSharedDiv from 'jsview/utils/JsViewVueWidget/JsvNativeSharedDiv.vue'
4
4
 
5
5
 
@@ -26,7 +26,7 @@ export default {
26
26
  */
27
27
  windowMode: {type: String, default: "resizable"},
28
28
  /**
29
- * 属性,int类型,底层使用的播放器类型。1:系统播放器;2:jsv播放器。默认2。
29
+ * 属性,int类型,底层使用的播放器类型。1:系统播放器;2:jsv视频播放器;3:jsv音频播放器。默认2。
30
30
  */
31
31
  playerType: {type: Number, default: 2},
32
32
  /**
@@ -170,7 +170,7 @@ export default {
170
170
  watch: {
171
171
  active(newValue) {
172
172
  logDebug("active newValue: "+newValue);
173
- if(this.video){
173
+ if(this.video && this.playerType !== 3){
174
174
  if(newValue){
175
175
  this.registerEvent();
176
176
  this.video.setHoleID(this.holeId);
@@ -188,7 +188,7 @@ export default {
188
188
  },
189
189
  style(newValue){
190
190
  logDebug("holeStyle newValue: left="+newValue.left+", top="+newValue.top+", width="+newValue.width+", height="+newValue.height);
191
- if(this.active){
191
+ if(this.active && this.playerType !== 3){
192
192
  this.holeStyle = {
193
193
  left: 0, top: 0,
194
194
  width:newValue.width, height:newValue.height
@@ -226,7 +226,7 @@ export default {
226
226
  }
227
227
  logDebug("player key:"+key)
228
228
 
229
- let player_type = 1;
229
+ let player_type = 2;
230
230
  if(this.playerType)
231
231
  player_type = this.playerType;
232
232
 
@@ -243,7 +243,11 @@ export default {
243
243
  let first_create = true;
244
244
 
245
245
  if(!this.video){
246
- this.video = new JsvMediaVideo(this.holeId, this.windowMode, player_type, key, background, designMap.width, this.decodeType);
246
+ if(player_type === 3){
247
+ this.video = new JsvMediaAudio(key, designMap.width);
248
+ }else{
249
+ this.video = new JsvMediaVideo(this.holeId, this.windowMode, player_type, key, background, designMap.width, this.decodeType);
250
+ }
247
251
  }else{
248
252
  this.video.setRef();
249
253
  first_create = false;
@@ -286,10 +290,12 @@ export default {
286
290
  //}else{
287
291
  if(!first_create){
288
292
  this.video.setHoleID(this.holeId);
289
- this.holeStyle = {
290
- left: 0, top: 0,
291
- width: this.style.width, height: this.style.height
292
- };
293
+ if(this.playerType !== 3){
294
+ this.holeStyle = {
295
+ left: 0, top: 0,
296
+ width: this.style.width, height: this.style.height
297
+ };
298
+ }
293
299
  }
294
300
  }
295
301
 
@@ -318,10 +324,12 @@ export default {
318
324
  this.video.addEventListener("timeupdate", this.onTimeUpdate);
319
325
  this.video.addEventListener("loadstart", () => {
320
326
  logDebug("JsvPlayer received loadstart event.");
321
- this.holeStyle = {
322
- left: 0, top: 0,
323
- width:this.style.width, height:this.style.height
324
- };
327
+ if(this.playerType !== 3){
328
+ this.holeStyle = {
329
+ left: 0, top: 0,
330
+ width:this.style.width, height:this.style.height
331
+ };
332
+ }
325
333
  this.onLoadStart();
326
334
  });
327
335
  this.video.addEventListener("canplaythrough", this.onCanPlayThrough);
@@ -349,7 +357,9 @@ export default {
349
357
  </script>
350
358
 
351
359
  <template>
352
- <div :style="style" backgroundColor="rgba(0,0,0,1)">
360
+ <div
361
+ v-if="playerType!=3"
362
+ :style="style" backgroundColor="rgba(0,0,0,1)">
353
363
  <JsvNativeSharedDiv :style="holeStyle" :getId="getHoleId"></JsvNativeSharedDiv>
354
364
  </div>
355
365
  </template>
@@ -1,18 +1,18 @@
1
- let PluginInfo={
2
- // downloadUrl:"http://192.168.0.85:8080/plugin/JsvPlayer-203.zip", //插件下载地址
3
- packageName:"com.qcode.jsvplayer",
4
- name:"播放器插件",
5
- version:"2.0.4", //插件需要的版本号
6
- versionCodeMin:204,
7
- versionCodeMax:204,
8
- bridgeName:"jsvPlayerBridge", //插件bridge注册到jsview的名称
9
- className:"com.qcode.jsvplayer.JsvPlayer", //插件初始化类名称
10
- initMethod:"createInstance", //插件初始化方法
11
- listener:"top.JsvPlayerPluginLoadResult", //插件加载结果回调
1
+ let PluginInfo = {
2
+ // downloadUrl:"http://192.168.0.85:8080/plugin/JsvPlayer-208.zip", //插件下载地址
3
+ packageName: "com.qcode.jsvplayer",
4
+ name: "播放器插件",
5
+ version: "2.0.9", //插件需要的版本号
6
+ versionCodeMin: 209,
7
+ versionCodeMax: 209,
8
+ bridgeName: "jsvPlayerBridge", //插件bridge注册到jsview的名称
9
+ className: "com.qcode.jsvplayer.JsvPlayer", //插件初始化类名称
10
+ initMethod: "createInstance", //插件初始化方法
11
+ listener: "top.JsvPlayerPluginLoadResult", //插件加载结果回调
12
12
  listener2: "top.JsvPlayerPluginStatus",
13
13
  // debug:true,
14
- md5:"7aa897a8ff6f6a09d2522cf93c3a083e"
14
+ md5: "4aee086cdab079baa7aacf7f0e915b48"
15
15
  };
16
16
 
17
17
  // 导出字段要含有 pluginVersionInfo 信息,作为npm时版本参考
18
- export default PluginInfo;
18
+ export default PluginInfo;
@@ -64,10 +64,17 @@ class JsvHashHistory {
64
64
  const initHash = this.#getInitHash();
65
65
  if(initHash) {
66
66
  // 已设置hash,替换到hash页面
67
- history.replace({
68
- path: initHash.substring(1),// 去除#
69
- query: window.location.search
70
- });
67
+ const replaceTo = {
68
+ path: initHash.substring(1), // 去除#
69
+ query: undefined,
70
+ }
71
+
72
+ const queryIdx = initHash.indexOf('?');
73
+ if(queryIdx >= 0) {
74
+ replaceTo.path = replaceTo.path.substring(0, queryIdx - 1),
75
+ replaceTo.query = this.#convertUrlParams(initHash.substring(queryIdx));
76
+ }
77
+ history.replace(replaceTo);
71
78
  } else {
72
79
  // 未设置hash定位,追加hash根的显示
73
80
  this.#updateLocation(null);
@@ -105,9 +112,39 @@ class JsvHashHistory {
105
112
  }
106
113
  }
107
114
 
115
+ #convertUrlParams(value) {
116
+ // 去除问号
117
+ const questionMarkIdx = value.indexOf('?');
118
+ if(questionMarkIdx >= 0) {
119
+ value = value.substr(questionMarkIdx + 1);
120
+ }
121
+
122
+ // 分割参数
123
+ var paramArray = value.split('&');
124
+ var result = {};
125
+
126
+ // 遍历参数并解析键值对
127
+ for(const param of paramArray) {
128
+ const [key, value] = param.split('=');
129
+
130
+ // 如果键已存在,则将值转换为数组
131
+ if (result.hasOwnProperty(key)) {
132
+ if (!Array.isArray(result[key])) {
133
+ result[key] = [result[key]];
134
+ }
135
+ result[key].push(value);
136
+ } else {
137
+ result[key] = value;
138
+ }
139
+ };
140
+
141
+ return result;
142
+ }
143
+
108
144
  #history;
109
145
  }
110
146
 
147
+
111
148
  function jsvCreateHashHistory(base) {
112
149
  return new JsvHashHistory(base)
113
150
  }
@@ -35,7 +35,7 @@
35
35
  <script setup>
36
36
  import { getKeyFramesGroup } from '../../JsViewVueTools/JsvDynamicKeyFrames.js'
37
37
  import { reactive, shallowRef, onUnmounted, watch } from 'vue';
38
-
38
+ import {getsAnimationToken} from "./sAnimationToken.js"
39
39
 
40
40
  const _getTransformInfo = (source_obj, target_obj, canvas_width, canvas_height) => {
41
41
  const result = { csw: 1, csh: 1, cx: 0, cy: 0, sw: 1, sh: 1, x: 0, y: 0 };
@@ -73,7 +73,7 @@
73
73
  duration: Number,
74
74
  onAnimEnd: Function,
75
75
  autostart: [Boolean, String],
76
- loop: [String,Number],
76
+ loop: [String, Number],
77
77
  spriteName: String,
78
78
  controller: Object,
79
79
  })
@@ -108,7 +108,6 @@
108
108
  let spriteDuration = shallowRef(props.duration);
109
109
  let blinkAnim = shallowRef(null);
110
110
  let blinkAnimCache = reactive({});
111
- let sAnimationToken = shallowRef(0);
112
111
 
113
112
  const _removeKeyFrame = (names_array) => {
114
113
  if (keyFrameStyleSheet) {
@@ -128,7 +127,7 @@
128
127
  })
129
128
 
130
129
  const _getAnimNameBase = () => {
131
- return props.spriteName ? props.spriteName : `sprite-anim-name-${sAnimationToken.value++}`;
130
+ return props.spriteName ? props.spriteName : `sprite-anim-name-${getsAnimationToken()}`;
132
131
  }
133
132
 
134
133
  const _updateFrozeFrameCache = (image_url, frame_info_list,
@@ -324,7 +323,6 @@
324
323
  })
325
324
  const onAnimEndDelegate = () => {
326
325
  // 在onAnimEnd之前进行Stop,以防onAnimEnd内部继续发生别的操作
327
- stopped.value = true;
328
326
  if (props.onAnimEnd) {
329
327
  props.onAnimEnd();
330
328
  }
@@ -413,9 +411,9 @@
413
411
 
414
412
  <template>
415
413
  <div id="canvas">
416
- <div id="clip" :style="{ ...transform_style.clipStyle }">
417
- <div id="trans" :style="{ ...transform_style.transStyle }" @animationend="onAnimEndDelegate">
418
- <div id="image" :style="{ ...transform_style.imageStyle, animation: blinkAnim }"
414
+ <div id="clip" :style="{ ...transform_style.clipStyle }" :key="innerId">
415
+ <div id="trans" :style="{ ...transform_style.transStyle }" @animationend="onAnimEndDelegate" :key="innerId">
416
+ <div id="image" :style="{ ...transform_style.imageStyle, animation: blinkAnim }" :key="innerId"
419
417
  @animationend="onBlinkAnimEnd"></div>
420
418
  </div>
421
419
  </div>
@@ -0,0 +1,9 @@
1
+ let sAnimationToken=0
2
+
3
+ const getsAnimationToken=()=>{
4
+ return sAnimationToken++
5
+ }
6
+
7
+ export{
8
+ getsAnimationToken
9
+ }