UNPKG

nuxt-ripple

Version:

Add simple ripple effects to your elements

115 lines (114 loc) 5.01 kB
var RippleEvent = /* @__PURE__ */ ((RippleEvent2) => { RippleEvent2["CLICK"] = "mousedown"; RippleEvent2["HOVER"] = "mouseover"; RippleEvent2["TRANSITION_END"] = "transitionend"; return RippleEvent2; })(RippleEvent || {}); const cssTextBuilder = (options) => Object.entries(options).filter(([_, value]) => value !== void 0).map(([key, value]) => `${key}: ${value};`).join(""); const applyEffects = (el, styles, endTransition) => { el.style.cssText = cssTextBuilder(styles); if (endTransition) { el.addEventListener("transitionend" /* TRANSITION_END */, (event) => { const target = event.target; if (event.propertyName === "opacity" && target.className === "nuxt-ripple-animation") el.remove(); }, { once: true }); } else void el.offsetTop; }; export const addHeadStyles = (config) => { const styleId = "nuxt-ripple-styles"; const styleContent = `[data-ripple-bound="true"]{overflow: ${config.overflow === true ? "visible" : "hidden"};}[data-ripple-bound="true"] .nuxt-ripple-animation{background-color: var(--nuxt-ripple-background-color, ${config.color});transition: calc(var(--t, 0) * var(--nuxt-ripple-duration, ${config.duration}ms)) linear;transform: translate(-50%, -50%) scale(var(--s, ${config.scale}));}[data-ripple-bound="true"].nuxt-ripple-pulse .nuxt-ripple-animation{background-color: var(--nuxt-ripple-background-color, ${config.color});}`; const rippeStyles = document.getElementById(styleId); if (!rippeStyles) { const addStyle = document.createElement("style"); addStyle.id = styleId; addStyle.innerHTML = styleContent; document.head.appendChild(addStyle); } else { rippeStyles.innerHTML = styleContent; } }; const addRippleElement = (el) => { const ripple = document.createElement("span"); el.appendChild(ripple); ripple.classList.add("nuxt-ripple-animation"); return ripple; }; export const animationHandler = (e, el) => { const { clientX, clientY } = e.touches?.[0] || e; const { left, top, width, height } = el.getBoundingClientRect(); const rippleColor = el.getAttribute("data-ripple-color"); const rippleDuration = el.getAttribute("data-ripple-duration"); const rippleScale = el.getAttribute("data-ripple-scale"); const rippleEl = addRippleElement(el); applyEffects(rippleEl, { "--s": 0, "--o": 1, ...rippleColor ? { "--nuxt-ripple-background-color": rippleColor } : {} }); applyEffects(rippleEl, { "--t": 1, "--o": 0, "--d": Math.sqrt(width ** 2 + height ** 2) * 2, "--x": clientX - left, "--y": clientY - top, ...rippleScale ? { "--s": Number(rippleScale) } : {}, ...rippleColor ? { "--nuxt-ripple-background-color": rippleColor } : {}, ...rippleDuration ? { "--nuxt-ripple-duration": String(rippleDuration) + "ms" } : {} }, true); }; export const unmountListeners = (el, listeners, intervals) => { if (listeners.has(el) || intervals.has(el)) { const removeListener = listeners.get(el); if (removeListener) { el.removeEventListener("mouseover" /* HOVER */, removeListener); el.removeEventListener("mousedown" /* CLICK */, removeListener); listeners.delete(el); } const interval = intervals.get(el); if (intervals.get(el)) { clearInterval(interval); intervals.delete(el); } } }; export const modeHandler = (el, config, listeners, intervals) => { if (listeners.has(el)) return; el.classList.remove("nuxt-ripple-pulse"); const rippleMode = el.getAttribute("data-ripple-mode"); const ripplepulseInterval = Number(el.getAttribute("data-ripple-pulseInterval")) || config.pulseInterval; const rippleColor = el.getAttribute("data-ripple-color"); const rippleScale = el.getAttribute("data-ripple-scale"); const eventHandler = (e) => animationHandler(e, el); if (config.mode === "hover" && !rippleMode || rippleMode === "hover") { el.addEventListener("mouseover" /* HOVER */, eventHandler); listeners.set(el, eventHandler); } else if (config.mode === "pulse" && !rippleMode || rippleMode === "pulse") { el.classList.add("nuxt-ripple-pulse"); intervals.set(el, setInterval(() => { const { width, height } = el.getBoundingClientRect(); const rippleEl = addRippleElement(el); applyEffects(rippleEl, { "--s": 0, "--o": 1, ...rippleColor ? { "--nuxt-ripple-background-color": rippleColor } : {} }); applyEffects(rippleEl, { "--t": 1, "--o": 0, "--d": Math.sqrt(width ** 2 + height ** 2) * 2, ...rippleScale ? { "--s": Number(rippleScale) } : {}, ...rippleColor ? { "--nuxt-ripple-background-color": rippleColor } : {} }, true); }, ripplepulseInterval)); } else { el.addEventListener("mousedown" /* CLICK */, eventHandler); listeners.set(el, eventHandler); } }; export const setAttributes = (el, values) => { if (!values) return; for (const [key, value] of Object.entries(values)) { el.setAttribute(`data-ripple-${key}`, String(value)); } };