|
1 |
| -import { onBeforeMount, ref } from 'vue' |
2 |
| -import { type MaybeRefOrGetter, useEventListener } from '@vueuse/core' |
| 1 | +import { onBeforeMount, ref } from "vue"; |
| 2 | +import { type MaybeRefOrGetter, useEventListener } from "@vueuse/core"; |
3 | 3 |
|
4 |
| -const rippleElement = ref() |
| 4 | +const rippleElement = ref(); |
5 | 5 |
|
6 | 6 | function setCSSStyle(el: HTMLElement, style: CSSStyleDeclaration) {
|
7 | 7 | for (const [key, value] of Object.entries(style)) {
|
8 |
| - el.style[key as any] = value |
| 8 | + el.style[key as any] = value; |
9 | 9 | }
|
10 | 10 | }
|
11 | 11 |
|
12 | 12 | function ripple(event: MouseEvent) {
|
13 |
| - const target = event.currentTarget as HTMLElement |
14 |
| - const { x, y, width, height } = target.getBoundingClientRect() |
15 |
| - const { clientX, clientY } = event |
| 13 | + const target = event.currentTarget as HTMLElement; |
| 14 | + const { x, y, width, height } = target.getBoundingClientRect(); |
| 15 | + const { clientX, clientY } = event; |
16 | 16 |
|
17 |
| - const newElement = rippleElement.value?.cloneNode() as HTMLSpanElement |
| 17 | + const newElement = rippleElement.value?.cloneNode() as HTMLSpanElement; |
18 | 18 | const style = {
|
19 |
| - position: 'absolute', |
| 19 | + position: "absolute", |
20 | 20 | left: `${clientX - x}px`,
|
21 | 21 | top: `${clientY - y}px`,
|
22 |
| - borderRadius: '50%', |
23 |
| - background: 'white', |
| 22 | + borderRadius: "50%", |
| 23 | + backgroundColor: "currentColor", |
24 | 24 | transform: `translate(-50%, -50%)`,
|
25 |
| - pointerEvents: 'none', |
26 |
| - } as CSSStyleDeclaration |
| 25 | + pointerEvents: "none", |
| 26 | + } as CSSStyleDeclaration; |
27 | 27 |
|
28 |
| - setCSSStyle(newElement, style) |
| 28 | + setCSSStyle(newElement, style); |
29 | 29 |
|
30 |
| - const radius = Math.round(Math.hypot(width, height)) * 2 |
| 30 | + const radius = Math.round(Math.hypot(width, height)) * 2; |
31 | 31 | const animate = newElement.animate(
|
32 | 32 | {
|
33 |
| - opacity: [0.5, 0], |
34 |
| - width: ['0', `${radius}px`], |
35 |
| - height: ['0', `${radius}px`], |
| 33 | + opacity: [0.35, 0], |
| 34 | + width: ["0", `${radius}px`], |
| 35 | + height: ["0", `${radius}px`], |
36 | 36 | },
|
37 | 37 | {
|
38 | 38 | duration: 450,
|
39 |
| - easing: 'ease-in', |
40 |
| - fill: 'forwards', |
| 39 | + easing: "ease-in", |
| 40 | + fill: "forwards", |
41 | 41 | },
|
42 |
| - ) |
43 |
| - animate.addEventListener('finish', () => { |
44 |
| - target.removeChild(newElement) |
45 |
| - }) |
46 |
| - target.appendChild(newElement) |
| 42 | + ); |
| 43 | + animate.addEventListener("finish", () => { |
| 44 | + target.removeChild(newElement); |
| 45 | + }); |
| 46 | + target.appendChild(newElement); |
47 | 47 | }
|
48 | 48 |
|
49 | 49 | export function useRipple(
|
50 | 50 | target: MaybeRefOrGetter<HTMLElement | null | undefined>,
|
51 | 51 | ) {
|
52 | 52 | onBeforeMount(() => {
|
53 |
| - rippleElement.value = document.createElement('span') |
54 |
| - }) |
55 |
| - useEventListener(target, 'click', ripple) |
| 53 | + rippleElement.value = document.createElement("span"); |
| 54 | + }); |
| 55 | + useEventListener(target, "click", ripple); |
56 | 56 | }
|
57 | 57 |
|
58 |
| -export default useRipple |
| 58 | +export default useRipple; |
0 commit comments