import CSS from "./CSS"; import "./RippleEffect.css"; /** * Эффект волны. */ export default class RippleEffect { /** * Создание подложки. */ private static createOverlay(): HTMLDivElement { let container: HTMLDivElement = document.createElement( "div" ); container.classList.add( CSS.OVERLAY ); return container; } /** * Создание элемента для эффекта волны. */ private static createRipple(): HTMLDivElement { let container: HTMLDivElement = document.createElement( "div" ); container.classList.add( CSS.RIPPLE ); return container; } /** * Инициализация элемента, для которого будет применяться эффект волны. * * @param element Элемент. */ private initElement( element: HTMLElement ): void { let overlay: HTMLDivElement | null = null; let ripple: HTMLDivElement | null = null; element.addEventListener( "mousedown", ( event: MouseEvent ): void => { if ( ripple !== null ) { ripple.remove(); } if ( overlay !== null ) { overlay.remove(); } let rect: DOMRect = element.getBoundingClientRect(); let radius: number = Math.sqrt( Math.pow( rect.width, 2 ) + Math.pow( rect.height, 2 ) ); let diameter: number = radius * 2; let x: number = event.pageX - rect.x - radius; let y: number = event.pageY - rect.y - radius; ripple = RippleEffect.createRipple(); ripple.style.left = x + "px"; ripple.style.top = y + "px"; ripple.style.height = diameter + "px"; ripple.style.width = diameter + "px"; overlay = RippleEffect.createOverlay(); overlay.appendChild( ripple ); element.appendChild( overlay ); ripple.addEventListener( "animationend", () => { if ( ripple !== null ) { ripple.remove(); } if ( overlay !== null ) { overlay.remove(); } } ); } ); } /** * Конструктор. * * @param element Элемент, для которого будет применяться эффект волны. */ constructor( element: HTMLElement ) { this.initElement( element ); } /** * Создание эффекта волны для всех элементов, отмеченных атрибутом "data-sw-ripple-effect". */ public static create(): void { let elements: HTMLElement[] = Array.from( document.querySelectorAll( '[data-sw-ripple-effect]' ) ); for ( const element of elements ) { new RippleEffect( element ); } } }