feat: add sample video loading functionality and improve button styling in upscaler page

This commit is contained in:
Harvey Zhao committed 2026-03-01 15:56:57 +08:00
1 parent 9db9cd1f1e
commit 6b66029c54
1 file changed
+108 -18
+108 -18
View File
@@ -41,7 +41,11 @@
name="twitter:description"
content="Upscale videos with AI super resolution directly in your browser. Free, private, no upload needed."
/>
<link rel="shortcut icon" href="/assets/img/favicon.ico" type="image/x-icon" />
<link
rel="shortcut icon"
href="/assets/img/favicon.ico"
type="image/x-icon"
/>
<script
async
src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8579453810848662"
@@ -131,9 +135,35 @@
class="text-slate-700 font-medium text-base mb-1"
>Choose a video file</span
>
<span class="text-slate-400 text-sm"
<span class="text-slate-400 text-sm mb-4"
>or drag and drop here</span
>
<button
type="button"
onclick="loadSampleVideo(event)"
class="inline-flex items-center gap-2 px-4 py-2 text-sm font-semibold text-white bg-blue-500 hover:bg-blue-600 rounded-lg transition-all"
>
<svg
class="w-4 h-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"
/>
<path
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
/>
</svg>
Try sample video
</button>
</div>
<!-- Video Preview (shown after file selection) -->
<div
@@ -517,7 +547,9 @@
signal,
});
document.addEventListener("mousemove", updatePosition, { signal });
document.addEventListener("mousemove", updatePosition, {
signal,
});
document.addEventListener("touchmove", updatePosition, {
passive: false,
signal,
@@ -526,18 +558,22 @@
document.addEventListener("mouseup", stopDrag, { signal });
document.addEventListener("touchend", stopDrag, { signal });
container.addEventListener("click", (e) => {
const rect = container.getBoundingClientRect();
const x = e.clientX - rect.left;
const { percentage } = updateComparisonPosition(
originalElement,
rect,
x,
);
container.addEventListener(
"click",
(e) => {
const rect = container.getBoundingClientRect();
const x = e.clientX - rect.left;
const { percentage } = updateComparisonPosition(
originalElement,
rect,
x,
);
handle.style.left = x + "px";
applyMaskToElement(originalElement, percentage);
}, { signal });
handle.style.left = x + "px";
applyMaskToElement(originalElement, percentage);
},
{ signal },
);
applyMaskToElement(originalElement, 50);
handle.style.left = container.offsetWidth / 2 + "px";
@@ -583,7 +619,11 @@
originalVideo.currentTime = enhancedVideo.currentTime;
});
comparisonCleanup = setupComparisonDrag(container, handle, originalVideo);
comparisonCleanup = setupComparisonDrag(
container,
handle,
originalVideo,
);
enhancedVideo.autoplay = true;
enhancedVideo.play().catch(() => {});
@@ -596,6 +636,47 @@
return s > 0 ? `${m}m ${s}s` : `${m}m`;
}
async function loadSampleVideo(e) {
e.preventDefault();
e.stopPropagation();
const sampleUrl =
"https://artplayer.org/assets/sample/frag_bunny.mp4";
const btn = e.currentTarget;
const originalText = btn.innerHTML;
btn.disabled = true;
btn.innerHTML = `
<svg class="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24">
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
Loading...
`;
try {
const response = await fetch(sampleUrl);
const blob = await response.blob();
const file = new File([blob], "sample_video.mp4", {
type: "video/mp4",
});
// Create a DataTransfer to set files on input
const dataTransfer = new DataTransfer();
dataTransfer.items.add(file);
document.getElementById("universalInput").files =
dataTransfer.files;
document
.getElementById("universalInput")
.dispatchEvent(new Event("change"));
} catch (error) {
console.error("Failed to load sample video:", error);
alert("Failed to load sample video. Please try again.");
btn.disabled = false;
btn.innerHTML = originalText;
}
}
let previewVideoUrl = null;
function showVideoPreview(file) {
@@ -873,14 +954,23 @@
videoResultSection?.classList.remove("hidden");
// Scroll to result section
resultSection.scrollIntoView({ behavior: "smooth", block: "start" });
resultSection.scrollIntoView({
behavior: "smooth",
block: "start",
});
// Initialize comparison drag after video loads
const enhancedVideo = document.getElementById("resultVideoEnhanced");
const enhancedVideo = document.getElementById(
"resultVideoEnhanced",
);
if (enhancedVideo.readyState >= 2) {
initVideoComparisonDrag();
} else {
enhancedVideo.addEventListener("loadeddata", initVideoComparisonDrag, { once: true });
enhancedVideo.addEventListener(
"loadeddata",
initVideoComparisonDrag,
{ once: true },
);
}
} catch (error) {
console.error("Upscaling error:", error);