release: 5.0.4 — VOD-Hover: CSS geometry raus, JS allein authoritativ
Probleme der 5.0.3: - CSS .vod-storyboard-preview hatte noch aspect-ratio:16/9, top:0, left:0, right:0 - JS hat dann inset:0 + aspect-ratio:auto inline gesetzt - Im Electron-28-Chromium kam ein Layout-Konflikt raus -> Overlay-Box- Dimensions wichen von Host ab -> backgroundSize-Skalierung passte nicht zu visible-area -> mehrere Cells gleichzeitig sichtbar (Sprite-Sheet- Look statt Single-Cell-Preview) Fix 5.0.4: - CSS-Klasse hat NUR noch Visual+Stacking (opacity, transition, border- radius, overflow:hidden, z-index, position:absolute, pointer-events) - KEIN top/left/right/bottom/width/height/aspect-ratio im CSS - JS setzt alles inline und voll explicit: top=0, left=0, width=Xpx, height=Ypx aus hostRect (.vod-thumb-wrap) - Sanity-Guards fuer width/height<=0 und cellWidth/cellHeight<=0 - scaleX und scaleY weiter unabhaengig fuer korrekte Cell-Box-Fuellung Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
a5a1d8c067
commit
261aaa362e
4
package-lock.json
generated
4
package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "twitch-vod-manager",
|
"name": "twitch-vod-manager",
|
||||||
"version": "5.0.3",
|
"version": "5.0.4",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "twitch-vod-manager",
|
"name": "twitch-vod-manager",
|
||||||
"version": "5.0.3",
|
"version": "5.0.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^1.6.0",
|
"axios": "^1.6.0",
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "twitch-vod-manager",
|
"name": "twitch-vod-manager",
|
||||||
"version": "5.0.3",
|
"version": "5.0.4",
|
||||||
"description": "Twitch VOD Manager - Download Twitch VODs easily",
|
"description": "Twitch VOD Manager - Download Twitch VODs easily",
|
||||||
"main": "dist/main.js",
|
"main": "dist/main.js",
|
||||||
"author": "xRangerDE",
|
"author": "xRangerDE",
|
||||||
|
|||||||
@ -125,36 +125,31 @@ async function activateHoverPreview(card: HTMLElement, vodId: string): Promise<v
|
|||||||
const overlay = document.createElement('div');
|
const overlay = document.createElement('div');
|
||||||
overlay.className = 'vod-storyboard-preview';
|
overlay.className = 'vod-storyboard-preview';
|
||||||
|
|
||||||
// Anchor an .vod-thumb-wrap statt .vod-card. Das wrap-Element hat
|
// Anchor an .vod-thumb-wrap. Wrap-Element hat exakt Thumbnail-Bounds.
|
||||||
// exakt Thumbnail-Bounds (kein card-border, kein info/actions-Bereich
|
|
||||||
// darunter). Faellt zurueck auf das card selbst falls Markup anders.
|
|
||||||
const anchor = card.querySelector('.vod-thumb-wrap') as HTMLElement | null;
|
const anchor = card.querySelector('.vod-thumb-wrap') as HTMLElement | null;
|
||||||
const host = anchor ?? card;
|
const host = anchor ?? card;
|
||||||
const hostRect = host.getBoundingClientRect();
|
const hostRect = host.getBoundingClientRect();
|
||||||
|
const width = hostRect.width;
|
||||||
|
const height = hostRect.height;
|
||||||
|
|
||||||
// inset: 0 statt explicit width/height — Overlay fuellt garantiert das
|
if (width <= 0 || height <= 0) return;
|
||||||
// gesamte Host-Element. Vermeidet Subpixel-Spalten am oberen oder
|
if (storyboard.cellWidth <= 0 || storyboard.cellHeight <= 0) return;
|
||||||
// unteren Rand wenn JS-measured Dimensions minimal von der CSS-aspect-
|
|
||||||
// ratio-Reserve abweichen.
|
// Position + Size voll inline gesetzt — kein CSS aspect-ratio mehr, das
|
||||||
|
// sich mit JS-Dimensionen streiten koennte (siehe styles.css, die Klasse
|
||||||
|
// gibt nur noch Visual + Stacking, keine Geometrie).
|
||||||
overlay.style.top = '0';
|
overlay.style.top = '0';
|
||||||
overlay.style.right = '0';
|
|
||||||
overlay.style.bottom = '0';
|
|
||||||
overlay.style.left = '0';
|
overlay.style.left = '0';
|
||||||
overlay.style.width = 'auto';
|
overlay.style.width = `${width}px`;
|
||||||
overlay.style.height = 'auto';
|
overlay.style.height = `${height}px`;
|
||||||
// CSS hat noch aspect-ratio: 16/9 als Legacy-Fallback — wir setzen
|
|
||||||
// hier explizit auto, sodass inset:0 die Box-Groesse bestimmt.
|
|
||||||
overlay.style.aspectRatio = 'auto';
|
|
||||||
|
|
||||||
// Skaliere X und Y unabhaengig, damit eine Cell die Overlay-Box exakt
|
// Skaliere X und Y unabhaengig, damit eine Cell die Overlay-Box exakt
|
||||||
// fuellt — egal ob Twitch-Cell-Aspect (z.B. 320x180) gleich Thumbnail-
|
// fuellt — Twitch-Cell-Aspect kann von 16:9 minimal abweichen.
|
||||||
// Aspect (CSS 16/9) ist oder leicht abweicht.
|
const scaleX = width / storyboard.cellWidth;
|
||||||
const scaleX = hostRect.width / storyboard.cellWidth;
|
const scaleY = height / storyboard.cellHeight;
|
||||||
const scaleY = hostRect.height / storyboard.cellHeight;
|
|
||||||
overlay.style.backgroundImage = `url("${storyboard.spriteDataUrl.replace(/"/g, '%22')}")`;
|
overlay.style.backgroundImage = `url("${storyboard.spriteDataUrl.replace(/"/g, '%22')}")`;
|
||||||
overlay.style.backgroundSize = `${storyboard.cols * storyboard.cellWidth * scaleX}px ${storyboard.rows * storyboard.cellHeight * scaleY}px`;
|
overlay.style.backgroundSize = `${storyboard.cols * storyboard.cellWidth * scaleX}px ${storyboard.rows * storyboard.cellHeight * scaleY}px`;
|
||||||
overlay.style.backgroundRepeat = 'no-repeat';
|
overlay.style.backgroundRepeat = 'no-repeat';
|
||||||
// Initial position = first chosen cell.
|
|
||||||
const first = cellsToShow[0];
|
const first = cellsToShow[0];
|
||||||
overlay.style.backgroundPosition = `-${first.col * storyboard.cellWidth * scaleX}px -${first.row * storyboard.cellHeight * scaleY}px`;
|
overlay.style.backgroundPosition = `-${first.col * storyboard.cellWidth * scaleX}px -${first.row * storyboard.cellHeight * scaleY}px`;
|
||||||
|
|
||||||
|
|||||||
@ -4497,11 +4497,9 @@ input[type="number"]::-webkit-outer-spin-button {
|
|||||||
thumbnail's bounding box. Width matches the card; aspect-ratio
|
thumbnail's bounding box. Width matches the card; aspect-ratio
|
||||||
16/9 anchors the height to align with the thumbnail. */
|
16/9 anchors the height to align with the thumbnail. */
|
||||||
.vod-storyboard-preview {
|
.vod-storyboard-preview {
|
||||||
|
/* Position + size werden vollstaendig per JS gesetzt (siehe
|
||||||
|
renderer-vod-hover.ts). Wir geben hier nur Visual + Stacking. */
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
aspect-ratio: 16/9;
|
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: opacity 0.22s ease-out;
|
transition: opacity 0.22s ease-out;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user