79617073

Date: 2025-05-12 01:37:15
Score: 1
Natty:
Report link

here's the example code that looks similar to the typescript

unlike other ripple button with this link example

[https://css-tricks.com/how-to-recreate-the-ripple-effect-of-material-design-buttons/][1]

but with this code it's use the keyboard mouse and touch to start ripple effect on your button

here's the full code html with javascript and css

            function addRippleEffect(button) {
                const buttonColor = button.getAttribute('data-button-color');
                const hoverColor = button.getAttribute('data-hover-color');
                const textColor = button.getAttribute('data-text-color');
                const overlay = button.querySelector('.hover-overlay');
                
                if (buttonColor) {
                    button.style.backgroundColor = buttonColor;
                }
                if (textColor) {
                    button.style.color = textColor;
                }
                if (hoverColor) {
                    overlay.style.backgroundColor = hoverColor;
                }
    
                const ripples = new Set();
                let isInteractionActive = false;
                let initialTouchX = 0;
                let initialTouchY = 0;
                const moveThreshold = 10;
    
                function setHoverState() {
                    overlay.style.opacity = '0.3';
                }
    
                function resetState() {
                    overlay.style.opacity = '0';
                }
    
                button.addEventListener('mouseenter', setHoverState);
                button.addEventListener('focus', setHoverState);
    
                button.addEventListener('mouseleave', () => {
                    resetState();
                    fadeOutAllRipples();
                });
    
                function createRipple(e) {
                    let x, y;
                    const rect = button.getBoundingClientRect();
                    const size = Math.max(rect.width, rect.height);
                    
                    if (e instanceof KeyboardEvent) {
                        x = rect.width / 2 - size / 2;
                        y = rect.height / 2 - size / 2;
                    } else if (e.type === 'touchstart') {
                        e.preventDefault();
                        initialTouchX = e.touches[0].clientX;
                        initialTouchY = e.touches[0].clientY;
                        setHoverState();
                        x = e.touches[0].clientX - rect.left - size / 2;
                        y = e.touches[0].clientY - rect.top - size / 2;
                    } else {
                        x = e.clientX - rect.left - size / 2;
                        y = e.clientY - rect.top - size / 2;
                    }
                    
                    const ripple = document.createElement('span');
                    ripple.classList.add('ripple');
                    
                    ripple.style.width = size + 'px';
                    ripple.style.height = size + 'px';
                    ripple.style.left = x + 'px';
                    ripple.style.top = y + 'px';
                    ripple.style.background = button.getAttribute('data-ripple-color');
                    
                    button.appendChild(ripple);
                    
                    ripples.add(ripple);
                    
                    isInteractionActive = true;
                    
                    let scale = 0;
                    const scaleIncrement = 0.1 * (100 / size);
                    
                    function animate() {
                        if (!ripples.has(ripple)) return;
                        scale += scaleIncrement;
                        ripple.style.transform = `scale(${scale})`;
                        
                        requestAnimationFrame(animate);
                    }
                    
                    requestAnimationFrame(animate);
                }
    
                function fadeOutRipple(ripple) {
                    if (ripples.has(ripple)) {
                        ripple.classList.add('fade-out');
                        ripple.addEventListener('animationend', () => {
                            ripple.remove();
                            ripples.delete(ripple);
                        }, { once: true });
                    }
                }
    
                function fadeOutAllRipples() {
                    isInteractionActive = false;
                    ripples.forEach(fadeOutRipple);
                    resetState();
                }
    
                button.addEventListener('mousedown', createRipple);
                button.addEventListener('mouseup', () => {
                    if (isInteractionActive && button.getAttribute('href')) {
                        button.click();
                    }
                    fadeOutAllRipples();
                });
                button.addEventListener('mouseleave', fadeOutAllRipples);
    
                button.addEventListener('touchstart', createRipple, { passive: false });
                button.addEventListener('touchend', () => {
                    if (isInteractionActive && button.getAttribute('href')) {
                        button.click();
                    }
                    fadeOutAllRipples();
                });
                button.addEventListener('touchcancel', fadeOutAllRipples);
    
                button.addEventListener('touchmove', (e) => {
                    const touch = e.touches[0];
                    const rect = button.getBoundingClientRect();
                    
                    const dx = Math.abs(touch.clientX - initialTouchX);
                    const dy = Math.abs(touch.clientY - initialTouchY);
                    
                    if (dx > moveThreshold || dy > moveThreshold) {
                        fadeOutAllRipples();
                    }
                    
                    if (
                        touch.clientX < rect.left ||
                        touch.clientX > rect.right ||
                        touch.clientY < rect.top ||
                        touch.clientY > rect.bottom
                    ) {
                        fadeOutAllRipples();
                    }
                }, { passive: true });
    
                button.addEventListener('keydown', (e) => {
                    if (e.key === 'Enter' || e.key === ' ') {
                        e.preventDefault();
                        setHoverState();
                        createRipple(e);
                    }
                });
    
                button.addEventListener('keyup', (e) => {
                    if (e.key === 'Enter' || e.key === ' ') {
                        if (isInteractionActive && button.getAttribute('href')) {
                            button.click();
                        }
                        fadeOutAllRipples();
                    }
                });
    
                button.addEventListener('blur', fadeOutAllRipples);
    
                button.addEventListener('click', (e) => {
                    if (!isInteractionActive) {
                        e.preventDefault();
                        e.stopPropagation();
                    }
                });
            }
    
            document.querySelectorAll('a.button').forEach(button => {
                addRippleEffect(button);
            });
            a.button {
                display: inline-block;
                padding: 12px 24px;
                border: none;
                border-radius: 8px;
                cursor: pointer;
                font-size: 16px;
                font-family: Arial, sans-serif;
                text-decoration: none;
                text-align: center;
                position: relative;
                overflow: hidden;
                outline: none;
                margin: 10px;
            }
    
            a.button:focus-visible {
                box-shadow: 0 0 0 2px rgba(0, 0, 0, 0.3);
            }
    
            .hover-overlay {
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                opacity: 0;
                transition: opacity 0.3s ease;
                z-index: 1;
            }
    
            .ripple {
                position: absolute;
                border-radius: 50%;
                pointer-events: none;
                opacity: 0.5;
                transform: scale(0);
                z-index: 2;
            }
    
            .ripple.fade-out {
                animation: fadeOut 0.5s ease forwards;
            }
    
            @keyframes fadeOut {
                to {
                    opacity: 0;
                }
            }
        <a class="button"
           data-ripple-color="rgba(0, 0, 0, 0.5)" 
           data-button-color="rgb(255, 102, 102)" 
           data-hover-color="rgb(255, 51, 51)" 
           data-text-color="rgb(255, 255, 255)">
            <span class="hover-overlay"></span>
            Red Ripple
        </a>
        <a href="https://example.com/blue-page" class="button"
           data-ripple-color="rgba(0, 0, 0, 0.5)" 
           data-button-color="rgb(102, 102, 255)" 
           data-hover-color="rgb(51, 51, 255)" 
           data-text-color="rgb(255, 255, 255)">
            <span class="hover-overlay"></span>
            Blue Ripple
        </a>
        <a href="https://example.com/green-page" class="button"
           data-ripple-color="rgba(0, 0, 0, 0.5)" 
           data-button-color="rgb(102, 255, 102)" 
           data-hover-color="rgb(51, 255, 51)" 
           data-text-color="rgb(0, 0, 0)">
            <span class="hover-overlay"></span>
            Green Ripple
        </a>

Reasons:
  • Blacklisted phrase (1): this link
  • Long answer (-1):
  • Has code block (-0.5):
  • Unregistered user (0.5):
  • Low reputation (1):
Posted by: anonymous