Track while scrolling

This commit is contained in:
Justin Edmund 2025-06-13 07:53:22 -04:00
parent fcf5f87177
commit 824e44a1ef
3 changed files with 122 additions and 42 deletions

View file

@ -138,10 +138,10 @@
// Check if mouse is in hover zones
if (x < imageRect.left) {
isHoveringLeft = true
leftButtonCoords.set({ x: mouseX, y: mouseY })
leftButtonCoords.set({ x: mouseX, y: mouseY }, { hard: true })
} else if (x > imageRect.right) {
isHoveringRight = true
rightButtonCoords.set({ x: mouseX, y: mouseY })
rightButtonCoords.set({ x: mouseX, y: mouseY }, { hard: true })
}
// Remove the listener
@ -157,16 +157,47 @@
const mouseX = currentPos.x - pageRect.left
const mouseY = currentPos.y - pageRect.top
// Store client coordinates for scroll updates
lastClientX = currentPos.x
lastClientY = currentPos.y
// Check if mouse is in hover zones
if (x < imageRect.left) {
isHoveringLeft = true
leftButtonCoords.set({ x: mouseX, y: mouseY })
leftButtonCoords.set({ x: mouseX, y: mouseY }, { hard: true })
} else if (x > imageRect.right) {
isHoveringRight = true
rightButtonCoords.set({ x: mouseX, y: mouseY })
rightButtonCoords.set({ x: mouseX, y: mouseY }, { hard: true })
}
}
// Store last mouse client position for scroll updates
let lastClientX = 0
let lastClientY = 0
// Update button positions during scroll
function handleScroll() {
if (!isHoveringLeft && !isHoveringRight) return
const pageContainer = document.querySelector('.photo-page') as HTMLElement
if (!pageContainer) return
// Use last known mouse position (which is viewport-relative)
// and recalculate relative to the page container's new position
const pageRect = pageContainer.getBoundingClientRect()
const mouseX = lastClientX - pageRect.left
const mouseY = lastClientY - pageRect.top
// Update button positions
if (isHoveringLeft) {
leftButtonCoords.set({ x: mouseX, y: mouseY })
}
if (isHoveringRight) {
rightButtonCoords.set({ x: mouseX, y: mouseY })
}
}
// Mouse tracking for hover areas
function handleMouseMove(event: MouseEvent) {
const pageContainer = event.currentTarget as HTMLElement
@ -185,6 +216,10 @@
const mouseX = event.clientX - pageRect.left
const mouseY = event.clientY - pageRect.top
// Store last mouse position for scroll updates
lastClientX = event.clientX
lastClientY = event.clientY
// Check if mouse is in the left or right margin (outside the photo)
const wasHoveringLeft = isHoveringLeft
const wasHoveringRight = isHoveringRight
@ -238,10 +273,15 @@
}
}
// Set up keyboard listener
// Set up keyboard and scroll listeners
$effect(() => {
window.addEventListener('keydown', handleKeydown)
return () => window.removeEventListener('keydown', handleKeydown)
window.addEventListener('scroll', handleScroll)
return () => {
window.removeEventListener('keydown', handleKeydown)
window.removeEventListener('scroll', handleScroll)
}
})
</script>

View file

@ -48,19 +48,19 @@
titleFormat: { type: 'by' }
})
: type === 'photo' && photo
? generateMetaTags({
title: photo.title || 'Photo',
description: photo.description || photo.caption || 'A photograph',
url: pageUrl,
image: photo.url,
titleFormat: { type: 'by' }
})
: generateMetaTags({
title: 'Not Found',
description: 'The content you are looking for could not be found.',
url: pageUrl,
noindex: true
})
? generateMetaTags({
title: photo.title || 'Photo',
description: photo.description || photo.caption || 'A photograph',
url: pageUrl,
image: photo.url,
titleFormat: { type: 'by' }
})
: generateMetaTags({
title: 'Not Found',
description: 'The content you are looking for could not be found.',
url: pageUrl,
noindex: true
})
)
// Generate image gallery JSON-LD
@ -77,15 +77,15 @@
})) || []
})
: type === 'photo' && photo
? {
'@context': 'https://schema.org',
'@type': 'ImageObject',
name: photo.title || 'Photo',
description: photo.description || photo.caption,
contentUrl: photo.url,
url: pageUrl
}
: null
? {
'@context': 'https://schema.org',
'@type': 'ImageObject',
name: photo.title || 'Photo',
description: photo.description || photo.caption,
contentUrl: photo.url,
url: pageUrl
}
: null
)
</script>
@ -157,20 +157,16 @@
<div class="photo-header">
<BackButton href="/photos" label="Back to Photos" />
</div>
<div class="photo-container">
<img
src={photo.url}
alt={photo.title || photo.caption || 'Photo'}
class="photo-image"
/>
<img src={photo.url} alt={photo.title || photo.caption || 'Photo'} class="photo-image" />
</div>
<div class="photo-info">
{#if photo.title}
<h1 class="photo-title">{photo.title}</h1>
{/if}
{#if photo.caption || photo.description}
<p class="photo-description">{photo.caption || photo.description}</p>
{/if}
@ -215,7 +211,7 @@
width: 100%;
max-width: 900px;
margin: 0 auto;
padding: $unit-4x $unit-3x;
padding: 0 $unit-3x;
@include breakpoint('phone') {
padding: $unit-3x $unit-2x;

View file

@ -169,10 +169,10 @@
// Check if mouse is in hover zones
if (x < imageRect.left) {
isHoveringLeft = true
leftButtonCoords.set({ x: mouseX, y: mouseY })
leftButtonCoords.set({ x: mouseX, y: mouseY }, { hard: true })
} else if (x > imageRect.right) {
isHoveringRight = true
rightButtonCoords.set({ x: mouseX, y: mouseY })
rightButtonCoords.set({ x: mouseX, y: mouseY }, { hard: true })
}
// Remove the listener
@ -188,16 +188,51 @@
const mouseX = currentPos.x - pageRect.left
const mouseY = currentPos.y - pageRect.top
// Store client coordinates for scroll updates
lastClientX = currentPos.x
lastClientY = currentPos.y
// Check if mouse is in hover zones
if (x < imageRect.left) {
isHoveringLeft = true
leftButtonCoords.set({ x: mouseX, y: mouseY })
leftButtonCoords.set({ x: mouseX, y: mouseY }, { hard: true })
} else if (x > imageRect.right) {
isHoveringRight = true
rightButtonCoords.set({ x: mouseX, y: mouseY })
rightButtonCoords.set({ x: mouseX, y: mouseY }, { hard: true })
}
}
// Track last known mouse position for scroll updates
let lastMouseX = 0
let lastMouseY = 0
// Store last mouse client position for scroll updates
let lastClientX = 0
let lastClientY = 0
// Update button positions during scroll
function handleScroll() {
if (!isHoveringLeft && !isHoveringRight) return
const pageContainer = document.querySelector('.photo-page') as HTMLElement
if (!pageContainer) return
// Use last known mouse position (which is viewport-relative)
// and recalculate relative to the page container's new position
const pageRect = pageContainer.getBoundingClientRect()
const mouseX = lastClientX - pageRect.left
const mouseY = lastClientY - pageRect.top
// Update button positions
if (isHoveringLeft) {
leftButtonCoords.set({ x: mouseX, y: mouseY })
}
if (isHoveringRight) {
rightButtonCoords.set({ x: mouseX, y: mouseY })
}
}
// Mouse tracking for hover areas
function handleMouseMove(event: MouseEvent) {
const pageContainer = event.currentTarget as HTMLElement
@ -216,6 +251,10 @@
const mouseX = event.clientX - pageRect.left
const mouseY = event.clientY - pageRect.top
// Store last mouse position for scroll updates
lastClientX = event.clientX
lastClientY = event.clientY
// Check if mouse is in the left or right margin (outside the photo)
const wasHoveringLeft = isHoveringLeft
const wasHoveringRight = isHoveringRight
@ -260,10 +299,15 @@
}
}
// Set up keyboard listener
// Set up keyboard and scroll listeners
$effect(() => {
window.addEventListener('keydown', handleKeydown)
return () => window.removeEventListener('keydown', handleKeydown)
window.addEventListener('scroll', handleScroll)
return () => {
window.removeEventListener('keydown', handleKeydown)
window.removeEventListener('scroll', handleScroll)
}
})
</script>