refactor: extract PipImage component from inline PiP markup

Deduplicates mobile PiP image code shared between the rosary page and
StickyImage. Adds fullscreen support to StickyImage and fixes hidden PiP
elements capturing pointer events via pointer-events: none default.
This commit is contained in:
2026-02-10 21:15:50 +01:00
parent 6eaf0bb4f4
commit b3c3f34e50
4 changed files with 141 additions and 175 deletions

View File

@@ -2,6 +2,7 @@
import { onMount, tick } from "svelte";
import { createLanguageContext } from "$lib/contexts/languageContext.js";
import { createPip } from "$lib/js/pip.svelte";
import PipImage from "$lib/components/PipImage.svelte";
import "$lib/css/christ.css";
import "$lib/css/action_button.css";
import Kreuzzeichen from "$lib/components/prayers/Kreuzzeichen.svelte";
@@ -1462,86 +1463,6 @@ h1 {
}
}
/* Mobile PiP for mystery images */
.mystery-pip {
position: fixed;
top: 0;
left: 0;
z-index: 10000;
opacity: 0;
touch-action: none;
cursor: grab;
user-select: none;
transition: opacity 0.25s ease;
}
.mystery-pip:active {
cursor: grabbing;
}
.mystery-pip img {
height: 25vh;
width: auto;
object-fit: contain;
border-radius: 6px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
pointer-events: none;
transition: height 0.25s ease;
}
.mystery-pip.enlarged img {
height: 37.5vh;
}
.mystery-pip.fullscreen {
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.95);
display: flex;
align-items: center;
justify-content: center;
cursor: default;
}
.mystery-pip.fullscreen img {
border-radius: 0;
box-shadow: none;
}
.pip-fullscreen-btn {
all: unset;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: transparent;
filter: drop-shadow(0 0 1px black);
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
padding: 0;
z-index: 1;
pointer-events: auto;
outline: none;
transition: transform 0.15s ease;
}
.pip-fullscreen-btn:hover,
.pip-fullscreen-btn:active {
transform: translate(-50%, -50%) scale(1.2);
}
.mystery-pip.fullscreen .pip-fullscreen-btn {
top: auto;
left: auto;
bottom: 10vw;
right: 10vw;
transform: none;
}
.mystery-pip.fullscreen .pip-fullscreen-btn:hover,
.mystery-pip.fullscreen .pip-fullscreen-btn:active {
transform: scale(0.85);
}
@media (min-width: 1200px) {
.mystery-pip {
display: none;
}
}
</style>
<svelte:head>
<title>{labels.pageTitle}</title>
@@ -1957,35 +1878,7 @@ h1 {
<!-- Mobile PiP for mystery images -->
{#if hasMysteryImages}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<div
class="mystery-pip"
class:visible={!!mysteryPipSrc}
class:enlarged={pip.enlarged}
class:fullscreen={pip.fullscreen}
bind:this={rosaryPipEl}
onpointerdown={pip.onpointerdown}
onpointermove={pip.onpointermove}
onpointerup={pip.onpointerup}
>
{#if lastPipSrc}
<img src={lastPipSrc} alt="" onload={() => pip.reposition()}>
{/if}
{#if pip.showControls}
<button
class="pip-fullscreen-btn"
onpointerdown={(e) => e.stopPropagation()}
onclick={(e) => { e.stopPropagation(); pip.toggleFullscreen(); }}
>
<svg viewBox="0 0 24 24" width="28" height="28" fill="none" stroke="white" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
<polyline points="8 3 3 3 3 8"/>
<polyline points="16 3 21 3 21 8"/>
<polyline points="8 21 3 21 3 16"/>
<polyline points="16 21 21 21 21 16"/>
</svg>
</button>
{/if}
</div>
<PipImage {pip} src={lastPipSrc} visible={!!mysteryPipSrc} onload={() => pip.reposition()} bind:el={rosaryPipEl} />
{/if}
</div>