From b7a4b8605a486a57d69877621e4119b592cd0aed Mon Sep 17 00:00:00 2001 From: Javid Date: Sun, 30 Aug 2026 14:34:36 +0200 Subject: [PATCH] feat(identity): add interactive login background --- public/img/identity-topography.webp | Bin 0 -> 14997 bytes src/login/InteractiveBackground.css | 1 + src/login/InteractiveBackground.tsx | 80 ++++++++++++++++++++++++++++ src/login/KcPage.tsx | 4 ++ 4 files changed, 85 insertions(+) create mode 100644 public/img/identity-topography.webp create mode 100644 src/login/InteractiveBackground.css create mode 100644 src/login/InteractiveBackground.tsx diff --git a/public/img/identity-topography.webp b/public/img/identity-topography.webp new file mode 100644 index 0000000000000000000000000000000000000000..86e1426c5a535dd5fc80875f909c4355d8f9dd1b GIT binary patch literal 14997 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 literal 0 HcmV?d00001 diff --git a/src/login/InteractiveBackground.css b/src/login/InteractiveBackground.css new file mode 100644 index 0000000..0df7849 --- /dev/null +++ b/src/login/InteractiveBackground.css @@ -0,0 +1 @@ +.corelink-interactive-background{--pointer-x:50%;--pointer-y:50%;position:fixed;inset:0;z-index:0;overflow:hidden;pointer-events:none;background:#041014}.corelink-interactive-background__image{position:absolute;inset:-3%;background-position:center;background-repeat:no-repeat;background-size:cover;transform:scale(1.035);will-change:transform}.corelink-interactive-background__light{position:absolute;inset:0;background:radial-gradient(circle 320px at var(--pointer-x) var(--pointer-y),rgba(72,220,210,.11),rgba(72,220,210,.035) 36%,transparent 68%);mix-blend-mode:screen}.corelink-interactive-background__shade{position:absolute;inset:0;background:linear-gradient(90deg,rgba(2,11,15,.52),rgba(2,11,15,.24) 45%,rgba(2,11,15,.62)),linear-gradient(180deg,rgba(0,0,0,.08),rgba(0,7,10,.46))}body{background:#041014}body:before{display:none!important}#root{position:relative;isolation:isolate}.corelink-brand-bar,#kc-content,.corelink-auth-footer{z-index:2}#kc-content{position:relative}#kc-content-wrapper{background:linear-gradient(180deg,rgba(8,22,28,.78),rgba(4,15,21,.84));border-color:rgba(120,220,215,.16);box-shadow:0 32px 90px rgba(0,0,0,.42);backdrop-filter:blur(22px) saturate(115%);-webkit-backdrop-filter:blur(22px) saturate(115%)}input[type=text],input[type=email],input[type=password],input[type=tel],input[type=number],select{background:rgba(5,18,24,.82);border-color:rgba(130,190,200,.2)}@media(hover:none),(pointer:coarse){.corelink-interactive-background__image{transform:scale(1.02)!important;will-change:auto}.corelink-interactive-background__light{display:none}}@media(prefers-reduced-motion:reduce){.corelink-interactive-background__image{transform:scale(1.02)!important;will-change:auto}.corelink-interactive-background__light{display:none}} diff --git a/src/login/InteractiveBackground.tsx b/src/login/InteractiveBackground.tsx new file mode 100644 index 0000000..02d5bd1 --- /dev/null +++ b/src/login/InteractiveBackground.tsx @@ -0,0 +1,80 @@ +import { useEffect, useRef } from "react"; + +interface InteractiveBackgroundProps { + imageUrl: string; +} + +export function InteractiveBackground({ imageUrl }: InteractiveBackgroundProps) { + const rootRef = useRef(null); + const imageRef = useRef(null); + + useEffect(() => { + const root = rootRef.current; + const image = imageRef.current; + + if (!root || !image) { + return; + } + + const reducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; + const finePointer = window.matchMedia("(hover: hover) and (pointer: fine)").matches; + + if (reducedMotion || !finePointer) { + return; + } + + let targetX = 0; + let targetY = 0; + let currentX = 0; + let currentY = 0; + let frame = 0; + + const move = (event: PointerEvent) => { + const x = event.clientX / window.innerWidth; + const y = event.clientY / window.innerHeight; + + targetX = (x - 0.5) * -14; + targetY = (y - 0.5) * -10; + + root.style.setProperty("--pointer-x", `${x * 100}%`); + root.style.setProperty("--pointer-y", `${y * 100}%`); + }; + + const leave = () => { + targetX = 0; + targetY = 0; + root.style.setProperty("--pointer-x", "50%"); + root.style.setProperty("--pointer-y", "50%"); + }; + + const animate = () => { + currentX += (targetX - currentX) * 0.055; + currentY += (targetY - currentY) * 0.055; + + image.style.transform = `translate3d(${currentX}px, ${currentY}px, 0) scale(1.035)`; + frame = window.requestAnimationFrame(animate); + }; + + window.addEventListener("pointermove", move, { passive: true }); + window.addEventListener("pointerleave", leave); + frame = window.requestAnimationFrame(animate); + + return () => { + window.removeEventListener("pointermove", move); + window.removeEventListener("pointerleave", leave); + window.cancelAnimationFrame(frame); + }; + }, []); + + return ( +