Skip to content

Commit e7cb785

Browse files
author
Корпусов Максим
committed
fix: better mobile support
1 parent 0bb3523 commit e7cb785

File tree

1 file changed

+45
-11
lines changed

1 file changed

+45
-11
lines changed

lib/src/components/MStateLayer.vue

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
<template>
22
<div
33
ref="stateEl"
4-
class="absolute top-0 left-0 right-0 bottom-0 cursor-pointer opacity-0 hover:opacity-[8%] focus:opacity-[12%] active:opacity-[12%]"
5-
:class="{ 'pointer-events-none': disabled }"
4+
class="mv-absolute mv-top-0 mv-left-0 mv-right-0 mv-bottom-0 mv-cursor-pointer mv-opacity-0 sm:hover:mv-opacity-[8%] sm:focus:mv-opacity-[12%] sm:active:mv-opacity-[12%]"
5+
:class="[classes, { 'mv-pointer-events-none': disabled }]"
66
:style="`${background}`"
7+
@click.stop
78
/>
89
<span
10+
v-show="rippled"
911
ref="rippleEl"
10-
class="ripple opacity-0 absolute pointer-events-none"
12+
class="ripple mv-opacity-0 mv-absolute mv-pointer-events-none"
1113
:style="`
1214
background: radial-gradient(
1315
closest-side,
@@ -36,8 +38,18 @@ const props = defineProps({
3638
type: String,
3739
default: null,
3840
},
41+
rippled: {
42+
type: Boolean,
43+
default: true,
44+
},
45+
classes: {
46+
type: String,
47+
default: null,
48+
},
3949
})
4050
51+
const emits = defineEmits(['click'])
52+
4153
const stateEl = ref(null)
4254
const rippleEl = ref(null)
4355
const rectWidth = ref(null)
@@ -73,6 +85,7 @@ function getEndPoint() {
7385
let animation = null
7486
7587
function handleTouchStart(event) {
88+
shouldEmit.value = true
7689
showRipple.value = true
7790
ripplePos.value.x = event.offsetX
7891
ripplePos.value.y = event.offsetY
@@ -101,6 +114,8 @@ function handleTouchStart(event) {
101114
)
102115
}
103116
async function handleTouchEnd() {
117+
if (showRipple.value === false) return
118+
104119
let pressAnimationPlayState = Infinity
105120
if (typeof animation?.currentTime === 'number') {
106121
pressAnimationPlayState = animation.currentTime
@@ -120,7 +135,15 @@ async function handleTouchEnd() {
120135
animEnd()
121136
}
122137
123-
function animEnd() {
138+
const shouldEmit = ref(true)
139+
140+
function handleTouchLeave() {
141+
if (showRipple.value === false) return
142+
shouldEmit.value = false
143+
animEnd()
144+
}
145+
146+
async function animEnd() {
124147
showRipple.value = false
125148
126149
rippleEl.value.animate(
@@ -133,15 +156,25 @@ function animEnd() {
133156
easing: EASING.STANDARD_ACCELERATE,
134157
}
135158
)
159+
160+
if (!shouldEmit.value) return
161+
162+
await new Promise((resolve) => {
163+
setTimeout(resolve, 30)
164+
})
165+
166+
emits('click')
167+
shouldEmit.value = false
136168
}
137169
138170
let rippleScale = null
139171
let initialSize = null
140172
141173
onMounted(() => {
142-
stateEl.value.addEventListener('mousedown', handleTouchStart)
143-
stateEl.value.addEventListener('mouseup', handleTouchEnd)
144-
stateEl.value.addEventListener('mouseleave', handleTouchEnd)
174+
stateEl.value.addEventListener('pointerdown', handleTouchStart)
175+
stateEl.value.addEventListener('pointerup', handleTouchEnd)
176+
stateEl.value.addEventListener('contextmenu', handleTouchLeave)
177+
stateEl.value.addEventListener('pointerleave', handleTouchLeave)
145178
146179
const { height, width } = stateEl.value.getBoundingClientRect()
147180
const maxDim = Math.max(height, width)
@@ -160,15 +193,16 @@ onMounted(() => {
160193
161194
onUnmounted(() => {
162195
if (stateEl.value) {
163-
stateEl.value.removeEventListener('mousedown', handleTouchStart)
164-
stateEl.value.removeEventListener('mouseup', handleTouchEnd)
165-
stateEl.value.removeEventListener('mouseleave', handleTouchEnd)
196+
stateEl.value.removeEventListener('pointerdown', handleTouchStart)
197+
stateEl.value.removeEventListener('pointerup', handleTouchEnd)
198+
stateEl.value.removeEventListener('contextmenu', handleTouchLeave)
199+
stateEl.value.removeEventListener('pointerleave', handleTouchLeave)
166200
}
167201
})
168202
</script>
169203
170204
<script>
171205
export default {
172-
name: 'MVStateLayer',
206+
name: 'MStateLayer',
173207
}
174208
</script>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy