const mainTag = document.querySelector("main") const bodyTag = document.querySelector("body") const cursorTag = document.querySelector("div.cursor") const cursorInnerTag = document.querySelector("div.cursor-inner") const captions = document.querySelectorAll("figcaption") const motion = window.matchMedia('(prefers-reduced-motion: no-preference)') const large = window.matchMedia('(min-width: 600px)') const observer = new IntersectionObserver(entries => { entries.forEach(entry => { if (entry.intersectionRatio > 0.5) { entry.target.classList.add("in-view") } }) }, { threshold: [0, 0.1, 0.5, 1] }) if (motion.matches && large.matches) { // styling with JS so we can scroll with JS turned off mainTag.style.position = "fixed" mainTag.style.top = 0 mainTag.style.left = 0 mainTag.style.width = "100%" // where are we, vs where we wanna be let currentScroll = 0 let aimScroll = 0 let currentCursorX = 0 let currentCursorInnerX = 0 let aimCursorX = 0 let currentCursorY = 0 let currentCursorInnerY = 0 let aimCursorY = 0 captions.forEach(caption => { observer.observe(caption) }) // make a bit of code that'll run every frame const changeScroll = function () { // we need to make the whole page the same height as this too so we can scroll down to the same distance bodyTag.style.height = mainTag.offsetHeight + "px" // is there any diff between aim and current? // if so, tween towards the aim // 0.05 is how quickly/slowly to aim currentScroll += (aimScroll - currentScroll) * 0.1 // then move the whole 'page', actually, the main tag, for this current scroll position // minus we we're moving the main Tag up as we scroll down // mainTag.style.top = (-1 * currentScroll) + "px" mainTag.style.transform = `translate(0, ${-1 * currentScroll}px)` document.querySelectorAll("figcaption").forEach(caption => { const box = caption.getBoundingClientRect() const midY = box.y + box.height / 2 const midScreen = window.innerHeight / 2 const diff = midY - midScreen const images = caption.querySelectorAll("img") images.forEach((image, index) => { const speed = 0.05 * index image.style.transform = `translate(0, ${diff * speed}px)` }) }) // run this every 'frame' requestAnimationFrame(changeScroll) } const changeCursor = function () { currentCursorX += (aimCursorX - currentCursorX) * 0.1 currentCursorY += (aimCursorY - currentCursorY) * 0.1 currentCursorInnerX += (aimCursorX - currentCursorInnerX) * 0.15 currentCursorInnerY += (aimCursorY - currentCursorInnerY) * 0.15 cursorTag.style.left = currentCursorX + "px" cursorTag.style.top = currentCursorY + "px" cursorInnerTag.style.left = currentCursorInnerX + "px" cursorInnerTag.style.top = currentCursorInnerY + "px" requestAnimationFrame(changeCursor) } // when we scroll, update the aim window.addEventListener("scroll", function () { aimScroll = window.pageYOffset }) document.addEventListener("mousemove", function (event) { aimCursorX = event.pageX aimCursorY = event.pageY }) const links = document.querySelectorAll("a") links.forEach(link => { link.addEventListener("mouseenter", function () { bodyTag.classList.add("hovering") }) link.addEventListener("mouseleave", function () { bodyTag.classList.remove("hovering") }) }) changeScroll() changeCursor() }