From 39fa99da63962c7497c1cb850b19b0da58e1676c Mon Sep 17 00:00:00 2001 From: Reimar Date: Tue, 28 Jan 2025 19:31:11 +0100 Subject: [PATCH] Implement showing video you just selected --- public/assets/scripts/main.js | 24 ++++++------ public/assets/scripts/ui.js | 43 +++++++++++++++++++++ public/assets/style/main.css | 72 ++++++++++++++++++++++++++--------- public/index.html | 17 ++++++--- 4 files changed, 121 insertions(+), 35 deletions(-) create mode 100644 public/assets/scripts/ui.js diff --git a/public/assets/scripts/main.js b/public/assets/scripts/main.js index 7f469a3..8ef8372 100644 --- a/public/assets/scripts/main.js +++ b/public/assets/scripts/main.js @@ -2,6 +2,7 @@ async function compress() { showSection("loading"); const filesize = document.getElementById("filesize").value; + const filesizeUnit = document.getElementById("filesize-unit").value; const file = document.getElementById("file-input").files[0]; const ffmpeg = new FFmpegWASM.FFmpeg(); @@ -13,30 +14,27 @@ async function compress() { await ffmpeg.writeFile(file.name, await readFromBlob(file)); - await ffmpeg.exec(["-i", file.name, "-fs", filesize + "M", "compressed.mp4"]); + await ffmpeg.exec(["-i", file.name, "-preset", "ultrafast", "-fs", filesize + filesizeUnit, "compressed.mp4"]); const video = await ffmpeg.readFile("compressed.mp4"); location.href = URL.createObjectURL(new Blob([video.buffer], { type: "video/mp4" })); } -function selectFile() { +function openFileSelector() { document.getElementById("file-input").click(); } -function showSection(section) { - for (const section of document.getElementsByTagName("section")) { - section.style.opacity = "0"; - } - +function selectFile() { setTimeout(() => { - for (const section of document.getElementsByTagName("section")) { - section.style.display = "none"; - } + const file = document.getElementById("file-input").files[0]; - document.getElementById(section + "-section").style.display = "block"; - document.getElementById(section + "-section").style.opacity = "1"; - }, 400); + document.getElementById("uploaded-video").src = URL.createObjectURL(file); + document.getElementById("uploaded-video").load(); + + hideElements("#file-drop-area", "#file-input-spacing"); + showElements("#uploaded-video", "#change-file"); + }, 200); } // https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/packages/util/src/index.ts diff --git a/public/assets/scripts/ui.js b/public/assets/scripts/ui.js new file mode 100644 index 0000000..297b5fd --- /dev/null +++ b/public/assets/scripts/ui.js @@ -0,0 +1,43 @@ +const TRANSITION_TIME = 300; + +function showSection(section) { + for (const section of document.getElementsByTagName("section")) { + hideElements(section); + } + + showElements(`#${section}-section`); +} + +function hideElements() { + for (const input of arguments) { + const elem = input instanceof Element ? input : document.querySelector(input); + + if (getComputedStyle(elem).display === "none") + continue; + + elem.style.opacity = "0"; + elem.dataset.oldDisplay = getComputedStyle(elem).display; + + setTimeout(() => { + elem.style.display = "none"; + }, TRANSITION_TIME); + } +} + +function showElements() { + setTimeout(() => { + for (const input of arguments) { + const elem = input instanceof Element ? input : document.querySelector(input); + + elem.style.opacity = "0"; + + elem.style.display = elem.dataset.oldDisplay || "block"; + elem.dataset.oldDisplay = null; + + setTimeout(() => { + elem.style.opacity = "1"; + }, 10); + } + }, TRANSITION_TIME); +} + diff --git a/public/assets/style/main.css b/public/assets/style/main.css index 4eb539e..1af31c9 100644 --- a/public/assets/style/main.css +++ b/public/assets/style/main.css @@ -20,36 +20,44 @@ h1 { margin-bottom: 1rem; } -h3 { - color: #757575; - font-size: 4rem; - font-weight: 400; - margin: 0; -} - p { color: #9E9E9E; font-size: 0.8rem; } -section { - transition: opacity ease-in 400ms; +* { + opacity: 1; + transition: opacity 300ms; } -#file-input { +video { + width: 355px; + height: 200px; + border: 2px solid #212121; + background-color: black; + border-radius: 1rem; + box-shadow: 0 5px 5px rgba(0, 0, 0, 0.2); +} + +#file-input, #change-file { display: none; + opacity: 0; +} + +#file-input-spacing * { + visibility: hidden; } #file-drop-area { max-width: 355px; - height: 200px; + height: 198px; border: 3px dotted #BDBDBD; - margin: 3rem auto; + margin: 3rem auto 1rem auto; border-radius: 1rem; display: flex; justify-content: center; align-items: center; - transition: background-color ease-in 200ms; + transition: all 300ms; cursor: pointer; } @@ -62,7 +70,13 @@ section { outline: none; } -button { +#uploaded-video { + display: none; + opacity: 0; + margin: 3rem auto 1rem auto; +} + +button.primary { background-image: linear-gradient(to right, #4CAF50, #00BCD4); border: none; color: white; @@ -74,19 +88,32 @@ button { cursor: pointer; } -button:hover { +button.primary:hover { filter: brightness(1.1); } -button:active { +button.primary:active { filter: brightness(0.8); } -button:focus { +button.primary:focus { box-shadow: 0 4px 4px rgba(0, 0, 0, 0.2); outline: 2px solid black; } +button.simple { + border: none; + background-color: transparent; + transition: color 100ms; + cursor: pointer; + color: #9E9E9E; + margin: 1rem auto; +} + +button.simple:hover { + color: black; +} + input, select { background-color: white; padding: 0.5rem 1rem; @@ -121,3 +148,14 @@ input:focus, select:focus { margin-left: 1rem; } +#loading-title { + color: #757575; + font-size: 3rem; + font-weight: bold; + margin-top: 2rem; +} + +#loading-description { + font-size: 1rem; +} + diff --git a/public/index.html b/public/index.html index 209f8bf..42f9fd5 100644 --- a/public/index.html +++ b/public/index.html @@ -4,6 +4,7 @@ Video Compressor + @@ -12,10 +13,16 @@

Compress video files to a specific file size, so you can upload them to your favorite social media and messaging apps!

-
+
Drag and drop a file here!
- + +
+ +
+ + +