Revert masonry thumbnail change
This commit is contained in:
parent
d73619aa24
commit
a69f1098de
4 changed files with 291 additions and 7 deletions
270
src/lib/components/PhotoViewEnhanced.svelte
Normal file
270
src/lib/components/PhotoViewEnhanced.svelte
Normal file
|
|
@ -0,0 +1,270 @@
|
|||
<script lang="ts">
|
||||
import Zoom from 'svelte-medium-image-zoom'
|
||||
import 'svelte-medium-image-zoom/dist/styles.css'
|
||||
import { onMount } from 'svelte'
|
||||
|
||||
interface Props {
|
||||
src: string
|
||||
alt?: string
|
||||
title?: string
|
||||
id?: string
|
||||
class?: string
|
||||
width?: number
|
||||
height?: number
|
||||
}
|
||||
|
||||
let {
|
||||
src,
|
||||
alt = '',
|
||||
title,
|
||||
id,
|
||||
class: className = '',
|
||||
width,
|
||||
height
|
||||
}: Props = $props()
|
||||
|
||||
let imageRef = $state<HTMLImageElement>()
|
||||
let isUltrawide = $state(false)
|
||||
let imageLoaded = $state(false)
|
||||
|
||||
// Check if image is ultrawide (aspect ratio > 2:1)
|
||||
function checkIfUltrawide() {
|
||||
if (width && height) {
|
||||
isUltrawide = width / height > 2
|
||||
console.log('Ultrawide check from props:', { width, height, ratio: width / height, isUltrawide })
|
||||
} else if (imageRef && imageLoaded) {
|
||||
isUltrawide = imageRef.naturalWidth / imageRef.naturalHeight > 2
|
||||
console.log('Ultrawide check from image:', {
|
||||
naturalWidth: imageRef.naturalWidth,
|
||||
naturalHeight: imageRef.naturalHeight,
|
||||
ratio: imageRef.naturalWidth / imageRef.naturalHeight,
|
||||
isUltrawide
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Update scroll indicators based on scroll position
|
||||
function updateScrollIndicators(modal: HTMLElement) {
|
||||
const isAtStart = modal.scrollLeft <= 0
|
||||
const isAtEnd = modal.scrollLeft >= modal.scrollWidth - modal.clientWidth - 1
|
||||
|
||||
if (isAtStart) {
|
||||
modal.setAttribute('data-at-start', '')
|
||||
} else {
|
||||
modal.removeAttribute('data-at-start')
|
||||
}
|
||||
|
||||
if (isAtEnd) {
|
||||
modal.setAttribute('data-at-end', '')
|
||||
} else {
|
||||
modal.removeAttribute('data-at-end')
|
||||
}
|
||||
}
|
||||
|
||||
// Enhance zoom behavior for ultrawide images
|
||||
function enhanceZoomForUltrawide() {
|
||||
if (!isUltrawide) return
|
||||
|
||||
console.log('Setting up ultrawide zoom enhancement')
|
||||
|
||||
// Wait for zoom to be activated
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
mutations.forEach((mutation) => {
|
||||
if (mutation.type === 'childList') {
|
||||
// Check for zoom overlay - try multiple selectors
|
||||
const zoomOverlay = document.querySelector('[data-smiz-overlay]') ||
|
||||
document.querySelector('.medium-image-zoom-overlay') ||
|
||||
document.querySelector('[data-rmiz-modal-overlay]')
|
||||
const zoomedImage = document.querySelector('[data-smiz-modal] img') ||
|
||||
document.querySelector('.medium-image-zoom-image') ||
|
||||
document.querySelector('[data-rmiz-modal-img]') as HTMLImageElement
|
||||
|
||||
console.log('Checking for zoom elements:', {
|
||||
zoomOverlay: !!zoomOverlay,
|
||||
zoomedImage: !!zoomedImage,
|
||||
allDivs: document.querySelectorAll('div').length,
|
||||
bodyChildren: document.body.children.length
|
||||
})
|
||||
|
||||
// Also check for any new elements with specific classes
|
||||
const allNewElements = mutation.addedNodes
|
||||
allNewElements.forEach(node => {
|
||||
if (node.nodeType === 1) { // Element node
|
||||
const element = node as HTMLElement
|
||||
console.log('New element added:', element.tagName, element.className, element.getAttribute('data-rmiz-modal-overlay'))
|
||||
}
|
||||
})
|
||||
|
||||
if (zoomOverlay && zoomedImage) {
|
||||
console.log('Zoom activated, applying ultrawide enhancements')
|
||||
// Add custom class for ultrawide handling
|
||||
zoomOverlay.classList.add('ultrawide-zoom')
|
||||
|
||||
// Make the zoomed image scrollable horizontally
|
||||
const modal = zoomedImage.closest('[data-smiz-modal]') as HTMLElement
|
||||
if (modal) {
|
||||
modal.style.overflow = 'auto'
|
||||
modal.style.maxHeight = '90vh'
|
||||
|
||||
// Adjust image height to fill more vertical space for ultrawide
|
||||
zoomedImage.style.maxHeight = '85vh'
|
||||
zoomedImage.style.height = 'auto'
|
||||
zoomedImage.style.width = 'auto'
|
||||
zoomedImage.style.maxWidth = 'none'
|
||||
|
||||
// Center the scroll position initially
|
||||
setTimeout(() => {
|
||||
const scrollLeft = (modal.scrollWidth - modal.clientWidth) / 2
|
||||
modal.scrollLeft = scrollLeft
|
||||
updateScrollIndicators(modal)
|
||||
}, 50)
|
||||
|
||||
// Add scroll listener to update indicators
|
||||
modal.addEventListener('scroll', () => updateScrollIndicators(modal))
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
})
|
||||
|
||||
// Clean up observer when component unmounts
|
||||
return () => observer.disconnect()
|
||||
}
|
||||
|
||||
$effect(() => {
|
||||
checkIfUltrawide()
|
||||
})
|
||||
|
||||
$effect(() => {
|
||||
if (isUltrawide && imageLoaded) {
|
||||
const cleanup = enhanceZoomForUltrawide()
|
||||
return cleanup
|
||||
}
|
||||
})
|
||||
|
||||
function handleImageLoad() {
|
||||
imageLoaded = true
|
||||
checkIfUltrawide()
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="photo-view {className}" class:ultrawide={isUltrawide}>
|
||||
{#key id || src}
|
||||
<Zoom>
|
||||
<img
|
||||
bind:this={imageRef}
|
||||
{src}
|
||||
alt={title || alt || 'Photo'}
|
||||
class="photo-image"
|
||||
onload={handleImageLoad}
|
||||
/>
|
||||
</Zoom>
|
||||
{/key}
|
||||
</div>
|
||||
|
||||
<style lang="scss">
|
||||
@import '$styles/variables.scss';
|
||||
@import '$styles/mixins.scss';
|
||||
|
||||
.photo-view {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.photo-image {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
max-width: 700px;
|
||||
object-fit: contain;
|
||||
border-radius: $image-corner-radius;
|
||||
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
|
||||
|
||||
@include breakpoint('phone') {
|
||||
border-radius: $image-corner-radius;
|
||||
}
|
||||
}
|
||||
|
||||
// Hide the zoom library's close button
|
||||
:global([data-smiz-btn-unzoom]) {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
// Ultrawide zoom enhancements
|
||||
:global(.ultrawide-zoom) {
|
||||
:global([data-smiz-modal]) {
|
||||
cursor: grab;
|
||||
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
}
|
||||
|
||||
// Add subtle scroll indicators
|
||||
&::before,
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 40px;
|
||||
height: 100px;
|
||||
pointer-events: none;
|
||||
z-index: 10;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
&::before {
|
||||
left: 0;
|
||||
background: linear-gradient(to right, rgba(0, 0, 0, 0.3), transparent);
|
||||
border-radius: 0 $unit-2x $unit-2x 0;
|
||||
}
|
||||
|
||||
&::after {
|
||||
right: 0;
|
||||
background: linear-gradient(to left, rgba(0, 0, 0, 0.3), transparent);
|
||||
border-radius: $unit-2x 0 0 $unit-2x;
|
||||
}
|
||||
|
||||
// Hide indicators when scrolled to edges
|
||||
&[data-at-start]::before {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&[data-at-end]::after {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Scrollbar styling for ultrawide images
|
||||
:global([data-smiz-modal]) {
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: rgba(255, 255, 255, 0.3) transparent;
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
border-radius: 4px;
|
||||
|
||||
&:hover {
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -112,7 +112,7 @@ export const GET: RequestHandler = async (event) => {
|
|||
description: album.description || undefined,
|
||||
coverPhoto: {
|
||||
id: `cover-${firstMedia.id}`,
|
||||
src: firstMedia.thumbnailUrl || firstMedia.url,
|
||||
src: firstMedia.url,
|
||||
alt: firstMedia.photoCaption || album.title,
|
||||
caption: firstMedia.photoCaption || undefined,
|
||||
width: firstMedia.width || 400,
|
||||
|
|
@ -120,7 +120,7 @@ export const GET: RequestHandler = async (event) => {
|
|||
},
|
||||
photos: album.media.map((albumMedia) => ({
|
||||
id: `media-${albumMedia.media.id}`,
|
||||
src: albumMedia.media.thumbnailUrl || albumMedia.media.url,
|
||||
src: albumMedia.media.url,
|
||||
alt: albumMedia.media.photoCaption || albumMedia.media.filename,
|
||||
caption: albumMedia.media.photoCaption || undefined,
|
||||
width: albumMedia.media.width || 400,
|
||||
|
|
@ -137,7 +137,7 @@ export const GET: RequestHandler = async (event) => {
|
|||
|
||||
return {
|
||||
id: `media-${media.id}`,
|
||||
src: media.thumbnailUrl || media.url,
|
||||
src: media.url,
|
||||
alt: media.photoTitle || media.photoCaption || media.filename,
|
||||
caption: media.photoCaption || undefined,
|
||||
width: media.width || 400,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import BackButton from '$components/BackButton.svelte'
|
||||
import PhotoView from '$components/PhotoView.svelte'
|
||||
import PhotoViewEnhanced from '$components/PhotoViewEnhanced.svelte'
|
||||
import PhotoMetadata from '$components/PhotoMetadata.svelte'
|
||||
import { generateMetaTags, generateCreativeWorkJsonLd } from '$lib/utils/metadata'
|
||||
import { page } from '$app/stores'
|
||||
|
|
@ -333,7 +333,14 @@
|
|||
{:else}
|
||||
<div class="photo-page" onmousemove={handleMouseMove} onmouseleave={handleMouseLeave}>
|
||||
<div class="photo-content-wrapper">
|
||||
<PhotoView src={photo.url} alt={photo.caption} title={photo.title} id={photo.id} />
|
||||
<PhotoViewEnhanced
|
||||
src={photo.url}
|
||||
alt={photo.caption}
|
||||
title={photo.title}
|
||||
id={photo.id}
|
||||
width={photo.width}
|
||||
height={photo.height}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Adjacent Photos Navigation -->
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import BackButton from '$components/BackButton.svelte'
|
||||
import PhotoView from '$components/PhotoView.svelte'
|
||||
import PhotoViewEnhanced from '$components/PhotoViewEnhanced.svelte'
|
||||
import PhotoMetadata from '$components/PhotoMetadata.svelte'
|
||||
import { generateMetaTags } from '$lib/utils/metadata'
|
||||
import { page } from '$app/stores'
|
||||
|
|
@ -355,7 +355,14 @@
|
|||
{:else if photo}
|
||||
<div class="photo-page" onmousemove={handleMouseMove} onmouseleave={handleMouseLeave}>
|
||||
<div class="photo-content-wrapper">
|
||||
<PhotoView src={photo.url} alt={photo.caption} title={photo.title} id={photo.id} />
|
||||
<PhotoViewEnhanced
|
||||
src={photo.url}
|
||||
alt={photo.caption}
|
||||
title={photo.title}
|
||||
id={photo.id}
|
||||
width={photo.width}
|
||||
height={photo.height}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Adjacent Photos Navigation -->
|
||||
|
|
|
|||
Loading…
Reference in a new issue