@shijiu/jsview-vue 2.3.0 → 2.3.151-test.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/bin/browser/BrowserAudio.vue.mjs +4 -1
- package/bin/jsview-vue.mjs +2200 -466
- package/bin/types/utils/JsViewEngineWidget/JsvFocus/JsvFocusHub.d.ts +21 -1
- package/bin/types/utils/JsViewEngineWidget/MetroWidget/RenderItem.d.ts +5 -1
- package/bin/types/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.d.ts +2 -1
- package/bin/types/utils/JsViewEngineWidget/WidgetCommon.d.ts +10 -7
- package/bin/types/utils/JsViewVueTools/ForgeHandles.d.ts +1 -0
- package/bin/types/utils/JsViewVueTools/JsvRuntimeBridge.d.ts +37 -1
- package/bin/types/utils/JsViewVueTools/JsvTextureStore/CapturedTexture/CapturedTexture.d.ts +3 -3
- package/bin/types/utils/JsViewVueTools/JsvTextureStore/DominantColor/GetDominantColor.d.ts +7 -0
- package/bin/types/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.d.ts +14 -1
- package/bin/types/utils/JsViewVueTools/JsvTextureStore/Store.d.ts +2 -0
- package/bin/types/utils/JsViewVueTools/JsvTextureStore/Texture.d.ts +4 -0
- package/bin/types/utils/JsViewVueWidget/JsvDashPath.vue.d.ts +11 -0
- package/bin/types/utils/JsViewVueWidget/JsvFragShaderView/JsvFragShaderView.vue.d.ts +2 -1
- package/bin/types/utils/JsViewVueWidget/JsvSmoothSlideContainer.vue.d.ts +72 -0
- package/bin/types/utils/JsViewVueWidget/JsvSoundPool.d.ts +26 -0
- package/bin/types/utils/JsViewVueWidget/JsvSwiper/JsvSmoothSwiper.vue.d.ts +112 -0
- package/bin/types/utils/JsViewVueWidget/JsvSwiper/JsvSwiper2.vue.d.ts +142 -0
- package/bin/types/utils/JsViewVueWidget/JsvSwiper/index.d.ts +3 -1
- package/bin/types/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue.d.ts +2 -2
- package/bin/types/utils/JsViewVueWidget/index.d.ts +2 -1
- package/package.json +1 -1
- package/utils/JsViewEngineWidget/JsvFocus/JsvFocusHub.ts +27 -1
- package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +35 -3
- package/utils/JsViewEngineWidget/MetroWidget/MetroWidgetSetup.js +736 -386
- package/utils/JsViewEngineWidget/MetroWidget/RenderItem.ts +13 -2
- package/utils/JsViewEngineWidget/MetroWidget/TaskManager.ts +38 -26
- package/utils/JsViewEngineWidget/TemplateParser/CommonMetroTemplate.ts +144 -73
- package/utils/JsViewEngineWidget/WidgetCommon.ts +12 -0
- package/utils/JsViewPlugin/JsvAudio/BrowserAudio/BrowserAudio.vue +4 -0
- package/utils/JsViewPlugin/JsvAudio/BrowserAudio/JsvSystemAudio.vue +13 -13
- package/utils/JsViewPlugin/JsvPlayer/BrowserJsvPlayer.vue +1 -1
- package/utils/JsViewVueTools/FeatureActive.ts +2 -1
- package/utils/JsViewVueTools/ForgeHandles.ts +5 -2
- package/utils/JsViewVueTools/JsvRuntimeBridge.js +97 -1
- package/utils/JsViewVueTools/JsvTextTools.ts +3 -1
- package/utils/JsViewVueTools/JsvTextureStore/CapturedTexture/CapturedTexture.ts +15 -12
- package/utils/JsViewVueTools/JsvTextureStore/DominantColor/GetDominantColor.ts +36 -0
- package/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.ts +23 -2
- package/utils/JsViewVueTools/JsvTextureStore/Store.ts +33 -21
- package/utils/JsViewVueTools/JsvTextureStore/Texture.ts +56 -41
- package/utils/JsViewVueWidget/JsvDashPath.vue +150 -0
- package/utils/JsViewVueWidget/JsvFlexCell/JsvFullScrAdjust.vue +3 -1
- package/utils/JsViewVueWidget/JsvFragShaderView/JsvFragShaderView.vue +26 -22
- package/utils/JsViewVueWidget/JsvFreeMoveActor/SetAction.ts +1 -1
- package/utils/JsViewVueWidget/JsvInput/JsvInput.vue +1 -0
- package/utils/JsViewVueWidget/JsvPreload/JsvPreload.vue +2 -2
- package/utils/JsViewVueWidget/JsvSmoothSlideContainer.vue +108 -0
- package/utils/JsViewVueWidget/JsvSoundPool.js +75 -12
- package/utils/JsViewVueWidget/JsvSwiper/JsvSmoothSwiper.vue +543 -0
- package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue +3 -3
- package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper2.vue +644 -0
- package/utils/JsViewVueWidget/JsvSwiper/index.js +3 -1
- package/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue +14 -8
- package/utils/JsViewVueWidget/index.js +2 -1
|
@@ -0,0 +1,543 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
* @file
|
|
3
|
+
*
|
|
4
|
+
* 【模块 export 内容】
|
|
5
|
+
* JsvSmoothSwiper:Vue高阶组件,平滑滚动轮播组件
|
|
6
|
+
* props说明:
|
|
7
|
+
* totalFrame {int} (必需)item 的个数
|
|
8
|
+
* firstFrame {int} 初始 item 的 index,默认为0
|
|
9
|
+
* layoutInfo {Object} (必需)组件的大小及位置 {top: 0, left: 0, width: 0, height: 0}
|
|
10
|
+
* onClick {Function} 点击事件 function () {}
|
|
11
|
+
* onChange {Function} 滚动事件 function (index) {}
|
|
12
|
+
* onEdge {Function} 到达边缘事件 ({direction: EdgeDirection}) => Void
|
|
13
|
+
* autoplayInterval {int} 自动滚动的时间(毫秒),等于0时不自动滚动, 默认为5000
|
|
14
|
+
* enableAutoplay {boolean} 是否启用自动滚动,默认为false
|
|
15
|
+
* animation {Object} 滚动动画设置 {duration: 0, easing: "linear"}
|
|
16
|
+
* vertical {boolean} 组件是否为纵向的,默认为 false
|
|
17
|
+
* name {String} 组件获得焦点的 name
|
|
18
|
+
* onFocus {Function} 获得焦点的回调
|
|
19
|
+
* onBlur {Function} 失去焦点的回调
|
|
20
|
+
* reverseSwipe {boolean} 反转滚动方向,默认值为false. 默认滚动方向是正向, 既向index增大的方向, 反转后为反向, 既向index减小的方向
|
|
21
|
+
* itemSize {Object} item的大小 {width: 0, height: 0}
|
|
22
|
+
* itemGap {int} item之间的间隔,默认为0
|
|
23
|
+
* padding {Object} 内边距 {left: 0, top: 0, right: 0, bottom: 0}
|
|
24
|
+
-->
|
|
25
|
+
|
|
26
|
+
<template>
|
|
27
|
+
<jsv-focus-block
|
|
28
|
+
:name="name"
|
|
29
|
+
:onAction="{ onFocus, onBlur, onKeyDown, onKeyUp }"
|
|
30
|
+
>
|
|
31
|
+
<div
|
|
32
|
+
:style="{
|
|
33
|
+
width: props.layoutInfo.width,
|
|
34
|
+
height: props.layoutInfo.height,
|
|
35
|
+
overflow: 'hidden',
|
|
36
|
+
}"
|
|
37
|
+
>
|
|
38
|
+
<div
|
|
39
|
+
:style="{
|
|
40
|
+
left: innerPadding.left,
|
|
41
|
+
top: innerPadding.top,
|
|
42
|
+
}"
|
|
43
|
+
>
|
|
44
|
+
<JsvSmoothSlideContainer
|
|
45
|
+
ref="root"
|
|
46
|
+
:initPosition="[xInitPosition, yInitPosition]"
|
|
47
|
+
>
|
|
48
|
+
<div
|
|
49
|
+
v-for="item in childDivList"
|
|
50
|
+
:key="item.id"
|
|
51
|
+
:style="{
|
|
52
|
+
left: item.left,
|
|
53
|
+
top: item.top,
|
|
54
|
+
width: item.width,
|
|
55
|
+
height: item.height,
|
|
56
|
+
}"
|
|
57
|
+
>
|
|
58
|
+
<slot
|
|
59
|
+
name="itemView"
|
|
60
|
+
:currentIndex="currentDataIndex"
|
|
61
|
+
:dataIndex="item.dataIndex"
|
|
62
|
+
:focused="focused"
|
|
63
|
+
></slot>
|
|
64
|
+
</div>
|
|
65
|
+
</JsvSmoothSlideContainer>
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
</jsv-focus-block>
|
|
69
|
+
</template>
|
|
70
|
+
|
|
71
|
+
<script setup>
|
|
72
|
+
import { shallowRef, onMounted, computed, ref } from "vue";
|
|
73
|
+
import ActorControl from "../JsvFreeMoveActor/ActorControl.ts";
|
|
74
|
+
import { EdgeDirection } from "../../JsViewEngineWidget";
|
|
75
|
+
import JsvSmoothSlideContainer from "../JsvSmoothSlideContainer.vue";
|
|
76
|
+
|
|
77
|
+
// 定义props
|
|
78
|
+
const props = defineProps({
|
|
79
|
+
totalFrame: {
|
|
80
|
+
type: Number,
|
|
81
|
+
required: true,
|
|
82
|
+
},
|
|
83
|
+
firstFrame: {
|
|
84
|
+
type: Number,
|
|
85
|
+
default: 0,
|
|
86
|
+
},
|
|
87
|
+
layoutInfo: {
|
|
88
|
+
type: Object,
|
|
89
|
+
required: true,
|
|
90
|
+
},
|
|
91
|
+
onClick: {
|
|
92
|
+
type: Function,
|
|
93
|
+
},
|
|
94
|
+
onChange: {
|
|
95
|
+
type: Function,
|
|
96
|
+
},
|
|
97
|
+
onEdge: {
|
|
98
|
+
type: Function,
|
|
99
|
+
},
|
|
100
|
+
autoplayInterval: {
|
|
101
|
+
type: Number,
|
|
102
|
+
default: 5000,
|
|
103
|
+
},
|
|
104
|
+
enableAutoplay: {
|
|
105
|
+
type: Boolean,
|
|
106
|
+
default: false,
|
|
107
|
+
},
|
|
108
|
+
animation: {
|
|
109
|
+
type: Object,
|
|
110
|
+
default() {
|
|
111
|
+
return {
|
|
112
|
+
duration: 200,
|
|
113
|
+
easing: "linear",
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
vertical: {
|
|
118
|
+
type: Boolean,
|
|
119
|
+
default: false,
|
|
120
|
+
},
|
|
121
|
+
name: {
|
|
122
|
+
type: String,
|
|
123
|
+
},
|
|
124
|
+
onFocus: {
|
|
125
|
+
type: Function,
|
|
126
|
+
},
|
|
127
|
+
onBlur: {
|
|
128
|
+
type: Function,
|
|
129
|
+
},
|
|
130
|
+
reverseSwipe: {
|
|
131
|
+
type: Boolean,
|
|
132
|
+
default: false,
|
|
133
|
+
},
|
|
134
|
+
itemSize: {
|
|
135
|
+
type: Object,
|
|
136
|
+
},
|
|
137
|
+
itemGap: {
|
|
138
|
+
type: Number,
|
|
139
|
+
default: 0,
|
|
140
|
+
},
|
|
141
|
+
padding: {
|
|
142
|
+
type: Object,
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
const root = shallowRef();
|
|
146
|
+
// const actorControl = new ActorControl();
|
|
147
|
+
const childDivList = ref([]);
|
|
148
|
+
window.test = childDivList;
|
|
149
|
+
const focused = shallowRef(false);
|
|
150
|
+
const currentIndex = shallowRef(props.firstFrame);
|
|
151
|
+
const targetIndex = shallowRef(props.firstFrame);
|
|
152
|
+
const currentDataIndex = computed(() => {
|
|
153
|
+
return modToRange(currentIndex.value, props.totalFrame);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
const keyCode2EdgeDirection = (keyCode) => {
|
|
157
|
+
switch (keyCode) {
|
|
158
|
+
case 37:
|
|
159
|
+
return EdgeDirection.left;
|
|
160
|
+
case 38:
|
|
161
|
+
return EdgeDirection.top;
|
|
162
|
+
case 39:
|
|
163
|
+
return EdgeDirection.right;
|
|
164
|
+
case 40:
|
|
165
|
+
return EdgeDirection.bottom;
|
|
166
|
+
default:
|
|
167
|
+
console.error("not direction key", keyCode);
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
function modToRange(value, mod, start = 0) {
|
|
173
|
+
let m = value % mod;
|
|
174
|
+
if (m < start) {
|
|
175
|
+
m += mod;
|
|
176
|
+
} else if (m >= start + mod) {
|
|
177
|
+
m -= mod;
|
|
178
|
+
}
|
|
179
|
+
return m;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const innerPadding = computed(() => {
|
|
183
|
+
return Object.assign(
|
|
184
|
+
{
|
|
185
|
+
left: 0,
|
|
186
|
+
top: 0,
|
|
187
|
+
right: 0,
|
|
188
|
+
bottom: 0,
|
|
189
|
+
},
|
|
190
|
+
props.padding
|
|
191
|
+
);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
const innerItemSize = computed(() => {
|
|
195
|
+
return (
|
|
196
|
+
props.itemSize || {
|
|
197
|
+
width: props.layoutInfo.width,
|
|
198
|
+
height: props.layoutInfo.height,
|
|
199
|
+
}
|
|
200
|
+
);
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
const centerOffset = computed(() => {
|
|
204
|
+
return props.vertical
|
|
205
|
+
? (props.layoutInfo.height -
|
|
206
|
+
(innerPadding.value.top + innerPadding.value.bottom) -
|
|
207
|
+
innerItemSize.value.height) /
|
|
208
|
+
2
|
|
209
|
+
: (props.layoutInfo.width -
|
|
210
|
+
(innerPadding.value.left + innerPadding.value.right) -
|
|
211
|
+
innerItemSize.value.width) /
|
|
212
|
+
2;
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
const itemStart = (index) => {
|
|
216
|
+
return props.vertical
|
|
217
|
+
? index * props.itemSize.height + index * props.itemGap
|
|
218
|
+
: index * props.itemSize.width + index * props.itemGap;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
const visibleCount = computed(() => {
|
|
222
|
+
if (props.vertical) {
|
|
223
|
+
return (
|
|
224
|
+
Math.ceil(
|
|
225
|
+
(props.layoutInfo.height - innerItemSize.value.height) /
|
|
226
|
+
2 /
|
|
227
|
+
(innerItemSize.value.height + props.itemGap)
|
|
228
|
+
) *
|
|
229
|
+
2 +
|
|
230
|
+
1
|
|
231
|
+
);
|
|
232
|
+
} else {
|
|
233
|
+
return (
|
|
234
|
+
Math.ceil(
|
|
235
|
+
(props.layoutInfo.width - innerItemSize.value.width) /
|
|
236
|
+
2 /
|
|
237
|
+
(innerItemSize.value.width + props.itemGap)
|
|
238
|
+
) *
|
|
239
|
+
2 +
|
|
240
|
+
1
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
const viewNum = computed(() => {
|
|
246
|
+
return visibleCount.value + 2;
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
const viewNumOneSide = computed(() => {
|
|
250
|
+
return Math.floor(viewNum.value / 2);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
let xInitPosition = 0;
|
|
254
|
+
let yInitPosition = 0;
|
|
255
|
+
if (props.vertical) {
|
|
256
|
+
yInitPosition = -itemStart(currentIndex.value) + centerOffset.value;
|
|
257
|
+
} else {
|
|
258
|
+
xInitPosition = -itemStart(currentIndex.value) + centerOffset.value;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
const initDivList = () => {
|
|
262
|
+
prepareDiv(currentIndex.value, -1);
|
|
263
|
+
prepareDiv(currentIndex.value, 1);
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
const addDiv = (divInfo) => {
|
|
267
|
+
for (let i of childDivList.value) {
|
|
268
|
+
if (i.id === divInfo.id) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
childDivList.value.push(divInfo);
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
const cleanInvisibleDiv = () => {
|
|
276
|
+
childDivList.value = childDivList.value.filter(
|
|
277
|
+
(item) =>
|
|
278
|
+
item.id >= currentIndex.value - viewNumOneSide.value &&
|
|
279
|
+
item.id <= currentIndex.value + viewNumOneSide.value
|
|
280
|
+
);
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const prepareDiv = (index, toward = 1) => {
|
|
284
|
+
const start = Math.min(index, index + toward * viewNumOneSide.value);
|
|
285
|
+
const end = Math.max(index, index + toward * viewNumOneSide.value);
|
|
286
|
+
for (let i = start; i <= end; ++i) {
|
|
287
|
+
const divInfo = {
|
|
288
|
+
id: i,
|
|
289
|
+
left: itemStart(i),
|
|
290
|
+
top: 0,
|
|
291
|
+
width: props.itemSize.width,
|
|
292
|
+
height: props.itemSize.height,
|
|
293
|
+
dataIndex: modToRange(i, props.totalFrame),
|
|
294
|
+
};
|
|
295
|
+
addDiv(divInfo);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
|
|
299
|
+
let intervalId = null;
|
|
300
|
+
const startAutoplay = () => {
|
|
301
|
+
// 设置定时器
|
|
302
|
+
intervalId = setInterval(() => {
|
|
303
|
+
const toward = props.reverseSwipe ? -1 : 1;
|
|
304
|
+
moveTo(curTargetIndex + toward, lowSpeed.value);
|
|
305
|
+
}, props.autoplayInterval);
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
const stopAutoplay = () => {
|
|
309
|
+
clearInterval(intervalId);
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
const onFocus = () => {
|
|
313
|
+
focused.value = true;
|
|
314
|
+
stopAutoplay();
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
const onBlur = () => {
|
|
318
|
+
focused.value = false;
|
|
319
|
+
if (props.enableAutoplay && props.autoplayInterval > 0) {
|
|
320
|
+
startAutoplay();
|
|
321
|
+
}
|
|
322
|
+
};
|
|
323
|
+
|
|
324
|
+
const getSlidePosByIndex = (index) => {
|
|
325
|
+
return -itemStart(index) + centerOffset.value;
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
let preTargetIndex = props.firstFrame;
|
|
329
|
+
let curTargetIndex = props.firstFrame;
|
|
330
|
+
let curMoveDirection = 0;
|
|
331
|
+
let moveSpeed = 0;
|
|
332
|
+
let moveDirection = 0;
|
|
333
|
+
const moveTo = (index, speed) => {
|
|
334
|
+
if (index == curTargetIndex && speed == moveSpeed) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
moveSpeed = speed;
|
|
338
|
+
if (index != curTargetIndex) {
|
|
339
|
+
preTargetIndex = curTargetIndex;
|
|
340
|
+
curTargetIndex = index;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
moveDirection = Math.sign(curTargetIndex - preTargetIndex);
|
|
344
|
+
|
|
345
|
+
let targetX = 0;
|
|
346
|
+
let targetY = 0;
|
|
347
|
+
let halfTargetX = 0;
|
|
348
|
+
let halfTargetY = 0;
|
|
349
|
+
if (props.vertical) {
|
|
350
|
+
targetY = getSlidePosByIndex(curTargetIndex);
|
|
351
|
+
let preTargetY = getSlidePosByIndex(preTargetIndex);
|
|
352
|
+
halfTargetY = (targetY + preTargetY) / 2;
|
|
353
|
+
} else {
|
|
354
|
+
targetX = getSlidePosByIndex(curTargetIndex);
|
|
355
|
+
let preTargetX = getSlidePosByIndex(preTargetIndex);
|
|
356
|
+
halfTargetX = (targetX + preTargetX) / 2;
|
|
357
|
+
}
|
|
358
|
+
prepareDiv(index, moveDirection);
|
|
359
|
+
|
|
360
|
+
root.value.moveTo(
|
|
361
|
+
speed,
|
|
362
|
+
targetX,
|
|
363
|
+
targetY,
|
|
364
|
+
onReach(index, curMoveDirection),
|
|
365
|
+
halfTargetX,
|
|
366
|
+
halfTargetY,
|
|
367
|
+
onBeforeReach(index, curMoveDirection)
|
|
368
|
+
);
|
|
369
|
+
moveInfo.moving = true;
|
|
370
|
+
};
|
|
371
|
+
|
|
372
|
+
const brakeTo = (index) => {
|
|
373
|
+
let targetX = undefined;
|
|
374
|
+
let targetY = undefined;
|
|
375
|
+
if (props.vertical) {
|
|
376
|
+
targetY = getSlidePosByIndex(index);
|
|
377
|
+
} else {
|
|
378
|
+
targetX = getSlidePosByIndex(index);
|
|
379
|
+
}
|
|
380
|
+
root.value.brakeTo(targetX, targetY);
|
|
381
|
+
};
|
|
382
|
+
|
|
383
|
+
const onReach = (index, toward) => {
|
|
384
|
+
return () => {
|
|
385
|
+
moveInfo.reachedIndex = index;
|
|
386
|
+
if (keyInfo.keyRepeat) {
|
|
387
|
+
//继续移动
|
|
388
|
+
moveTo(
|
|
389
|
+
curTargetIndex + Math.sign(curTargetIndex - preTargetIndex),
|
|
390
|
+
moveSpeed
|
|
391
|
+
);
|
|
392
|
+
} else {
|
|
393
|
+
//移动结束
|
|
394
|
+
moveInfo.moving = false;
|
|
395
|
+
moveSpeed = 0;
|
|
396
|
+
cleanInvisibleDiv();
|
|
397
|
+
if (curTargetIndex === index) {
|
|
398
|
+
//刹车
|
|
399
|
+
root.value?.stop();
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
};
|
|
404
|
+
|
|
405
|
+
const onBeforeReach = (index, toward) => {
|
|
406
|
+
return () => {
|
|
407
|
+
currentIndex.value = index;
|
|
408
|
+
props.onChange?.(currentDataIndex.value);
|
|
409
|
+
if (!keyInfo.keyRepeat) {
|
|
410
|
+
//不再继续移动
|
|
411
|
+
if (curTargetIndex === index) {
|
|
412
|
+
//刹车
|
|
413
|
+
brakeTo(index);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
};
|
|
418
|
+
|
|
419
|
+
let moveInfo = {
|
|
420
|
+
reachedIndex: props.firstFrame,
|
|
421
|
+
preReached: false,
|
|
422
|
+
toward: 0,
|
|
423
|
+
moving: false,
|
|
424
|
+
moveSpeed: 0,
|
|
425
|
+
targetIndex: 0,
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
const lowSpeed = computed(() => {
|
|
429
|
+
return (
|
|
430
|
+
(props.verticals ? props.itemSize.height : props.itemSize.width) /
|
|
431
|
+
((60 * props.animation.duration) / 1000)
|
|
432
|
+
);
|
|
433
|
+
});
|
|
434
|
+
const highSpeed = computed(() => {
|
|
435
|
+
return 2 * lowSpeed.value;
|
|
436
|
+
});
|
|
437
|
+
|
|
438
|
+
const keyInfo = {
|
|
439
|
+
keyCode: 0,
|
|
440
|
+
keyRepeat: false,
|
|
441
|
+
};
|
|
442
|
+
const onKeyDown = (ev) => {
|
|
443
|
+
if (ev.keyCode ==13) {
|
|
444
|
+
if (!moveInfo.moving) {
|
|
445
|
+
props.onClick?.(currentDataIndex.value);
|
|
446
|
+
}
|
|
447
|
+
return true;
|
|
448
|
+
}
|
|
449
|
+
if (
|
|
450
|
+
ev.keyCode != 37 &&
|
|
451
|
+
ev.keyCode != 38 &&
|
|
452
|
+
ev.keyCode != 39 &&
|
|
453
|
+
ev.keyCode != 40
|
|
454
|
+
) {
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
let toward = 0;
|
|
459
|
+
if (props.vertical) {
|
|
460
|
+
toward = ev.keyCode == 38 ? -1 : ev.keyCode == 40 ? 1 : 0;
|
|
461
|
+
} else {
|
|
462
|
+
toward = ev.keyCode == 37 ? -1 : ev.keyCode == 39 ? 1 : 0;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
if (toward == 0) {
|
|
466
|
+
props.onEdge?.({
|
|
467
|
+
direction: keyCode2EdgeDirection(ev.keyCode),
|
|
468
|
+
rect: {
|
|
469
|
+
x: props.layoutInfo.left,
|
|
470
|
+
y: props.layoutInfo.top,
|
|
471
|
+
width: props.layoutInfo.width,
|
|
472
|
+
height: props.layoutInfo.height,
|
|
473
|
+
},
|
|
474
|
+
});
|
|
475
|
+
return true;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
//会有同时摁住两个键的情况, 所以要记录keyCode, 以便在keyUp的时候比对
|
|
479
|
+
keyInfo.keyCode = ev.keyCode;
|
|
480
|
+
keyInfo.keyRepeat = ev.repeat;
|
|
481
|
+
|
|
482
|
+
if (moveInfo.moving) {
|
|
483
|
+
if (ev.repeat) {
|
|
484
|
+
if (moveSpeed != highSpeed.value) {
|
|
485
|
+
moveSpeed = highSpeed.value;
|
|
486
|
+
root.value?.setSpeed(
|
|
487
|
+
props.vertical ? undefined : -toward * highSpeed.value,
|
|
488
|
+
props.vertical ? -toward * highSpeed.value : undefined
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
return true;
|
|
492
|
+
}
|
|
493
|
+
// 如果正在移动到目标, 则继续移动
|
|
494
|
+
if (toward == moveDirection) {
|
|
495
|
+
// 同向加速
|
|
496
|
+
if (currentIndex.value == curTargetIndex) {
|
|
497
|
+
moveTo(curTargetIndex + toward, highSpeed.value);
|
|
498
|
+
}
|
|
499
|
+
} else {
|
|
500
|
+
// 反向
|
|
501
|
+
moveTo(curTargetIndex + toward, lowSpeed.value);
|
|
502
|
+
}
|
|
503
|
+
} else {
|
|
504
|
+
moveTo(curTargetIndex + toward, lowSpeed.value);
|
|
505
|
+
}
|
|
506
|
+
return true;
|
|
507
|
+
};
|
|
508
|
+
|
|
509
|
+
const onKeyUp = (ev) => {
|
|
510
|
+
let targetKey = false;
|
|
511
|
+
switch (ev.keyCode) {
|
|
512
|
+
case 37:
|
|
513
|
+
targetKey = true;
|
|
514
|
+
break;
|
|
515
|
+
case 39:
|
|
516
|
+
targetKey = true;
|
|
517
|
+
break;
|
|
518
|
+
case 38:
|
|
519
|
+
targetKey = true;
|
|
520
|
+
break;
|
|
521
|
+
case 40:
|
|
522
|
+
targetKey = true;
|
|
523
|
+
break;
|
|
524
|
+
default:
|
|
525
|
+
break;
|
|
526
|
+
}
|
|
527
|
+
if (targetKey) {
|
|
528
|
+
if (keyInfo.keyCode != ev.keyCode) {
|
|
529
|
+
return true;
|
|
530
|
+
}
|
|
531
|
+
keyInfo.keyRepeat = false;
|
|
532
|
+
if (moveInfo.moving) {
|
|
533
|
+
brakeTo(curTargetIndex);
|
|
534
|
+
}
|
|
535
|
+
return true;
|
|
536
|
+
}
|
|
537
|
+
return false;
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
onMounted(() => {
|
|
541
|
+
initDivList();
|
|
542
|
+
});
|
|
543
|
+
</script>
|
|
@@ -397,7 +397,7 @@ export default {
|
|
|
397
397
|
},
|
|
398
398
|
_startAnimation(direction, smooth = false) {
|
|
399
399
|
let duration = this.animation.duration;
|
|
400
|
-
|
|
400
|
+
let easing = this.animation.easing ? this.animation.easing : "linear";
|
|
401
401
|
|
|
402
402
|
let curViewAnimation;
|
|
403
403
|
let preViewAnimation;
|
|
@@ -438,7 +438,7 @@ export default {
|
|
|
438
438
|
this.vertical ? direction * this.layoutInfo.height : 0,
|
|
439
439
|
0,
|
|
440
440
|
duration,
|
|
441
|
-
|
|
441
|
+
Forge.Easing.str2Easing(easing)
|
|
442
442
|
);
|
|
443
443
|
preViewAnimation = new Forge.TranslateAnimation(
|
|
444
444
|
this.vertical ? 0 : direction * this.layoutInfo.width,
|
|
@@ -446,7 +446,7 @@ export default {
|
|
|
446
446
|
this.vertical ? direction * this.layoutInfo.height : 0,
|
|
447
447
|
0,
|
|
448
448
|
duration,
|
|
449
|
-
|
|
449
|
+
Forge.Easing.str2Easing(easing)
|
|
450
450
|
);
|
|
451
451
|
}
|
|
452
452
|
break;
|