mirror of
https://github.com/multipleofnpm/tiny-ripple.git
synced 2026-01-13 16:17:57 +00:00
32 lines
3.8 KiB
JavaScript
32 lines
3.8 KiB
JavaScript
if(window.__tinyRippleInitialized) throw new Error('tiny-ripple already initialized')
|
|
window.__tinyRippleInitialized = true
|
|
var __tinyRippleStyleElement = null
|
|
var __tinyRipplePointerHandler = null
|
|
var __tinyRippleFallbackTimeouts = []
|
|
var __tinyRippleDefaultDurationMs = 550
|
|
function prefersReducedMotion(){try{return window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches}catch(e){return false}}
|
|
if(prefersReducedMotion()){
|
|
window.tinyRipple = {disable:function(){window.__tinyRippleInitialized=false}}
|
|
} else {
|
|
var css = ":root{--tiny-ripple-color:rgba(0,0,0,.15);--tiny-ripple-duration:550ms;} .tiny-ripple{position:fixed;border-radius:50%;pointer-events:none;transform:translate(-50%,-50%) scale(0);background:var(--tiny-ripple-color);will-change:transform,opacity;z-index:2147483647} .tiny-ripple.tiny-ripple--anim{transition:transform var(--tiny-ripple-duration) cubic-bezier(.2,.8,.2,1),opacity var(--tiny-ripple-duration) linear;transform:translate(-50%,-50%) scale(1);opacity:0} "
|
|
__tinyRippleStyleElement = document.createElement('style')
|
|
__tinyRippleStyleElement.type = 'text/css'
|
|
__tinyRippleStyleElement.appendChild(document.createTextNode(css))
|
|
;(document.head||document.documentElement).appendChild(__tinyRippleStyleElement)
|
|
function getComputedDurationMs(){try{var v=getComputedStyle(document.documentElement).getPropertyValue('--tiny-ripple-duration')||'';v=v.trim();if(!v) return __tinyRippleDefaultDurationMs; if(v.endsWith('ms')) return Math.round(parseFloat(v)); if(v.endsWith('s')) return Math.round(parseFloat(v)*1000); return __tinyRippleDefaultDurationMs}catch(e){return __tinyRippleDefaultDurationMs}}
|
|
function removeElement(el){if(!el) return; if(el.parentNode) el.parentNode.removeChild(el)}
|
|
function makeRipple(x,y){var dx=Math.max(x,window.innerWidth-x),dy=Math.max(y,window.innerHeight-y);var r=Math.sqrt(dx*dx+dy*dy);var size=Math.ceil(r*2);var el=document.createElement('div');el.className='tiny-ripple';el.style.width=el.style.height=size+'px';el.style.left=x+'px';el.style.top=y+'px';document.body.appendChild(el);void el.getBoundingClientRect();el.classList.add('tiny-ripple--anim');var duration=getComputedDurationMs();var onEnd=function(){removeElement(el);el.removeEventListener('transitionend',onEnd)};el.addEventListener('transitionend',onEnd);var to=setTimeout(function(){removeElement(el);el.removeEventListener('transitionend',onEnd)},duration+100);__tinyRippleFallbackTimeouts.push(to)}
|
|
__tinyRipplePointerHandler = function(ev){if('button' in ev && ev.button!==0) return;var x=(ev.clientX!==undefined&&ev.clientX!==null)?ev.clientX:((ev.touches&&ev.touches[0]&&ev.touches[0].clientX)||0);var y=(ev.clientY!==undefined&&ev.clientY!==null)?ev.clientY:((ev.touches&&ev.touches[0]&&ev.touches[0].clientY)||0);makeRipple(x,y)}
|
|
if(window.PointerEvent) document.addEventListener('pointerdown',__tinyRipplePointerHandler,{passive:true})
|
|
else { document.addEventListener('touchstart',__tinyRipplePointerHandler,{passive:true}); document.addEventListener('mousedown',__tinyRipplePointerHandler,{passive:true}) }
|
|
window.tinyRipple = {
|
|
disable:function(){
|
|
if(window.PointerEvent) document.removeEventListener('pointerdown',__tinyRipplePointerHandler)
|
|
else { document.removeEventListener('touchstart',__tinyRipplePointerHandler); document.removeEventListener('mousedown',__tinyRipplePointerHandler) }
|
|
if(__tinyRippleStyleElement && __tinyRippleStyleElement.parentNode) __tinyRippleStyleElement.parentNode.removeChild(__tinyRippleStyleElement)
|
|
var nodes=document.querySelectorAll('.tiny-ripple');for(var i=0;i<nodes.length;i++) removeElement(nodes[i])
|
|
for(var j=0;j<__tinyRippleFallbackTimeouts.length;j++) clearTimeout(__tinyRippleFallbackTimeouts[j]);__tinyRippleFallbackTimeouts.length=0;window.__tinyRippleInitialized=false
|
|
}
|
|
}
|
|
}
|