-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
TimerMixin.ts
109 lines (94 loc) · 2.39 KB
/
TimerMixin.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { ComponentOptionsMixin } from 'vue-demi'
const TimerMixin: ComponentOptionsMixin = {
props: {
duration: {
type: Number,
required: false,
default: 3000, // Default timing: 3 seconds
},
},
data: () => ({
start: null,
elapsed: null,
hovered: false,
}),
computed: {
/**
* Return the elapsed timer percentage
*
* @returns { string }
*/
percentageElapsed() {
return ((this.elapsed / this.duration) * 100).toFixed(1)
},
/**
* Return the remaining time as milliseconds
*
* @returns { number }
*/
remaining() {
return this.duration - this.elapsed
},
},
/**
* Attach the event listeners for hovering management
* and start the timer and requestAnimationFrame loop.
*/
mounted() {
// Don't use duration if it is set to 0.
if (!this.duration || this.duration === 0) return
// Hover event
this.$el.addEventListener('mouseover', () => {
this.hovered = true
})
// Mouse out event
this.$el.addEventListener('mouseout', () => {
this.hovered = false
})
// Set start timestampp
this.start = Date.now()
// Initialize elapsed time
this.elapsed = 0
// Start requestAnimationFrame loop
requestAnimationFrame(this.updateTimer)
},
/**
* Remove event listeners for hovering management
*/
beforeUnmount() {
// Don't use duration if it is set to 0.
if (!this.duration || this.duration === 0) return
// Hover event
this.$el.removeEventListener('mouseover', () => {
this.hovered = true
})
// Mouse out event
this.$el.removeEventListener('mouseout', () => {
this.hovered = false
})
},
methods: {
/**
* Update timer loop
*/
updateTimer() {
// Check if the toast is hovered
if (!this.hovered) {
// Update elapsed time
this.elapsed = Date.now() - this.start
// Check if elapsed time is longer than showing duration
if (this.elapsed >= this.duration) {
// Emit the `remove` event
this.$emit('remove')
return
}
} else {
// Pause the timer by keeping the elapsed time the same by updating started time
this.start = Date.now() - this.elapsed
}
// Call another aniationFrame
requestAnimationFrame(this.updateTimer)
},
},
}
export default TimerMixin