fix(imagePreview): duplicate & stuttering error (#62)

* add max media size on start preview

* fix fileinfo display so it wont show until the media loads, fix mouseonly timer and chking for current previews onscreen before trying to make another one. fixed positioning based on left and right side available space, fixed mouse hovering over the info making it freak out in mouse only mode, fixed style so its actually centered :p

* removed restraints on zoomlevel, removed spaces in code
This commit is contained in:
Creation's 2024-10-18 10:56:35 -04:00 committed by GitHub
parent 0d466d3ec7
commit 9a8678310c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 49 additions and 44 deletions

View file

@ -29,17 +29,23 @@ let lastMouseEvent: MouseEvent | null = null;
let observer: MutationObserver | null = null; let observer: MutationObserver | null = null;
function deleteCurrentPreview() { function deleteCurrentPreview() {
if (!currentPreview || !currentPreviewFile || !currentPreviewFileSize || !currentPreviewType || !loadingSpinner) return; if (!currentPreview) return;
currentPreview.remove(); currentPreview.remove();
loadingSpinner = null;
lastMouseEvent = null; lastMouseEvent = null;
currentPreview = null; currentPreview = null;
currentPreviewFile = null; currentPreviewFile = null;
currentPreviewFileSize = null; currentPreviewFileSize = null;
currentPreviewType = null; currentPreviewType = null;
lastMouseEvent = null; lastMouseEvent = null;
loadingSpinner = null; isDragging = false;
shouldKeepPreviewOpen = false;
if (loadingSpinner) {
loadingSpinner.remove();
loadingSpinner = null;
}
zoomLevel = 1; zoomLevel = 1;
} }
@ -163,6 +169,10 @@ function loadImagePreview(url: string) {
mimeTypeSpan.textContent = mimeType; mimeTypeSpan.textContent = mimeType;
fileInfo.appendChild(mimeTypeSpan);
fileInfo.appendChild(fileName);
fileInfo.appendChild(fileSize);
if (currentPreviewType === "video") { if (currentPreviewType === "video") {
const video = document.createElement("video"); const video = document.createElement("video");
video.src = url; video.src = url;
@ -170,7 +180,6 @@ function loadImagePreview(url: string) {
video.autoplay = true; video.autoplay = true;
video.muted = true; video.muted = true;
video.loop = true; video.loop = true;
video.style.pointerEvents = "none";
video.onplay = () => { video.onplay = () => {
video.removeAttribute("controls"); video.removeAttribute("controls");
@ -188,6 +197,8 @@ function loadImagePreview(url: string) {
showingSize.textContent = showingMediaSize ? `(${showingMediaSize[0]}x${showingMediaSize[1]})` : ""; showingSize.textContent = showingMediaSize ? `(${showingMediaSize[0]}x${showingMediaSize[1]})` : "";
fileSize.appendChild(showingSize); fileSize.appendChild(showingSize);
} }
preview.appendChild(fileInfo);
}); });
if (loadingSpinner) loadingSpinner.remove(); if (loadingSpinner) loadingSpinner.remove();
@ -216,6 +227,8 @@ function loadImagePreview(url: string) {
showingSize.textContent = showingMediaSize ? `(${showingMediaSize[0]}x${showingMediaSize[1]})` : ""; showingSize.textContent = showingMediaSize ? `(${showingMediaSize[0]}x${showingMediaSize[1]})` : "";
fileSize.appendChild(showingSize); fileSize.appendChild(showingSize);
} }
preview.appendChild(fileInfo);
}); });
if (loadingSpinner) loadingSpinner.remove(); if (loadingSpinner) loadingSpinner.remove();
@ -228,11 +241,6 @@ function loadImagePreview(url: string) {
currentPreviewFile = img; currentPreviewFile = img;
} }
fileInfo.appendChild(mimeTypeSpan);
fileInfo.appendChild(fileName);
fileInfo.appendChild(fileSize);
preview.appendChild(fileInfo);
if (settings.store.mouseOnlyMode) { if (settings.store.mouseOnlyMode) {
currentPreviewFile.addEventListener("mouseover", () => { currentPreviewFile.addEventListener("mouseover", () => {
if (currentPreview && !isCtrlHeld) { if (currentPreview && !isCtrlHeld) {
@ -257,16 +265,11 @@ function loadImagePreview(url: string) {
zoomLevel += event.deltaY * -zoomSpeed * zoomFactor; zoomLevel += event.deltaY * -zoomSpeed * zoomFactor;
zoomLevel = Math.min(Math.max(zoomLevel, 0.5), 10);
const previewMedia = currentPreviewFile as HTMLImageElement | HTMLVideoElement | null; const previewMedia = currentPreviewFile as HTMLImageElement | HTMLVideoElement | null;
if (previewMedia) { if (previewMedia) {
const rect = previewMedia.getBoundingClientRect(); const rect = previewMedia.getBoundingClientRect();
let offsetX = (event.clientX - rect.left) / rect.width; const offsetX = (event.clientX - rect.left) / rect.width;
let offsetY = (event.clientY - rect.top) / rect.height; const offsetY = (event.clientY - rect.top) / rect.height;
offsetX = Math.min(Math.max(offsetX, 0.1), 0.9);
offsetY = Math.min(Math.max(offsetY, 0.1), 0.9);
previewMedia.style.transformOrigin = `${offsetX * 100}% ${offsetY * 100}%`; previewMedia.style.transformOrigin = `${offsetX * 100}% ${offsetY * 100}%`;
previewMedia.style.transform = `scale(${zoomLevel})`; previewMedia.style.transform = `scale(${zoomLevel})`;
@ -274,7 +277,6 @@ function loadImagePreview(url: string) {
} }
}); });
currentPreview.addEventListener("mousedown", (event: MouseEvent) => { currentPreview.addEventListener("mousedown", (event: MouseEvent) => {
if ((isCtrlHeld || shouldKeepPreviewOpen) && currentPreview) { if ((isCtrlHeld || shouldKeepPreviewOpen) && currentPreview) {
isDragging = true; isDragging = true;
@ -290,31 +292,36 @@ function loadImagePreview(url: string) {
function updatePreviewPosition(mouseEvent: MouseEvent, element: HTMLElement) { function updatePreviewPosition(mouseEvent: MouseEvent, element: HTMLElement) {
if (currentPreview && !isCtrlHeld) { if (currentPreview && !isCtrlHeld) {
const padding = 15; const basePadding = 15;
const maxWidth = window.innerWidth * 0.9; const topPadding = 40;
const maxHeight = window.innerHeight * 0.9; const maxWidth: number = window.innerWidth * 0.9;
const maxHeight: number = window.innerHeight * 0.9;
const previewWidth = currentPreview.offsetWidth; const previewWidth: number = currentPreview.offsetWidth;
const previewHeight = currentPreview.offsetHeight; const previewHeight: number = currentPreview.offsetHeight;
let left = mouseEvent.pageX + padding; let left: number;
let top = mouseEvent.pageY + padding; let top: number = mouseEvent.pageY + basePadding;
if (left + previewWidth > window.innerWidth) { const spaceOnRight = window.innerWidth - mouseEvent.pageX - previewWidth - basePadding;
left = mouseEvent.pageX - previewWidth - padding; const spaceOnLeft = mouseEvent.pageX - previewWidth - basePadding;
if (left < padding) {
left = window.innerWidth - previewWidth - padding; if (spaceOnRight >= basePadding) {
} left = mouseEvent.pageX + basePadding;
} else if (spaceOnLeft >= basePadding) {
left = mouseEvent.pageX - previewWidth - basePadding;
} else {
left = Math.max(basePadding, Math.min(mouseEvent.pageX + basePadding, window.innerWidth - previewWidth - basePadding));
} }
if (top + previewHeight > window.innerHeight) { if (top + previewHeight > window.innerHeight) {
top = mouseEvent.pageY - previewHeight - padding; top = mouseEvent.pageY - previewHeight - topPadding;
if (top < padding) { if (top < topPadding) {
top = window.innerHeight - previewHeight - padding * 2; top = window.innerHeight - previewHeight - topPadding * 2;
} }
} else { } else {
top = Math.min(top, window.innerHeight - previewHeight - padding * 2); top = Math.min(top, window.innerHeight - previewHeight - basePadding * 2);
} }
currentPreview.style.left = `${left}px`; currentPreview.style.left = `${left}px`;
@ -332,20 +339,15 @@ function addHoverListener(element: Element) {
element.setAttribute("data-processed", "true"); element.setAttribute("data-processed", "true");
element.addEventListener("mouseover", event => { element.addEventListener("mouseover", event => {
if (isCtrlHeld && currentPreview) return;
if (currentPreview || loadingSpinner) { if (currentPreview || loadingSpinner) {
if (isCtrlHeld) return;
deleteCurrentPreview(); deleteCurrentPreview();
if (shouldKeepPreviewOpenTimeout) {
clearTimeout(shouldKeepPreviewOpenTimeout);
shouldKeepPreviewOpenTimeout = null;
}
} }
if (hoverDelayTimeout) { if (shouldKeepPreviewOpenTimeout) {
clearTimeout(hoverDelayTimeout); clearTimeout(shouldKeepPreviewOpenTimeout);
hoverDelayTimeout = null; shouldKeepPreviewOpenTimeout = null;
} }
const mouseEvent = event as MouseEvent; const mouseEvent = event as MouseEvent;

View file

@ -36,11 +36,14 @@
padding: 2px 5px; padding: 2px 5px;
border-radius: 4px; border-radius: 4px;
font-size: 12px; font-size: 12px;
margin: 0 5px;
box-shadow: 0 0 0 1px var(--background-secondary); box-shadow: 0 0 0 1px var(--background-secondary);
border: 1px solid var(--background-secondary); border: 1px solid var(--background-secondary);
} }
.image-preview .file-info span:last-child:not(:first-child) {
margin: 0 5px;
}
.file-size { .file-size {
display: flex; display: flex;
flex-direction: row; flex-direction: row;