Creating video editor with gifts
Add video and create gift with it
- ✓ README
- ✓ Files or snippet
- ✓ Security scan ran
- ✓ Checked — virus/secrets clean
- — AI tool named
- — AI workflow note
- — Human contribution stated
- ✓ Original (no parent)
- ✓ Live preview
- ✓ Published in public record
Based on this build, not self-reported. Select a skill to find matching builders.
- ✓ Scan completed
- — No test files detected
- ✓ No known-vulnerable dependencies listed
- ✓ No secret-shaped hits in the scan report
- — Maintenance history: 0 stored versions, 1 platform event
These are precise checks on this object. BlaqVibes does not guarantee this app is secure.
NICE APP
Thank you
Thank you
Try to remix it
Try to remix it
You are a senior front‑end engineer. Build a complete, single‑folder static web app named “Video Edit App” that runs entirely in the browser with only HTML, CSS, and vanilla JS (no frameworks, no bundlers, no external CDNs).
Requirements - Video load: drag & drop or file picker; local only (no uploads). - Timeline trim: dual range sliders for In/Out; visual selection bar; keyboard: I=mark In, O=mark Out, Space=play/pause, ←/→ nudge 0.1s. - Preview: one element with: - CSS filter controls: brightness, contrast, saturation, grayscale, blur. - Rotation: 0/90/180/270 via CSS transform. - Text overlay with content, size, color, background opacity, and position (top/bottom, left/right). - Playback controls: speed, volume, mute; current time and duration display; Go to In/Out buttons. - Export: render selected range to WebM (video+audio) using: - Canvas draw loop + CSS filters + rotation. - Web Audio routing (MediaElementSource -> MediaStreamDestination). - MediaRecorder to capture canvas (video) + audio track. - FPS setting (10–60) and output scale: source, 720p tall, 1080p tall. - Show progress %, a downloadable link for the .webm, and an inline preview of the export. - UX: dark theme, clean panels; dropzone state; error messages if export unsupported; cleanup Object URLs on reuse/unload. - Accessibility: labels for inputs, readable contrasts, keyboard shortcuts don’t trigger when typing in inputs.
Output format (very important)
- Return exactly four code blocks, in this order, and nothing else.
1) index.html (code block fenced as html)
2) styles.css (css)
3) app.js (js)
4) README.md (markdown)
Notes - Keep everything self‑contained; no external fonts or libs. - Guard for browsers without MediaRecorder/captureStream and show a helpful message. - Comment key parts of JS (load file, timeline update, export pipeline). - Use modern, readable JS (no minification).
React + Vite (npm run dev) — copy this prompt
You are a senior React engineer. Scaffold a Vite + React app named “video-edit-app” with npm scripts: dev, build, preview. Implement the same “Video Edit App” features as below in React 18 with functional components and hooks; no third‑party UI libs.
Features (must match) - Drag/drop or picker video load; local only. - Dual range sliders for trim In/Out with a visual selection bar; keyboard: I/O to set In/Out, Space play/pause, ←/→ nudge 0.1s. - Filters (brightness, contrast, saturation, grayscale, blur) applied to the preview via CSS filter. - Rotation 0/90/180/270 via CSS transform. - Text overlay content/size/color/background opacity/position. - Playback controls: speed, volume, mute; Go to In/Out; timecode display. - Export selected range to WebM using canvas + Web Audio + MediaRecorder; user‑set FPS (10–60) and scale: source, 720p tall, 1080p tall; progress %, download link, inline preview; clean up Object URLs and AudioContext.
Code quality - Use useRef/useState/useEffect; separate presentational CSS. - Handle unsupported browsers with a visible error note. - Cleanup on unmount: cancelAnimationFrame, close AudioContext, revoke URLs.
Output format (very important)
- Provide these files as code blocks only, in this exact order:
1) package.json (json)
2) index.html (html)
3) vite.config.js (js)
4) src/main.jsx (jsx)
5) src/App.jsx (jsx)
6) src/styles.css (css)
7) README.md (```markdown)
Notes - No explanations outside code blocks. - Keep the UI dark themed
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Video Edit App (Static)</title>
<link rel="stylesheet" href="styles.css" />
<meta name="description" content="Trim, filters, rotate, text overlay, and WebM export in-browser." />
</head>
<body>
<main class="app">
<header class="app__header">
<h1>🎬 Video Edit App</h1>
<p>Drop a video or click to upload. I/O to set trim, Space to play/pause. Export selection to WebM in-browser.</p>
</header>
<!-- Uploader -->
<section id="uploader">
<label id="dropzone" class="dropzone">
<input id="fileInput" type="file" accept="video/*" hidden />
<div>
<strong>Click to choose a video</strong> or drag & drop here
<div class="hint">MP4, WebM, MOV… (local files aren’t uploaded anywhere)</div>
</div>
</label>
</section>
<!-- Editor (hidden until a video is loaded) -->
<section id="editor" hidden>
<section class="stage">
<div class="video-stage">
<video id="video" controls="false" playsinline></video>
<div id="overlay" class="overlay overlay--bottom-left"></div>
</div>
<div class="transport">
<button id="playPauseBtn">Play</button>
<button id="goInBtn">⏮ Go to In</button>
<button id="goOutBtn">⏭ Go to Out</button>
<div class="timecode">
<span id="currentTime">0:00.00</span> /
<span id="duration">0:00.00</span>
</div>
</div>
<div class="timeline">
<div className="timeline__wrap">
<div class="timeline__bar">
<div id="timelineSelection" class="timeline__selection"></div>
</div>
</div>
<input id="rangeStart" class="range range--a" type="range" min="0" step="0.01" value="0" />
<input id="rangeEnd" class="range range--b" type="range" min="0" step="0.01" value="0" />
<div class="inout">
<button id="markInBtn">Set In (I) 0:00.00</button>
<button id="markOutBtn">Set Out (O) 0:00.00</button>
</div>
</div>
</section>
<section class="panel-grid">
<div class="panel">
<h3>Playback</h3>
<label>Speed
<input id="playbackRate" type="range" min="0.25" max="3" step="0.05" value="1" />
<span id="playbackRateVal">1.00×</span>
</label>
<label>Volume
<input id="volume" type="range" min="0" max="1" step="0.01" value="1" />
<span id="volumeVal">100%</span>
</label>
<label class="row">
<input id="mute" type="checkbox" />
Mute
</label>
</div>
<div class="panel">
<h3>Filters</h3>
<label>Brightness
<input id="brightness" type="range" min="50" max="200" step="1" value="100" />
</label>
<label>Contrast
<input id="contrast" type="range" min="50" max="200" step="1" value="100" />
</label>
<label>Saturation
<input id="saturate" type="range" min="0" max="300" step="1" value="100" />
</label>
<label>Grayscale
<input id="grayscale" type="range" min="0" max="100" step="1" value="0" />
</label>
<label>Blur
<input id="blur" type="range" min="0" max="10" step="0.5" value="0" />
</label>
<label class="row">Rotate
<select id="rotate">
<option value="0">0°</option>
<option value="90">90°</option>
<option value="180">180°</option>
<option value="270">270°</option>
</select>
</label>
</div>
<div class="panel">
<h3>Overlay</h3>
<label>Text
<input id="overlayText" type="text" placeholder="Enter overlay text…" />
</label>
<label>Size
<input id="overlaySize" type="range" min="16" max="96" step="1" value="36" />
<span id="overlaySizeVal">36px</span>
</label>
<label class="row">Color
<input id="overlayColor" type="color" value="#ffffff" />
</label>
<label>Background opacity
<input id="overlayBg" type="range" min="0" max="1" step="0.05" value="0.4" />
<span id="overlayBgVal">0.40</span>
</label>
<label class="row">Position
<select id="overlayPos">
<option value="top-left">Top left</option>
<option value="top-right">Top right</option>
<option value="bottom-left" selected>Bottom left</option>
<option value="bottom-right">Bottom right</option>
</select>
</label>
</div>
<div class="panel">
<h3>Export</h3>
<div class="export-rows">
<label class="row">FPS
<input id="fps" type="number" min="10" max="60" step="1" value="30" />
</label>
<label class="row">Resolution
<select id="scale">
<option value="source">Source</option>
<option value="720p">Scale to 720p tall</option>
<option value="1080p">Scale to 1080p tall</option>
</select>
</label>
</div>
<button id="exportBtn" disabled>Export selection (WebM)</button>
<button id="cancelExportBtn" class="ghost" hidden>Cancel</button>
<div id="exportError" class="error"></div>
<div id="exportOut" class="export-out" hidden>
<a id="downloadLink" href="#" download="clip.webm">Download clip</a>
<video id="exportVideo" controls playsinline></video>
</div>
<div class="note">Note: Export happens in real-time in your browser. Best supported on Chromium-based browsers.</div>
</div>
</section>
</section>
<canvas id="exportCanvas" style="display:none"></canvas>
<footer class="footer">
<span id="footerText">Tip: Press I to mark In and O to mark Out.</span>
</footer>
</main>
<script src="app.js" defer></script>
</body>
</html>:root {
--bg: #0f172a;
--panel: #0b1220;
--text: #e5e7eb;
--muted: #9ca3af;
--accent: #22d3ee;
--line: rgba(255,255,255,0.12);
--good: #22c55e;
--warn: #f59e0b;
--bad: #ef4444;
}
* { box-sizing: border-box; }
html, body, #root { height: 100%; }
body {
margin: 0;
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Arial, "Apple Color Emoji", "Segoe UI Emoji";
background: radial-gradient(1000px 500px at 20% -20%, #1f2937 0%, var(--bg) 60%);
color: var(--text);
}
.app {
max-width: 1100px;
margin: 28px auto 60px;
padding: 0 18px;
}
.app__header h1 { margin: 0 0 6px; font-size: 28px; }
.app__header p { margin: 0 0 18px; color: var(--muted); }
.dropzone {
border: 2px dashed var(--line);
border-radius: 14px;
padding: 36px;
display: grid;
place-items: center;
color: var(--muted);
cursor: pointer;
transition: 0.2s border-color ease, 0.2s color ease;
}
.dropzone:hover { border-color: var(--accent); color: var(--text); }
.dropzone .hint { margin-top: 6px; font-size: 13px; color: var(--muted); }
.stage { margin-top: 12px; }
.video-stage {
position: relative;
background: #000;
border: 1px solid var(--line);
border-radius: 12px;
overflow: hidden;
aspect-ratio: 16 / 9;
display: grid;
place-items: center;
}
.video-stage video {
max-width: 100%;
max-height: 70vh;
}
.overlay {
position: absolute;
padding: 6px 10px;
font-weight: 800;
border-radius: 8px;
background: rgba(0,0,0,0.4);
display: none;
}
.overlay--top-left { top: 10px; left: 10px; }
.overlay--top-right { top: 10px; right: 10px; }
.overlay--bottom-left { bottom: 10px; left: 10px; }
.overlay--bottom-right { bottom: 10px; right: 10px; }
.transport {
display: flex;
gap: 10px;
align-items: center;
margin: 10px 0 4px;
}
.transport button { padding: 8px 12px; }
.timecode { margin-left: auto; color: var(--muted); }
.timeline {
position: relative;
margin: 8px 0 18px;
padding-top: 22px;
}
.timeline__bar {
position: relative;
height: 8px;
background: rgba(255,255,255,0.07);
border-radius: 999px;
overflow: hidden;
}
.timeline__selection {
position: absolute;
top: 0;
height: 100%;
background: linear-gradient(90deg, rgba(34,211,238,0.5), rgba(34,211,238,0.25));
left: 0;
width: 0%;
}
.range {
-webkit-appearance: none;
appearance: none;
width: 100%;
background: transparent;
position: absolute;
top: 0;
height: 30px;
pointer-events: none;
}
.range::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 16px; height: 16px;
border-radius: 50%;
background: var(--accent);
border: 2px solid #062a30;
cursor: pointer;
pointer-events: all;
box-shadow: 0 0 0 2px rgba(34,211,238,0.35);
margin-top: 7px;
}
.range::-moz-range-thumb {
width: 16px; height: 16px; border-radius: 50%;
background: var(--accent); border: none;
cursor: pointer; pointer-events: all;
}
.range--a { z-index: 1; }
.range--b { z-index: 2; }
.inout { display: flex; gap: 10px; margin-top: 12px; }
.inout button { padding: 6px 10px; }
.panel-grid {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 12px;
}
@media (max-width: 1000px) {
.panel-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
.panel-grid { grid-template-columns: 1fr; }
}
.panel {
background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.03));
border: 1px solid rgba(255,255,255,0.08);
border-radius: 12px;
padding: 16px;
}
.panel h3 { margin: 0 0 12px; }
.panel label {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
gap: 10px;
margin: 10px 0;
font-size: 14px;
color: var(--text);
}
.panel label.row { grid-template-columns: auto 1fr; }
.panel input[type="text"] {
width: 100%;
padding: 8px 10px;
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.14);
border-radius: 8px;
color: var(--text);
}
.panel input[type="number"], .panel select {
padding: 6px 8px;
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.14);
border-radius: 8px;
color: var(--text);
}
button {
background: var(--accent);
color: #04242b;
border: none;
border-radius: 10px;
padding: 10px 14px;
font-weight: 700;
cursor: pointer;
}
button.ghost {
background: transparent;
color: var(--text);
border: 1px solid var(--line);
}
button:hover { filter: brightness(1.05); }
.export-rows { display: grid; gap: 10px; }
.error { margin-top: 10px; color: var(--bad); min-height: 1.2em; }
.export-out { margin-top: 10px; display: grid; gap: 8px; }
.export-out a {
color: #04242b; background: var(--good);
padding: 8px 12px; border-radius: 8px; font-weight: 800;
text-align: center; text-decoration: none;
}
.export-out video { width: 100%; border: 1px solid var(--line); border-radius: 8px; }
.footer { margin-top: 24px; color: var(--muted); font-size: 13px; }HOW TO ACCESS
- Read README
- Explore Files
- Check Evidence
- Remix or Download