WEBLEB
Inicio
Editora de código
Iniciar sesión
Pro
Español
English
Français
Español
Português
Deutsch
Italiano
हिंदी
Iconos sociales con CSS
5097
codex
Abrir en el editor
Publica tu código
Recomendado
15 July 2025
Animación de alternancia de triángulos CSS
22 August 2025
Formulario de inicio de sesión y registro con autenticación biométrica
17 May 2025
Tarjeta moderna con giro
HTML
Copy
Webleb
CSS
Copy
* { box-sizing: border-box; margin: 0; padding: 0; } body { width: 100%; height: 100vh; display: flex; justify-content: center; align-items: center; overflow: hidden; background: #121212; cursor: none; } .cursor { width: var(--size); height: var(--size); border-radius: 50%; position: absolute; left: 0; top: 0; pointer-events: none; z-index: 100; } .cursor--large { --size: 40px; border: 1px solid #423cff; } .cursor--small { --size: 10px; background: #423cff; transform: translate(-50%, -50%); } main { display: flex; flex-wrap: wrap; justify-content: center; } main button { --size: 60px; border: none; min-width: var(--size); min-height: var(--size); display: flex; justify-content: center; align-items: center; font-size: 1.2rem; background: rgba(255, 255, 255, 0.08); color: #fff; transition: background 200ms ease, color 200ms ease; cursor: none; } main:hover button { background: rgba(255, 255, 255, 0.04); color: rgba(255, 255, 255, 0.04); } main:hover button:hover { color: #fff; }
JS
Copy
console.clear(); const { gsap } = window; const cursorOuter = document.querySelector(".cursor--large"); const cursorInner = document.querySelector(".cursor--small"); let isStuck = false; let mouse = { x: -100, y: -100, }; // Just in case you need to scroll let scrollHeight = 0; window.addEventListener('scroll', function(e) { scrollHeight = window.scrollY }) let cursorOuterOriginalState = { width: cursorOuter.getBoundingClientRect().width, height: cursorOuter.getBoundingClientRect().height, }; const buttons = document.querySelectorAll("main button"); buttons.forEach((button) => { button.addEventListener("pointerenter", handleMouseEnter); button.addEventListener("pointerleave", handleMouseLeave); }); document.body.addEventListener("pointermove", updateCursorPosition); document.body.addEventListener("pointerdown", () => { gsap.to(cursorInner, 0.15, { scale: 2, }); }); document.body.addEventListener("pointerup", () => { gsap.to(cursorInner, 0.15, { scale: 1, }); }); function updateCursorPosition(e) { mouse.x = e.pageX; mouse.y = e.pageY; } function updateCursor() { gsap.set(cursorInner, { x: mouse.x, y: mouse.y, }); if (!isStuck) { gsap.to(cursorOuter, { duration: 0.15, x: mouse.x - cursorOuterOriginalState.width/2, y: mouse.y - cursorOuterOriginalState.height/2, }); } requestAnimationFrame(updateCursor); } updateCursor(); function handleMouseEnter(e) { isStuck = true; const targetBox = e.currentTarget.getBoundingClientRect(); gsap.to(cursorOuter, 0.2, { x: targetBox.left, y: targetBox.top + scrollHeight, width: targetBox.width, height: targetBox.width, borderRadius: 0, backgroundColor: "rgba(255, 255, 255, 0.1)", }); } function handleMouseLeave(e) { isStuck = false; gsap.to(cursorOuter, 0.2, { width: cursorOuterOriginalState.width, height: cursorOuterOriginalState.width, borderRadius: "50%", backgroundColor: "transparent", }); }