Update index.js

This commit is contained in:
2025-08-20 00:46:08 -07:00
committed by GitHub
parent 87b0e54aa1
commit ff2ac31966

217
index.js
View File

@@ -1,2 +1,215 @@
if(window.__tinyRippleInit) throw new Error('tiny-ripple already initialized') window.__tinyRippleInit = true var __tr_style = document.createElement('style') __tr_style.textContent = ".r{position:fixed;border-radius:50%;pointer-events:none;background:transparent;box-shadow:0 8px 18px rgba(0,0,0,0.14);transform:translate(-50%,-50%) scale(.15);opacity:1;transition:transform .42s cubic-bezier(.2,.8,.2,1),opacity .42s linear,box-shadow .42s linear;z-index:9999999}.r.a{transform:translate(-50%,-50%) scale(1);opacity:0;box-shadow:0 0 0 rgba(0,0,0,0)}" document.head.appendChild(__tr_style) var __tr_dur = 420 function __tr_make(x,y){var dx=Math.max(x,innerWidth-x),dy=Math.max(y,innerHeight-y),r=Math.hypot(dx,dy),s=Math.max(48,Math.ceil(r*2));var e=document.createElement('div');e.className='r';e.style.width=e.style.height=s+'px';e.style.left=x+'px';e.style.top=y+'px';document.body.appendChild(e);void e.offsetWidth;e.classList.add('a');setTimeout(function(){if(e.parentNode) e.parentNode.removeChild(e)},__tr_dur+60)} var __tr_h = function(ev){var x=('clientX' in ev && ev.clientX!=null)?ev.clientX:(ev.touches&&ev.touches[0]&&ev.touches[0].clientX)||0;var y=('clientY' in ev && ev.clientY!=null)?ev.clientY:(ev.touches&&ev.touches[0]&&ev.touches[0].clientY)||0;__tr_make(x,y)} if(window.PointerEvent) addEventListener('pointerdown',__tr_h,{passive:true}); else{addEventListener('touchstart',__tr_h,{passive:true});addEventListener('mousedown',__tr_h,{passive:true})} window.tinyRipple={disable:function(){if(window.PointerEvent) removeEventListener('pointerdown',__tr_h);else{removeEventListener('touchstart',__tr_h);removeEventListener('mousedown',__tr_h)}if(__tr_style.parentNode) __tr_style.parentNode.removeChild(__tr_style);window.__tinyRippleInit=false}}
/*!
* tiny-ripple v0.1.0
* A lightweight library that adds subtle ripple effects on touch/click interactions
* https://github.com/yourusername/tiny-ripple
*
* Copyright (c) 2025
* Licensed under MIT
*/
(function() {
'use strict';
const defaultOptions = {
size: 60,
duration: 500,
color: 'rgba(0,0,0,0.3)',
zIndex: 9999,
debounceDelay: 100
};
let isInitialized = false;
let lastRippleTime = 0;
let touchStartY = null;
let touchStartTime = null;
/**
* Create a ripple effect at specified coordinates
* @param {number} x - X coordinate
* @param {number} y - Y coordinate
* @param {Object} options - Custom options
*/
function createRipple(x, y, options = {}) {
const opts = { ...defaultOptions, ...options };
const ripple = document.createElement('div');
ripple.setAttribute('data-tiny-ripple', '');
// Set position and initial size
const size = opts.size;
ripple.style.cssText = `
position: fixed;
left: ${x - size/2}px;
top: ${y - size/2}px;
width: ${size}px;
height: ${size}px;
border-radius: 50%;
pointer-events: none;
z-index: ${opts.zIndex};
background: radial-gradient(circle, ${opts.color} 0%, ${opts.color.replace('0.3', '0.05')} 70%, transparent 100%);
animation: tiny-ripple-animation ${opts.duration}ms cubic-bezier(0.25, 0.46, 0.45, 0.94) forwards;
mix-blend-mode: multiply;
`;
document.body.appendChild(ripple);
// Remove the ripple after animation
setTimeout(() => {
if (ripple.parentNode) {
ripple.parentNode.removeChild(ripple);
}
}, opts.duration);
}
/**
* Handle touch start to track potential scrolling
*/
function handleTouchStart(e) {
if (e.touches.length === 1) {
touchStartY = e.touches[0].clientY;
touchStartTime = Date.now();
}
}
/**
* Handle touch move to detect if user is scrolling
*/
function handleTouchMove(e) {
if (touchStartY !== null && e.touches.length === 1) {
const currentY = e.touches[0].clientY;
const deltaY = Math.abs(currentY - touchStartY);
const deltaTime = Date.now() - touchStartTime;
// If moved more than 10px vertically in less than 300ms, it's likely scrolling
if (deltaY > 10 && deltaTime < 300) {
touchStartY = null; // Mark as scrolling gesture
}
}
}
/**
* Handle touch end - create ripple if it wasn't a scroll gesture
*/
function handleTouchEnd(e) {
// Only create ripple if touchStartY is still set (meaning no scroll detected)
if (touchStartY !== null && e.changedTouches.length === 1) {
const now = Date.now();
// Debounce check
if (now - lastRippleTime >= defaultOptions.debounceDelay) {
lastRippleTime = now;
const touch = e.changedTouches[0];
createRipple(touch.clientX, touch.clientY);
}
}
// Reset tracking
touchStartY = null;
touchStartTime = null;
}
/**
* Handle mouse events (desktop)
*/
function handleMouseDown(e) {
const now = Date.now();
// Debounce check
if (now - lastRippleTime < defaultOptions.debounceDelay) {
return;
}
lastRippleTime = now;
createRipple(e.clientX, e.clientY);
}
/**
* Add required CSS keyframes
*/
function addCSS() {
if (document.querySelector('#tiny-ripple-styles')) return;
const style = document.createElement('style');
style.id = 'tiny-ripple-styles';
style.textContent = `
@keyframes tiny-ripple-animation {
0% {
transform: scale(0);
opacity: 1;
}
100% {
transform: scale(4);
opacity: 0;
}
}
`;
document.head.appendChild(style);
}
/**
* Initialize the ripple effect library
*/
function init(options = {}) {
if (isInitialized) return;
// Merge custom options
Object.assign(defaultOptions, options);
// Add CSS
addCSS();
// Add event listeners
document.addEventListener('touchstart', handleTouchStart, { passive: true });
document.addEventListener('touchmove', handleTouchMove, { passive: true });
document.addEventListener('touchend', handleTouchEnd, { passive: true });
document.addEventListener('mousedown', handleMouseDown, { passive: true });
isInitialized = true;
}
/**
* Destroy the ripple effect (remove event listeners and styles)
*/
function destroy() {
if (!isInitialized) return;
document.removeEventListener('touchstart', handleTouchStart);
document.removeEventListener('touchmove', handleTouchMove);
document.removeEventListener('touchend', handleTouchEnd);
document.removeEventListener('mousedown', handleMouseDown);
// Remove existing ripples
const ripples = document.querySelectorAll('[data-tiny-ripple]');
ripples.forEach(ripple => ripple.remove());
// Remove styles
const styles = document.querySelector('#tiny-ripple-styles');
if (styles) styles.remove();
isInitialized = false;
}
/**
* Auto-initialize when DOM is ready
*/
function autoInit() {
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
}
// Public API
window.TinyRipple = {
init,
destroy,
createRipple,
isInitialized: () => isInitialized,
version: '0.1.0'
};
// Auto-initialize immediately
autoInit();
})();