Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
corporate-culture-qd
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
王立鹏
corporate-culture-qd
Commits
2c4b70c7
Commit
2c4b70c7
authored
Jul 23, 2026
by
lijiabin
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
【需求 23684】feat: 优化大转盘动画和抽奖音乐
parent
2582dbc9
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
74 additions
and
35 deletions
+74
-35
lucky-wheel-happy-adventure.mp3
src/assets/audio/lucky-wheel-happy-adventure.mp3
+0
-0
LuckyWheel.vue
...ents/common/LuckyWheelContainer/components/LuckyWheel.vue
+42
-9
index.vue
src/components/common/LuckyWheelContainer/index.vue
+32
-26
No files found.
src/assets/audio/lucky-wheel-happy-adventure.mp3
0 → 100644
View file @
2c4b70c7
File added
src/components/common/LuckyWheelContainer/components/LuckyWheel.vue
View file @
2c4b70c7
...
@@ -30,6 +30,7 @@
...
@@ -30,6 +30,7 @@
<
script
lang=
"ts"
setup
>
<
script
lang=
"ts"
setup
>
import
{
LuckyWheel
}
from
'@lucky-canvas/vue'
import
{
LuckyWheel
}
from
'@lucky-canvas/vue'
import
ringTexture
from
'@/assets/img/lucky-wheel-outer-ring.svg'
import
ringTexture
from
'@/assets/img/lucky-wheel-outer-ring.svg'
import
spinMusic
from
'@/assets/audio/lucky-wheel-happy-adventure.mp3'
import
type
{
WheelPrizeItemDto
,
LuckWheelResultDto
,
WheelConfigDto
}
from
'@/api'
import
type
{
WheelPrizeItemDto
,
LuckWheelResultDto
,
WheelConfigDto
}
from
'@/api'
import
{
participateLuckyWheel
,
getWheelPrizeList
}
from
'@/api'
import
{
participateLuckyWheel
,
getWheelPrizeList
}
from
'@/api'
...
@@ -56,8 +57,8 @@ const myLucky = ref<InstanceType<typeof LuckyWheel>>()
...
@@ -56,8 +57,8 @@ const myLucky = ref<InstanceType<typeof LuckyWheel>>()
const
defaultConfig
=
{
const
defaultConfig
=
{
offsetDegree
:
0
,
offsetDegree
:
0
,
speed
:
20
,
speed
:
20
,
accelerationTime
:
25
00
,
accelerationTime
:
10
00
,
decelerationTime
:
25
00
,
decelerationTime
:
10
00
,
}
}
const
defaultStyle
=
{
const
defaultStyle
=
{
...
@@ -124,18 +125,42 @@ const buttons = [
...
@@ -124,18 +125,42 @@ const buttons = [
const
isSpinning
=
ref
(
false
)
const
isSpinning
=
ref
(
false
)
let
resultPrize
:
null
|
LuckWheelResultDto
=
null
let
resultPrize
:
null
|
LuckWheelResultDto
=
null
let
spinAudio
:
HTMLAudioElement
|
null
=
null
const
startSpinMusic
=
()
=>
{
stopSpinMusic
()
spinAudio
||=
new
Audio
(
spinMusic
)
spinAudio
.
loop
=
true
spinAudio
.
volume
=
0.35
spinAudio
.
play
().
catch
(()
=>
{})
}
const
stopSpinMusic
=
()
=>
{
if
(
!
spinAudio
)
return
spinAudio
.
pause
()
spinAudio
.
currentTime
=
0
}
const
startCallback
=
async
()
=>
{
const
startCallback
=
async
()
=>
{
if
(
isSpinning
.
value
)
return
if
(
isSpinning
.
value
)
return
isSpinning
.
value
=
true
isSpinning
.
value
=
true
startSpinMusic
()
myLucky
.
value
?.
play
()
myLucky
.
value
?.
play
()
setTimeout
(
async
()
=>
{
setTimeout
(
async
()
=>
{
const
{
data
}
=
await
participateLuckyWheel
()
try
{
const
idx
=
computedPrizes
.
value
.
findIndex
((
item
)
=>
item
.
id
===
data
.
prizeId
)
const
{
data
}
=
await
participateLuckyWheel
()
myLucky
.
value
?.
stop
(
idx
)
const
idx
=
computedPrizes
.
value
.
findIndex
((
item
)
=>
item
.
id
===
data
.
prizeId
)
yabiStore
.
fetchYaBiData
()
myLucky
.
value
?.
stop
(
idx
)
resultPrize
=
data
yabiStore
.
fetchYaBiData
()
},
1000
)
resultPrize
=
data
}
catch
(
error
)
{
console
.
error
(
error
)
stopSpinMusic
()
isSpinning
.
value
=
false
}
},
600
)
}
}
// 获取最新的奖品列表 对比 是否更新了
// 获取最新的奖品列表 对比 是否更新了
...
@@ -185,7 +210,7 @@ const endCallback = () => {
...
@@ -185,7 +210,7 @@ const endCallback = () => {
setTimeout(() => {
setTimeout(() => {
isSpinning.value = false
isSpinning.value = false
emit('handlePrizeResult', resultPrize as LuckWheelResultDto)
emit('handlePrizeResult', resultPrize as LuckWheelResultDto)
},
50
0)
},
28
0)
}
}
const initWheelPrizeList = async () => {
const initWheelPrizeList = async () => {
...
@@ -195,6 +220,14 @@ const initWheelPrizeList = async () => {
...
@@ -195,6 +220,14 @@ const initWheelPrizeList = async () => {
onMounted(() => {
onMounted(() => {
initWheelPrizeList()
initWheelPrizeList()
})
})
onBeforeUnmount(() => {
stopSpinMusic()
})
defineExpose({
stopSpinMusic,
})
</
script
>
</
script
>
<
style
scoped
>
<
style
scoped
>
...
...
src/components/common/LuckyWheelContainer/index.vue
View file @
2c4b70c7
<
template
>
<
template
>
<Comp
:wheelConfig=
"wheelConfig"
@
handle-prize-result=
"handlePrizeResult"
/>
<Comp
ref=
"luckyWheelRef"
:wheelConfig=
"wheelConfig"
@
handle-prize-result=
"handlePrizeResult"
/>
<Teleport
to=
"body"
>
<Teleport
to=
"body"
>
<Transition
name=
"result"
>
<Transition
name=
"result"
>
<div
<div
...
@@ -84,7 +84,7 @@
...
@@ -84,7 +84,7 @@
<p
class=
"blessing-caption-subtitle"
>
抽一支好运电子签,把今天过得亮一点
</p>
<p
class=
"blessing-caption-subtitle"
>
抽一支好运电子签,把今天过得亮一点
</p>
</div>
</div>
<el-button
class=
"mt-8"
type=
"primary"
@
click=
"
showResult = false
"
>
知道了
</el-button>
<el-button
class=
"mt-8"
type=
"primary"
@
click=
"
closeResult
"
>
知道了
</el-button>
</
template
>
</
template
>
<
template
v-else
>
<
template
v-else
>
...
@@ -92,7 +92,7 @@
...
@@ -92,7 +92,7 @@
<div
class=
"mt-6 text-white text-3xl font-bold"
>
<div
class=
"mt-6 text-white text-3xl font-bold"
>
恭喜获得
{{
currentPrize
?.
prizeName
}}
恭喜获得
{{
currentPrize
?.
prizeName
}}
</div>
</div>
<el-button
class=
"mt-8"
type=
"primary"
@
click=
"
showResult = false
"
>
知道了
</el-button>
<el-button
class=
"mt-8"
type=
"primary"
@
click=
"
closeResult
"
>
知道了
</el-button>
</
template
>
</
template
>
</div>
</div>
</Transition>
</Transition>
...
@@ -112,6 +112,7 @@ const { wheelConfig } = defineProps<{
...
@@ -112,6 +112,7 @@ const { wheelConfig } = defineProps<{
const
showResult
=
ref
(
false
)
const
showResult
=
ref
(
false
)
const
currentPrize
=
ref
<
LuckWheelResultDto
|
null
>
(
null
)
const
currentPrize
=
ref
<
LuckWheelResultDto
|
null
>
(
null
)
const
luckyWheelRef
=
ref
<
InstanceType
<
typeof
Comp
>>
()
const
blessingWrapRef
=
ref
<
HTMLElement
|
null
>
(
null
)
const
blessingWrapRef
=
ref
<
HTMLElement
|
null
>
(
null
)
const
blessingGlowRef
=
ref
<
HTMLElement
|
null
>
(
null
)
const
blessingGlowRef
=
ref
<
HTMLElement
|
null
>
(
null
)
...
@@ -305,10 +306,10 @@ const playBlessingAnimation = () => {
...
@@ -305,10 +306,10 @@ const playBlessingAnimation = () => {
})
})
blessingTimeline
blessingTimeline
.
to
(
scene
,
{
opacity
:
1
,
y
:
0
,
duration
:
0.
4
5
})
.
to
(
scene
,
{
opacity
:
1
,
y
:
0
,
duration
:
0.
3
5
})
.
to
(
glow
,
{
opacity
:
0.95
,
scale
:
1
,
duration
:
0.
7
,
ease
:
'sine.out'
},
'<'
)
.
to
(
glow
,
{
opacity
:
0.95
,
scale
:
1
,
duration
:
0.
55
,
ease
:
'sine.out'
},
'<'
)
.
to
(
slot
,
{
opacity
:
1
,
scaleX
:
1
,
duration
:
0.
52
},
'-=0.3
'
)
.
to
(
slot
,
{
opacity
:
1
,
scaleX
:
1
,
duration
:
0.
42
},
'-=0.26
'
)
.
to
(
fan
,
{
opacity
:
1
,
y
:
0
,
duration
:
0.4
},
'<'
)
.
to
(
fan
,
{
opacity
:
1
,
y
:
0
,
duration
:
0.
3
4
},
'<'
)
.
to
(
.
to
(
fanItems
,
fanItems
,
{
{
...
@@ -316,10 +317,10 @@ const playBlessingAnimation = () => {
...
@@ -316,10 +317,10 @@ const playBlessingAnimation = () => {
y
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-y'
)
||
0
),
y
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-y'
)
||
0
),
rotate
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-angle'
)
||
0
),
rotate
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-angle'
)
||
0
),
scale
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-scale'
)
||
1
),
scale
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-scale'
)
||
1
),
duration
:
0.
9
,
duration
:
0.
7
,
ease
:
'back.out(1.08)'
,
ease
:
'back.out(1.08)'
,
stagger
:
{
stagger
:
{
each
:
0.0
55
,
each
:
0.0
42
,
from
:
'center'
,
from
:
'center'
,
},
},
},
},
...
@@ -329,16 +330,16 @@ const playBlessingAnimation = () => {
...
@@ -329,16 +330,16 @@ const playBlessingAnimation = () => {
fanItems
,
fanItems
,
{
{
x
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-x'
)
||
0
)
*
0.1
,
x
:
(
_index
,
target
)
=>
Number
(
target
.
getAttribute
(
'data-x'
)
||
0
)
*
0.1
,
duration
:
0.
32
,
duration
:
0.
26
,
ease
:
'power1.inOut'
,
ease
:
'power1.inOut'
,
stagger
:
{
stagger
:
{
each
:
0.0
2
,
each
:
0.0
16
,
from
:
'edges'
,
from
:
'edges'
,
},
},
yoyo
:
true
,
yoyo
:
true
,
repeat
:
1
,
repeat
:
1
,
},
},
'+=0.
26
'
,
'+=0.
18
'
,
)
)
.
to
(
.
to
(
blessingTagStageRef
.
value
,
blessingTagStageRef
.
value
,
...
@@ -346,10 +347,10 @@ const playBlessingAnimation = () => {
...
@@ -346,10 +347,10 @@ const playBlessingAnimation = () => {
opacity
:
1
,
opacity
:
1
,
y
:
0
,
y
:
0
,
filter
:
'blur(0px)'
,
filter
:
'blur(0px)'
,
duration
:
0.
48
,
duration
:
0.
36
,
ease
:
'power2.out'
,
ease
:
'power2.out'
,
},
},
'+=0.0
2
'
,
'+=0.0
1
'
,
)
)
.
to
(
.
to
(
tag
,
tag
,
...
@@ -358,7 +359,7 @@ const playBlessingAnimation = () => {
...
@@ -358,7 +359,7 @@ const playBlessingAnimation = () => {
opacity
:
0.5
,
opacity
:
0.5
,
scale
:
0.97
,
scale
:
0.97
,
filter
:
'blur(6px)'
,
filter
:
'blur(6px)'
,
duration
:
0.
42
,
duration
:
0.
34
,
ease
:
'power2.out'
,
ease
:
'power2.out'
,
},
},
'<'
,
'<'
,
...
@@ -370,10 +371,10 @@ const playBlessingAnimation = () => {
...
@@ -370,10 +371,10 @@ const playBlessingAnimation = () => {
opacity
:
1
,
opacity
:
1
,
scale
:
1.01
,
scale
:
1.01
,
filter
:
'blur(1px)'
,
filter
:
'blur(1px)'
,
duration
:
1.08
,
duration
:
0.82
,
ease
:
'power3.out'
,
ease
:
'power3.out'
,
},
},
'+=0.
1
'
,
'+=0.
08
'
,
)
)
.
to
(
.
to
(
tag
,
tag
,
...
@@ -382,10 +383,10 @@ const playBlessingAnimation = () => {
...
@@ -382,10 +383,10 @@ const playBlessingAnimation = () => {
rotation
:
-
1.4
,
rotation
:
-
1.4
,
scale
:
1.015
,
scale
:
1.015
,
filter
:
'blur(0px)'
,
filter
:
'blur(0px)'
,
duration
:
0.
3
,
duration
:
0.
24
,
ease
:
'power2.out'
,
ease
:
'power2.out'
,
},
},
'-=0.1
8
'
,
'-=0.1
4
'
,
)
)
.
to
(
.
to
(
tag
,
tag
,
...
@@ -394,19 +395,19 @@ const playBlessingAnimation = () => {
...
@@ -394,19 +395,19 @@ const playBlessingAnimation = () => {
rotation
:
0.4
,
rotation
:
0.4
,
scale
:
1
,
scale
:
1
,
filter
:
'blur(0px)'
,
filter
:
'blur(0px)'
,
duration
:
0.
32
,
duration
:
0.
26
,
ease
:
'back.out(1.5)'
,
ease
:
'back.out(1.5)'
,
},
},
'+=0.0
2
'
,
'+=0.0
1
'
,
)
)
.
to
(
tagTop
,
{
opacity
:
1
,
duration
:
0.
22
},
'<'
)
.
to
(
tagTop
,
{
opacity
:
1
,
duration
:
0.
18
},
'<'
)
.
to
(
.
to
(
chars
,
chars
,
{
{
opacity
:
1
,
opacity
:
1
,
y
:
0
,
y
:
0
,
duration
:
0.
34
,
duration
:
0.
28
,
stagger
:
0.05
,
stagger
:
0.0
3
5
,
},
},
'-=0.08'
,
'-=0.08'
,
)
)
...
@@ -415,7 +416,7 @@ const playBlessingAnimation = () => {
...
@@ -415,7 +416,7 @@ const playBlessingAnimation = () => {
{
{
opacity
:
1
,
opacity
:
1
,
y
:
0
,
y
:
0
,
duration
:
0.2
8
,
duration
:
0.2
2
,
},
},
'-=0.12'
,
'-=0.12'
,
)
)
...
@@ -424,7 +425,7 @@ const playBlessingAnimation = () => {
...
@@ -424,7 +425,7 @@ const playBlessingAnimation = () => {
{
{
opacity
:
1
,
opacity
:
1
,
y
:
0
,
y
:
0
,
duration
:
0.
42
,
duration
:
0.
34
,
},
},
'-=0.02'
,
'-=0.02'
,
)
)
...
@@ -461,6 +462,11 @@ const handlePrizeResult = (prize: LuckWheelResultDto) => {
...
@@ -461,6 +462,11 @@ const handlePrizeResult = (prize: LuckWheelResultDto) => {
currentPrize
.
value
=
prize
currentPrize
.
value
=
prize
showResult
.
value
=
true
showResult
.
value
=
true
}
}
const
closeResult
=
()
=>
{
showResult
.
value
=
false
luckyWheelRef
.
value
?.
stopSpinMusic
()
}
</
script
>
</
script
>
<
style
>
<
style
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment