UNPKG

absolute-hover-cursor

Version:

Elevate user experience with seamless cursor interactions using hover-cursor, a small JS library. Create captivating web interfaces by dynamically crafting bespoke hover cursors that you can style however you need.

152 lines (151 loc) 7.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HoverCursor = void 0; var gsap_1 = require("gsap"); require("./main.css"); var HoverCursor = /** @class */ (function () { function HoverCursor(options) { var _this = this; this.mothers = document.querySelectorAll(options.containerQuery) || null; this.snapPosition = options.snapPosition || null; this.callbackFunction = options.toggledFunction; this.activeTitle = options.title; this.activeIcon = options.icon; this.toggledIcon = options.toggledIcon; if (this.mothers === null) { console.error('No containerQuery specified!'); return; } this.mothers.forEach(function (mother) { var cursorElement = null; var moveHandler; mother.style.position = 'relative'; // Handle mouse enter mother.addEventListener('mouseenter', function () { mother.style.cursor = 'none'; // Hide default cursor // Only create and append the cursor once if (!cursorElement) { cursorElement = _this.registerCustomCursor(options.customClass || ''); mother.appendChild(cursorElement); // Create move handler function to track mouse movement moveHandler = function (event) { _this.updateCursorPosition(cursorElement, event, mother); }; // Add the move event listener mother.addEventListener('mousemove', moveHandler); // Snap cursor if needed if (_this.snapPosition !== null) { _this.snapCustomCursor(cursorElement); } } }); // Handle mouse leave mother.addEventListener('mouseleave', function () { if (cursorElement) { // If snapPosition is null, remove the cursor if (_this.snapPosition === null) { cursorElement.remove(); } else { // Otherwise snap cursor _this.snapCustomCursor(cursorElement); } // Clean up event listener to avoid duplication mother.removeEventListener('mousemove', moveHandler); // Reset cursor element reference after it's removed cursorElement = null; } }); // Handle mouse click (toggle content) mother.addEventListener('click', function () { _this.activeTitle = _this.activeTitle === options.title ? options.toggledTitle : options.title; _this.activeIcon = _this.activeIcon === options.icon ? options.toggledIcon : options.icon; _this.toggleCustomCursorContent(mother); if (_this.callbackFunction) { _this.callbackFunction(); } }); }); } HoverCursor.prototype.updateCursorPosition = function (cursorElement, event, mother) { var x = event.clientX, y = event.clientY; // <- Get mouse position from MouseEvent var containerRect = mother.getBoundingClientRect(); // <- Get container position and size var containerScaleX = gsap_1.gsap.getProperty(mother, 'scaleX'); var containerScaleY = gsap_1.gsap.getProperty(mother, 'scaleY'); var containerTransformX = gsap_1.gsap.getProperty(mother, 'x'); var containerTransformY = gsap_1.gsap.getProperty(mother, 'y'); // Calculate the actual position within the scaled and transformed container var containerX = (x - containerRect.left - containerTransformX) / containerScaleX; // <- Calculate cursor X position within container var containerY = (y - containerRect.top - containerTransformY) / containerScaleY; // <- Calculate cursor Y position within container gsap_1.gsap.to(cursorElement, { left: "".concat(containerX, "px"), top: "".concat(containerY, "px"), duration: 0 }); // <- Animate cursor to cursor position }; HoverCursor.prototype.snapCustomCursor = function (cursorElement) { if (this.snapPosition === null) return; // If snapPosition is null, do nothing // Snap cursor to snapPosition (snap mode) - note we do not use right or bottom here as we do not want to override the transform origin or any previously calculated transform values switch (this.snapPosition) { case 'L': gsap_1.gsap.to(cursorElement, { left: '10%', top: '50%', duration: 0.2 }); break; case 'M': gsap_1.gsap.to(cursorElement, { left: '50%', top: '50%', duration: 0.2 }); break; case 'R': gsap_1.gsap.to(cursorElement, { left: '90%', top: '50%', duration: 0.2 }); break; } }; HoverCursor.prototype.registerCustomCursor = function (customClass) { var cursor = document.createElement('div'); var cursorTitle = document.createElement('p'); var cursorIcon = document.createElement('img'); customClass ? cursor.classList.add("hover-cursor", customClass) : cursor.classList.add("hover-cursor"); cursorTitle.classList.add("hover-cursor--title"); cursorIcon.classList.add('hover-cursor--icon'); if (this.activeIcon) { cursorIcon.src = this.activeIcon; cursorIcon.alt = 'Custom cursor icon'; cursorIcon.width = 35; cursorIcon.height = 35; } cursorTitle.innerHTML = this.activeTitle || ''; cursor.appendChild(cursorTitle); cursor.appendChild(cursorIcon); return cursor; }; HoverCursor.prototype.toggleCustomCursorContent = function (mother) { var cursor = mother.querySelector('div.hover-cursor'); if (cursor === null) { console.error('Cursor not found, please open an issue at https://bitbucket.org/absm/hover-cursor if you see this.'); return; } var cursorTitle = cursor.querySelector('p.hover-cursor--title'); var cursorIcon = cursor.querySelector('img.hover-cursor--icon'); if (cursorTitle === null || cursorIcon === null) { console.error('cursorTitle or cursorIcon not found, please open an issue at https://bitbucket.org/absm/hover-cursor if you see this.'); return; } cursorTitle.innerHTML = this.activeTitle || ''; cursorIcon.src = this.activeIcon || ''; }; HoverCursor.prototype.setIcon = function (icon) { this.activeIcon = icon; // Update the icon for any existing custom cursors var cursor = document.querySelector('div.hover-cursor'); var cursorIcon = cursor === null || cursor === void 0 ? void 0 : cursor.querySelector('img.hover-cursor--icon'); if (cursorIcon) { cursorIcon.src = icon; // Change the icon to the new source } }; HoverCursor.prototype.setToggledIcon = function (icon) { this.toggledIcon = icon; // Update the toggled icon for any existing custom cursors var cursor = document.querySelector('div.hover-cursor'); var cursorIcon = cursor === null || cursor === void 0 ? void 0 : cursor.querySelector('img.hover-cursor--icon'); if (cursorIcon) { cursorIcon.src = icon; // Change the toggled icon to the new source } }; return HoverCursor; }()); exports.HoverCursor = HoverCursor;