sard-uniapp 1.1.7 → 1.2.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/README.md +42 -1
- package/changelog.md +9 -0
- package/components/_template/_template.d.ts +6 -4
- package/components/_template/_template.vue +4 -1
- package/components/_template/common.d.ts +3 -0
- package/components/_template/index.d.ts +1 -1
- package/components/config/index.d.ts +24 -0
- package/components/config/index.js +12 -0
- package/components/count-to/common.d.ts +13 -0
- package/components/count-to/common.js +2 -0
- package/components/count-to/count-to.d.ts +35 -0
- package/components/count-to/count-to.vue +67 -0
- package/components/count-to/index.d.ts +1 -0
- package/components/count-to/index.js +1 -0
- package/components/grid/common.d.ts +2 -0
- package/components/grid-item/grid-item.vue +14 -3
- package/components/indexes/common.d.ts +1 -0
- package/components/indexes/indexes.d.ts +1 -0
- package/components/indexes/indexes.vue +16 -10
- package/components/input/index.scss +6 -0
- package/components/marquee/common.d.ts +19 -0
- package/components/marquee/common.js +2 -0
- package/components/marquee/index.d.ts +1 -0
- package/components/marquee/index.js +1 -0
- package/components/marquee/index.scss +43 -0
- package/components/marquee/marquee.d.ts +39 -0
- package/components/marquee/marquee.vue +81 -0
- package/components/marquee/variables.scss +2 -0
- package/components/notice-bar/common.d.ts +3 -0
- package/components/notice-bar/index.d.ts +1 -1
- package/components/notice-bar/notice-bar.d.ts +3 -1
- package/components/notice-bar/notice-bar.vue +10 -5
- package/components/search/common.d.ts +3 -0
- package/components/search/search.d.ts +5 -0
- package/components/search/search.vue +10 -5
- package/components/stepper/index.scss +1 -0
- package/components/style/variables.scss +1 -1
- package/global.d.ts +4 -0
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/index.scss +1 -0
- package/package.json +4 -1
- package/use/index.d.ts +4 -0
- package/use/index.js +4 -0
- package/use/useImperative.d.ts +1 -1
- package/use/useLuckyDraw.d.ts +22 -0
- package/use/useLuckyDraw.js +160 -0
- package/use/useLuckyGrid.d.ts +26 -0
- package/use/useLuckyGrid.js +62 -0
- package/use/useLuckyWheel.d.ts +15 -0
- package/use/useLuckyWheel.js +25 -0
- package/use/useSlotMachine.d.ts +16 -0
- package/use/useSlotMachine.js +87 -0
- package/use/useTransition.d.ts +2 -2
- package/utils/utils.d.ts +2 -0
- package/utils/utils.js +8 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
export type { NoticeBarProps, NoticeBarSlots, NoticeBarEmits } from './common';
|
|
1
|
+
export type { NoticeBarProps, NoticeBarSlots, NoticeBarEmits, NoticeBarExpose, } from './common';
|
|
@@ -4,7 +4,9 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__
|
|
|
4
4
|
speed: number;
|
|
5
5
|
scrollable: "auto";
|
|
6
6
|
visible: boolean;
|
|
7
|
-
}>, {
|
|
7
|
+
}>, {
|
|
8
|
+
update: () => void;
|
|
9
|
+
}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
8
10
|
click: (event: any) => void;
|
|
9
11
|
close: () => void;
|
|
10
12
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<NoticeBarProps>, {
|
|
@@ -41,6 +41,7 @@ import SarIcon from "../icon/icon.vue";
|
|
|
41
41
|
import {
|
|
42
42
|
noticeBarPropsDefaults
|
|
43
43
|
} from "./common";
|
|
44
|
+
import { useSetTimeout } from "../../use";
|
|
44
45
|
export default _defineComponent({
|
|
45
46
|
...{
|
|
46
47
|
options: {
|
|
@@ -66,7 +67,6 @@ export default _defineComponent({
|
|
|
66
67
|
}, noticeBarPropsDefaults),
|
|
67
68
|
emits: ["click", "close"],
|
|
68
69
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
69
|
-
__expose();
|
|
70
70
|
const props = __props;
|
|
71
71
|
const emit = __emit;
|
|
72
72
|
const bem = createBem("notice-bar");
|
|
@@ -82,7 +82,7 @@ export default _defineComponent({
|
|
|
82
82
|
const getWidth = async (id) => {
|
|
83
83
|
return (await getBoundingClientRect(`#${id}`, instance)).width;
|
|
84
84
|
};
|
|
85
|
-
const
|
|
85
|
+
const update = async () => {
|
|
86
86
|
if (props.scrollable === "never") {
|
|
87
87
|
shouldScroll.value = false;
|
|
88
88
|
return;
|
|
@@ -114,14 +114,20 @@ export default _defineComponent({
|
|
|
114
114
|
emit("close");
|
|
115
115
|
}
|
|
116
116
|
};
|
|
117
|
+
const [updateLater] = useSetTimeout(() => {
|
|
118
|
+
update();
|
|
119
|
+
});
|
|
117
120
|
onMounted(() => {
|
|
118
121
|
if (props.scrollable) {
|
|
119
|
-
|
|
122
|
+
updateLater(props.delay);
|
|
120
123
|
}
|
|
121
124
|
});
|
|
122
125
|
const onClick = (event) => {
|
|
123
126
|
emit("click", event);
|
|
124
127
|
};
|
|
128
|
+
__expose({
|
|
129
|
+
update
|
|
130
|
+
});
|
|
125
131
|
const noticeBarClass = computed(() => {
|
|
126
132
|
return classNames(
|
|
127
133
|
bem.b(),
|
|
@@ -146,11 +152,10 @@ export default _defineComponent({
|
|
|
146
152
|
const wrapperStyle = computed(() => {
|
|
147
153
|
return stringifyStyle({
|
|
148
154
|
transform: `translateX(${firstLap.value ? 0 : wrapperData.value.contentWidth}px)`,
|
|
149
|
-
animationDelay: `${firstLap.value ? props.delay : 0}ms`,
|
|
150
155
|
animationDuration: `${firstLap.value ? wrapperData.value.first : wrapperData.value.later}ms`
|
|
151
156
|
});
|
|
152
157
|
});
|
|
153
|
-
const __returned__ = { props, emit, bem, instance, contentId, wrapperId, shouldScroll, wrapperData, getWidth,
|
|
158
|
+
const __returned__ = { props, emit, bem, instance, contentId, wrapperId, shouldScroll, wrapperData, getWidth, update, firstLap, onAnimationEnd, innerVisible, onRightIconClick, updateLater, onClick, noticeBarClass, noticeBarStyle, wrapperStyle, SarIcon };
|
|
154
159
|
return __returned__;
|
|
155
160
|
}
|
|
156
161
|
});
|
|
@@ -13,9 +13,11 @@ export interface SearchProps {
|
|
|
13
13
|
align?: 'left' | 'center' | 'right';
|
|
14
14
|
cancel?: string;
|
|
15
15
|
search?: string;
|
|
16
|
+
focus?: boolean;
|
|
16
17
|
}
|
|
17
18
|
export declare const searchPropsDefaults: {
|
|
18
19
|
shape: "square";
|
|
20
|
+
focus: boolean;
|
|
19
21
|
};
|
|
20
22
|
export interface SearchSlots {
|
|
21
23
|
prepend?(props: Record<string, never>): any;
|
|
@@ -27,4 +29,5 @@ export interface SearchEmits {
|
|
|
27
29
|
(e: 'update:model-value', value: string): void;
|
|
28
30
|
(e: 'cancel'): void;
|
|
29
31
|
(e: 'search', value: string): void;
|
|
32
|
+
(e: 'click', event: any): void;
|
|
30
33
|
}
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
import { type SearchProps, type SearchSlots } from './common';
|
|
2
2
|
declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToOption<SearchProps>, {
|
|
3
3
|
shape: "square";
|
|
4
|
+
focus: boolean;
|
|
4
5
|
}>, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
5
6
|
"update:model-value": (value: string) => void;
|
|
6
7
|
cancel: () => void;
|
|
7
8
|
search: (value: string) => void;
|
|
9
|
+
click: (event: any) => void;
|
|
8
10
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToOption<SearchProps>, {
|
|
9
11
|
shape: "square";
|
|
12
|
+
focus: boolean;
|
|
10
13
|
}>>> & {
|
|
11
14
|
"onUpdate:model-value"?: ((value: string) => any) | undefined;
|
|
15
|
+
onClick?: ((event: any) => any) | undefined;
|
|
12
16
|
onCancel?: (() => any) | undefined;
|
|
13
17
|
onSearch?: ((value: string) => any) | undefined;
|
|
14
18
|
}, {
|
|
15
19
|
shape: "round" | "square";
|
|
20
|
+
focus: boolean;
|
|
16
21
|
}, {}>, Readonly<SearchSlots> & SearchSlots>;
|
|
17
22
|
export default _default;
|
|
18
23
|
type __VLS_WithDefaults<P, D> = {
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<view :class="searchClass" :style="searchStyle">
|
|
2
|
+
<view :class="searchClass" :style="searchStyle" @click="onClick">
|
|
3
3
|
<view v-if="$slots.prepend" :class="bem.e('prepend')">
|
|
4
4
|
<slot name="prepend"></slot>
|
|
5
5
|
</view>
|
|
6
6
|
<view :class="bem.e('input-wrapper')">
|
|
7
7
|
<sar-input
|
|
8
8
|
:model-value="innerValue"
|
|
9
|
-
@update:model-value="onInput"
|
|
10
9
|
clearable
|
|
11
10
|
confirm-type="search"
|
|
12
11
|
showClearOnlyFocus
|
|
@@ -16,6 +15,8 @@
|
|
|
16
15
|
borderless
|
|
17
16
|
:root-class="inputClass"
|
|
18
17
|
:root-style="inputStyle"
|
|
18
|
+
:focus="focus"
|
|
19
|
+
@update:model-value="onInput"
|
|
19
20
|
@confirm="onConfirm"
|
|
20
21
|
>
|
|
21
22
|
<template #prepend>
|
|
@@ -81,9 +82,10 @@ export default _defineComponent({
|
|
|
81
82
|
disabled: { type: Boolean, required: false },
|
|
82
83
|
align: { type: String, required: false },
|
|
83
84
|
cancel: { type: String, required: false },
|
|
84
|
-
search: { type: String, required: false }
|
|
85
|
+
search: { type: String, required: false },
|
|
86
|
+
focus: { type: Boolean, required: false }
|
|
85
87
|
}, searchPropsDefaults),
|
|
86
|
-
emits: ["update:model-value", "cancel", "search"],
|
|
88
|
+
emits: ["update:model-value", "cancel", "search", "click"],
|
|
87
89
|
setup(__props, { expose: __expose, emit: __emit }) {
|
|
88
90
|
__expose();
|
|
89
91
|
const props = __props;
|
|
@@ -107,6 +109,9 @@ export default _defineComponent({
|
|
|
107
109
|
innerValue.value = "";
|
|
108
110
|
emit("cancel");
|
|
109
111
|
};
|
|
112
|
+
const onClick = (event) => {
|
|
113
|
+
emit("click", event);
|
|
114
|
+
};
|
|
110
115
|
const searchClass = computed(() => {
|
|
111
116
|
return classNames(
|
|
112
117
|
bem.b(),
|
|
@@ -133,7 +138,7 @@ export default _defineComponent({
|
|
|
133
138
|
backgroundColor: props.inputBackground
|
|
134
139
|
});
|
|
135
140
|
});
|
|
136
|
-
const __returned__ = { props, emit, bem, innerValue, onInput, onConfirm, onCancel, searchClass, searchStyle, inputClass, inputStyle, SarInput, SarIcon, SarButton };
|
|
141
|
+
const __returned__ = { props, emit, bem, innerValue, onInput, onConfirm, onCancel, onClick, searchClass, searchStyle, inputClass, inputStyle, SarInput, SarIcon, SarButton };
|
|
137
142
|
return __returned__;
|
|
138
143
|
}
|
|
139
144
|
});
|
package/global.d.ts
CHANGED
|
@@ -16,6 +16,7 @@ import SarCheckboxGroup from './components/checkbox-group/checkbox-group'
|
|
|
16
16
|
import SarCol from './components/col/col'
|
|
17
17
|
import SarCollapse from './components/collapse/collapse'
|
|
18
18
|
import SarCountDown from './components/count-down/count-down'
|
|
19
|
+
import SarCountTo from './components/count-to/count-to'
|
|
19
20
|
import SarDatetimePicker from './components/datetime-picker/datetime-picker'
|
|
20
21
|
import SarDatetimePickerInput from './components/datetime-picker-input/datetime-picker-input'
|
|
21
22
|
import SarDialog from './components/dialog/dialog'
|
|
@@ -36,6 +37,7 @@ import SarList from './components/list/list'
|
|
|
36
37
|
import SarListItem from './components/list-item/list-item'
|
|
37
38
|
import SarLoading from './components/loading/loading'
|
|
38
39
|
import SarLoadMore from './components/load-more/load-more'
|
|
40
|
+
import SarMarquee from './components/marquee/marquee'
|
|
39
41
|
import SarMenu from './components/menu/menu'
|
|
40
42
|
import SarNavbar from './components/navbar/navbar'
|
|
41
43
|
import SarNavbarItem from './components/navbar-item/navbar-item'
|
|
@@ -100,6 +102,7 @@ declare module '@vue/runtime-core' {
|
|
|
100
102
|
SarCol: typeof SarCol
|
|
101
103
|
SarCollapse: typeof SarCollapse
|
|
102
104
|
SarCountDown: typeof SarCountDown
|
|
105
|
+
SarCountTo: typeof SarCountTo
|
|
103
106
|
SarDatetimePicker: typeof SarDatetimePicker
|
|
104
107
|
SarDatetimePickerInput: typeof SarDatetimePickerInput
|
|
105
108
|
SarDialog: typeof SarDialog
|
|
@@ -120,6 +123,7 @@ declare module '@vue/runtime-core' {
|
|
|
120
123
|
SarListItem: typeof SarListItem
|
|
121
124
|
SarLoading: typeof SarLoading
|
|
122
125
|
SarLoadMore: typeof SarLoadMore
|
|
126
|
+
SarMarquee: typeof SarMarquee
|
|
123
127
|
SarMenu: typeof SarMenu
|
|
124
128
|
SarNavbar: typeof SarNavbar
|
|
125
129
|
SarNavbarItem: typeof SarNavbarItem
|
package/index.d.ts
CHANGED
|
@@ -12,6 +12,7 @@ export * from './components/checkbox';
|
|
|
12
12
|
export * from './components/collapse';
|
|
13
13
|
export * from './components/config';
|
|
14
14
|
export * from './components/count-down';
|
|
15
|
+
export * from './components/count-to';
|
|
15
16
|
export * from './components/datetime-picker';
|
|
16
17
|
export * from './components/datetime-picker-input';
|
|
17
18
|
export * from './components/dialog';
|
|
@@ -29,6 +30,7 @@ export * from './components/list';
|
|
|
29
30
|
export * from './components/loading';
|
|
30
31
|
export * from './components/load-more';
|
|
31
32
|
export * from './components/locale';
|
|
33
|
+
export * from './components/marquee';
|
|
32
34
|
export * from './components/menu';
|
|
33
35
|
export * from './components/navbar';
|
|
34
36
|
export * from './components/notice-bar';
|
package/index.js
CHANGED
|
@@ -12,6 +12,7 @@ export * from './components/checkbox';
|
|
|
12
12
|
export * from './components/collapse';
|
|
13
13
|
export * from './components/config';
|
|
14
14
|
export * from './components/count-down';
|
|
15
|
+
export * from './components/count-to';
|
|
15
16
|
export * from './components/datetime-picker';
|
|
16
17
|
export * from './components/datetime-picker-input';
|
|
17
18
|
export * from './components/dialog';
|
|
@@ -29,6 +30,7 @@ export * from './components/list';
|
|
|
29
30
|
export * from './components/loading';
|
|
30
31
|
export * from './components/load-more';
|
|
31
32
|
export * from './components/locale';
|
|
33
|
+
export * from './components/marquee';
|
|
32
34
|
export * from './components/menu';
|
|
33
35
|
export * from './components/navbar';
|
|
34
36
|
export * from './components/notice-bar';
|
package/index.scss
CHANGED
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
@use './components/list/variables.scss' as *;
|
|
22
22
|
@use './components/loading/variables.scss' as *;
|
|
23
23
|
@use './components/load-more/variables.scss' as *;
|
|
24
|
+
@use './components/marquee/variables.scss' as *;
|
|
24
25
|
@use './components/menu/variables.scss' as *;
|
|
25
26
|
@use './components/navbar/variables.scss' as *;
|
|
26
27
|
@use './components/notice-bar/variables.scss' as *;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "sard-uniapp",
|
|
3
3
|
"name": "sard-uniapp",
|
|
4
4
|
"displayName": "sard-uniapp",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"description": "sard-uniapp 是一套基于 Uniapp + Vue3 框架开发的兼容多端的 UI 组件库",
|
|
8
8
|
"keywords": [
|
|
@@ -114,5 +114,8 @@
|
|
|
114
114
|
},
|
|
115
115
|
"engines": {
|
|
116
116
|
"HBuilderX": "^3.6.0"
|
|
117
|
+
},
|
|
118
|
+
"dependencies": {
|
|
119
|
+
"lwa": "^0.2.2"
|
|
117
120
|
}
|
|
118
121
|
}
|
package/use/index.d.ts
CHANGED
|
@@ -2,3 +2,7 @@ export * from './useTransition';
|
|
|
2
2
|
export * from './useSetTimeout';
|
|
3
3
|
export * from './useZIndex';
|
|
4
4
|
export * from './useImperative';
|
|
5
|
+
export * from './useLuckyGrid';
|
|
6
|
+
export * from './useLuckyWheel';
|
|
7
|
+
export * from './useLuckyDraw';
|
|
8
|
+
export * from './useSlotMachine';
|
package/use/index.js
CHANGED
|
@@ -2,3 +2,7 @@ export * from './useTransition';
|
|
|
2
2
|
export * from './useSetTimeout';
|
|
3
3
|
export * from './useZIndex';
|
|
4
4
|
export * from './useImperative';
|
|
5
|
+
export * from './useLuckyGrid';
|
|
6
|
+
export * from './useLuckyWheel';
|
|
7
|
+
export * from './useLuckyDraw';
|
|
8
|
+
export * from './useSlotMachine';
|
package/use/useImperative.d.ts
CHANGED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
export interface UseLuckyDrawOptions {
|
|
3
|
+
count: number | Ref<number>;
|
|
4
|
+
minSpeed?: number | Ref<number>;
|
|
5
|
+
maxSpeed?: number | Ref<number>;
|
|
6
|
+
accelTime?: number | Ref<number>;
|
|
7
|
+
decelTime?: number | Ref<number>;
|
|
8
|
+
easeIn?: (progress: number) => number;
|
|
9
|
+
easeOut?: (progress: number) => number;
|
|
10
|
+
startDelay?: number | Ref<number>;
|
|
11
|
+
endDelay?: number | Ref<number>;
|
|
12
|
+
complete?: (index: number) => void;
|
|
13
|
+
}
|
|
14
|
+
export declare const useLuckyDraw: (options: UseLuckyDrawOptions) => {
|
|
15
|
+
play: () => void;
|
|
16
|
+
stop: (index?: number) => void;
|
|
17
|
+
pause: () => void;
|
|
18
|
+
reset: () => void;
|
|
19
|
+
playing: import("vue").ComputedRef<boolean>;
|
|
20
|
+
activeIndex: import("vue").ComputedRef<number | undefined>;
|
|
21
|
+
};
|
|
22
|
+
export type UseLuckyDrawReturn = ReturnType<typeof useLuckyDraw>;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { computed, onScopeDispose, ref, unref } from 'vue';
|
|
2
|
+
import { random } from '../utils';
|
|
3
|
+
import { ticker } from 'lwa';
|
|
4
|
+
const defaultOptions = {
|
|
5
|
+
minSpeed: 0.1,
|
|
6
|
+
maxSpeed: 0.4,
|
|
7
|
+
accelTime: 2500,
|
|
8
|
+
decelTime: 2500,
|
|
9
|
+
easeIn: (k) => k * k,
|
|
10
|
+
easeOut: (k) => k * (2 - k),
|
|
11
|
+
startDelay: 0,
|
|
12
|
+
endDelay: 0,
|
|
13
|
+
};
|
|
14
|
+
export const useLuckyDraw = (options) => {
|
|
15
|
+
const { count, minSpeed, maxSpeed, accelTime, decelTime, complete, easeIn, easeOut, startDelay, endDelay, } = Object.assign({}, defaultOptions, options);
|
|
16
|
+
let stage = 'INITIAL';
|
|
17
|
+
let currentIndex = 0;
|
|
18
|
+
const activeIndex = ref();
|
|
19
|
+
const playing = ref(false);
|
|
20
|
+
let startTime = 0;
|
|
21
|
+
let accelFrames = 0;
|
|
22
|
+
let decelStopIndex;
|
|
23
|
+
let decelStopActiveIndex;
|
|
24
|
+
let decelStartIndex = 0;
|
|
25
|
+
const getDecelStopIndex = () => {
|
|
26
|
+
const interval = unref(accelTime) / accelFrames;
|
|
27
|
+
let i = 0;
|
|
28
|
+
let mockCurrentIndex = currentIndex;
|
|
29
|
+
let mockActiveIndex = 0;
|
|
30
|
+
while (++i) {
|
|
31
|
+
let progress = (interval * i) / unref(decelTime);
|
|
32
|
+
if (progress >= 1) {
|
|
33
|
+
progress = 1;
|
|
34
|
+
}
|
|
35
|
+
const currentSpeed = unref(maxSpeed) -
|
|
36
|
+
easeOut(progress) * (unref(maxSpeed) - unref(minSpeed));
|
|
37
|
+
mockCurrentIndex += currentSpeed;
|
|
38
|
+
mockActiveIndex = mockCurrentIndex % unref(count) >> 0;
|
|
39
|
+
if (progress === 1 && mockActiveIndex === decelStopActiveIndex) {
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return mockCurrentIndex >> 0;
|
|
44
|
+
};
|
|
45
|
+
const tick = () => {
|
|
46
|
+
switch (stage) {
|
|
47
|
+
case 'START_DELAY': {
|
|
48
|
+
if (Date.now() - startTime >= unref(startDelay)) {
|
|
49
|
+
stage = 'ACCELERATED';
|
|
50
|
+
startTime = Date.now();
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
case 'ACCELERATED': {
|
|
55
|
+
accelFrames++;
|
|
56
|
+
let progress = (Date.now() - startTime) / unref(accelTime);
|
|
57
|
+
if (progress >= 1) {
|
|
58
|
+
progress = 1;
|
|
59
|
+
}
|
|
60
|
+
const currentSpeed = unref(minSpeed) +
|
|
61
|
+
easeIn(progress) * (unref(maxSpeed) - unref(minSpeed));
|
|
62
|
+
currentIndex += currentSpeed;
|
|
63
|
+
if (progress === 1) {
|
|
64
|
+
stage = 'CONSTANT_SPEED';
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
case 'CONSTANT_SPEED': {
|
|
69
|
+
currentIndex += unref(maxSpeed);
|
|
70
|
+
if (decelStopActiveIndex !== undefined) {
|
|
71
|
+
stage = 'DECELERATED';
|
|
72
|
+
startTime = Date.now();
|
|
73
|
+
}
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
case 'DECELERATED': {
|
|
77
|
+
if (decelStopIndex === undefined) {
|
|
78
|
+
decelStopIndex = getDecelStopIndex();
|
|
79
|
+
decelStartIndex = currentIndex;
|
|
80
|
+
}
|
|
81
|
+
let progress = (Date.now() - startTime) / unref(decelTime);
|
|
82
|
+
if (progress >= 1) {
|
|
83
|
+
progress = 1;
|
|
84
|
+
}
|
|
85
|
+
currentIndex =
|
|
86
|
+
decelStartIndex +
|
|
87
|
+
easeOut(progress) * (decelStopIndex - decelStartIndex);
|
|
88
|
+
if (progress === 1) {
|
|
89
|
+
if (unref(endDelay) === 0) {
|
|
90
|
+
stage = 'DONE';
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
stage = 'END_DELAY';
|
|
94
|
+
startTime = Date.now();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
case 'END_DELAY': {
|
|
100
|
+
if (Date.now() - startTime >= unref(endDelay)) {
|
|
101
|
+
stage = 'DONE';
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
104
|
+
}
|
|
105
|
+
case 'DONE': {
|
|
106
|
+
const index = decelStopActiveIndex;
|
|
107
|
+
pause();
|
|
108
|
+
complete?.(index);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
activeIndex.value = currentIndex;
|
|
113
|
+
};
|
|
114
|
+
const play = () => {
|
|
115
|
+
if (playing.value) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
playing.value = true;
|
|
119
|
+
startTime = Date.now();
|
|
120
|
+
if (unref(startDelay) === 0) {
|
|
121
|
+
stage = 'ACCELERATED';
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
stage = 'START_DELAY';
|
|
125
|
+
}
|
|
126
|
+
ticker.add(tick);
|
|
127
|
+
};
|
|
128
|
+
const pause = () => {
|
|
129
|
+
ticker.remove(tick);
|
|
130
|
+
playing.value = false;
|
|
131
|
+
startTime = 0;
|
|
132
|
+
accelFrames = 0;
|
|
133
|
+
decelStopIndex = undefined;
|
|
134
|
+
decelStopActiveIndex = undefined;
|
|
135
|
+
decelStartIndex = 0;
|
|
136
|
+
};
|
|
137
|
+
const reset = () => {
|
|
138
|
+
pause();
|
|
139
|
+
stage = 'INITIAL';
|
|
140
|
+
currentIndex = 0;
|
|
141
|
+
activeIndex.value = undefined;
|
|
142
|
+
};
|
|
143
|
+
const stop = (index) => {
|
|
144
|
+
if (decelStopActiveIndex === undefined) {
|
|
145
|
+
decelStopActiveIndex =
|
|
146
|
+
index === undefined ? random(0, unref(count) - 1) : index;
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
onScopeDispose(() => {
|
|
150
|
+
pause();
|
|
151
|
+
});
|
|
152
|
+
return {
|
|
153
|
+
play,
|
|
154
|
+
stop,
|
|
155
|
+
pause,
|
|
156
|
+
reset,
|
|
157
|
+
playing: computed(() => playing.value),
|
|
158
|
+
activeIndex: computed(() => activeIndex.value),
|
|
159
|
+
};
|
|
160
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
import { type UseLuckyDrawOptions } from './useLuckyDraw';
|
|
3
|
+
export declare function getGridPrizeCount(row: number, column: number): number;
|
|
4
|
+
export declare function getGridCenterSize(row: number, column: number): {
|
|
5
|
+
row: number;
|
|
6
|
+
column: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function getGridIndex(row: number, column: number, index: number): number;
|
|
9
|
+
export interface UseLuckyGridOptions extends Omit<UseLuckyDrawOptions, 'count'> {
|
|
10
|
+
row?: number | Ref<number>;
|
|
11
|
+
column?: number | Ref<number>;
|
|
12
|
+
}
|
|
13
|
+
export declare function useLuckyGrid(options?: UseLuckyGridOptions): {
|
|
14
|
+
activeIndex: import("vue").ComputedRef<number | undefined>;
|
|
15
|
+
grids: import("vue").ComputedRef<number[]>;
|
|
16
|
+
centerSize: import("vue").ComputedRef<{
|
|
17
|
+
row: number;
|
|
18
|
+
column: number;
|
|
19
|
+
}>;
|
|
20
|
+
play: () => void;
|
|
21
|
+
stop: (index?: number | undefined) => void;
|
|
22
|
+
pause: () => void;
|
|
23
|
+
reset: () => void;
|
|
24
|
+
playing: import("vue").ComputedRef<boolean>;
|
|
25
|
+
};
|
|
26
|
+
export type UseLuckyGridReturn = ReturnType<typeof useLuckyGrid>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { computed, unref } from 'vue';
|
|
2
|
+
import { useLuckyDraw } from './useLuckyDraw';
|
|
3
|
+
export function getGridPrizeCount(row, column) {
|
|
4
|
+
return row === 1 ? column : column === 1 ? row : row * 2 + column * 2 - 4;
|
|
5
|
+
}
|
|
6
|
+
export function getGridCenterSize(row, column) {
|
|
7
|
+
return {
|
|
8
|
+
row: Math.max(row - 2, 0),
|
|
9
|
+
column: Math.max(column - 2, 0),
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function getGridIndex(row, column, index) {
|
|
13
|
+
if (index < column) {
|
|
14
|
+
return index;
|
|
15
|
+
}
|
|
16
|
+
if (index % column === column - 1) {
|
|
17
|
+
return column - 1 + ((index / column) >> 0);
|
|
18
|
+
}
|
|
19
|
+
if ((index / column) >> 0 === row - 1) {
|
|
20
|
+
return column * 2 + row - 3 - (index % column);
|
|
21
|
+
}
|
|
22
|
+
if (index % column === 0) {
|
|
23
|
+
return column * 2 + row * 2 - 4 - ((index / column) >> 0);
|
|
24
|
+
}
|
|
25
|
+
const rowNo = (index / column) >> 0;
|
|
26
|
+
const columnNo = index % column;
|
|
27
|
+
return ((rowNo - 1) * (column - 2) + columnNo) * -1;
|
|
28
|
+
}
|
|
29
|
+
const defaultOptions = {
|
|
30
|
+
row: 3,
|
|
31
|
+
column: 3,
|
|
32
|
+
endDelay: 500,
|
|
33
|
+
};
|
|
34
|
+
export function useLuckyGrid(options) {
|
|
35
|
+
const { row, column, ...restOptions } = Object.assign({}, defaultOptions, options);
|
|
36
|
+
const prizeCount = computed(() => getGridPrizeCount(unref(row), unref(column)));
|
|
37
|
+
const grids = computed(() => {
|
|
38
|
+
if (prizeCount.value === 0) {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
return Array(unref(row) * unref(column))
|
|
42
|
+
.fill(0)
|
|
43
|
+
.map((_, index) => getGridIndex(unref(row), unref(column), index));
|
|
44
|
+
});
|
|
45
|
+
const centerSize = computed(() => {
|
|
46
|
+
return getGridCenterSize(unref(row), unref(column));
|
|
47
|
+
});
|
|
48
|
+
const { activeIndex, ...restResult } = useLuckyDraw({
|
|
49
|
+
...restOptions,
|
|
50
|
+
count: prizeCount,
|
|
51
|
+
});
|
|
52
|
+
return {
|
|
53
|
+
...restResult,
|
|
54
|
+
activeIndex: computed(() => {
|
|
55
|
+
return activeIndex.value !== undefined
|
|
56
|
+
? activeIndex.value % prizeCount.value >> 0
|
|
57
|
+
: undefined;
|
|
58
|
+
}),
|
|
59
|
+
grids,
|
|
60
|
+
centerSize,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
import { type UseLuckyDrawOptions } from './useLuckyDraw';
|
|
3
|
+
export interface UseLuckyWheelOptions extends Omit<UseLuckyDrawOptions, 'count'> {
|
|
4
|
+
count?: number | Ref<number>;
|
|
5
|
+
}
|
|
6
|
+
export declare function useLuckyWheel(options?: UseLuckyWheelOptions): {
|
|
7
|
+
degrees: import("vue").ComputedRef<number>;
|
|
8
|
+
sectorDegrees: import("vue").ComputedRef<number>;
|
|
9
|
+
play: () => void;
|
|
10
|
+
stop: (index?: number | undefined) => void;
|
|
11
|
+
pause: () => void;
|
|
12
|
+
reset: () => void;
|
|
13
|
+
playing: import("vue").ComputedRef<boolean>;
|
|
14
|
+
};
|
|
15
|
+
export type UseLuckyWheelReturn = ReturnType<typeof useLuckyWheel>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { computed, unref } from 'vue';
|
|
2
|
+
import { useLuckyDraw } from './useLuckyDraw';
|
|
3
|
+
const defaultOptions = {
|
|
4
|
+
count: 8,
|
|
5
|
+
minSpeed: 0.01,
|
|
6
|
+
endDelay: 300,
|
|
7
|
+
};
|
|
8
|
+
export function useLuckyWheel(options) {
|
|
9
|
+
const { count, ...restOptions } = Object.assign({}, defaultOptions, options);
|
|
10
|
+
const { activeIndex, ...restResult } = useLuckyDraw({
|
|
11
|
+
...restOptions,
|
|
12
|
+
count,
|
|
13
|
+
});
|
|
14
|
+
return {
|
|
15
|
+
...restResult,
|
|
16
|
+
degrees: computed(() => {
|
|
17
|
+
return unref(count) === 0
|
|
18
|
+
? 0
|
|
19
|
+
: ((activeIndex.value || 0) / unref(count)) * 360;
|
|
20
|
+
}),
|
|
21
|
+
sectorDegrees: computed(() => {
|
|
22
|
+
return unref(count) === 0 ? 0 : 360 / unref(count);
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type Ref } from 'vue';
|
|
2
|
+
import { type UseLuckyDrawOptions } from './useLuckyDraw';
|
|
3
|
+
export interface UseSlotMachineOptions extends Omit<UseLuckyDrawOptions, 'count' | 'complete'> {
|
|
4
|
+
columns: number[] | unknown[][] | Ref<number[] | unknown[][]>;
|
|
5
|
+
staggerDelay?: number | Ref<number>;
|
|
6
|
+
complete?: (index: number[]) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function useSlotMachine(options: UseSlotMachineOptions): {
|
|
9
|
+
play: () => void;
|
|
10
|
+
stop: (index?: number[]) => void;
|
|
11
|
+
pause: () => void;
|
|
12
|
+
reset: () => void;
|
|
13
|
+
playing: import("vue").ComputedRef<boolean>;
|
|
14
|
+
offset: import("vue").ComputedRef<number[]>;
|
|
15
|
+
};
|
|
16
|
+
export type UseSlotMachineReturn = ReturnType<typeof useSlotMachine>;
|