▶ Run preview

Creating video editor with gifts

Add video and create gift with it

Built by@NDtechBronze
WEB Web app AI-generated Checked ▶ Preview
Published 18 Sep 2026 · Created 18 Sep 2026
creating-video-editor-with-gifts-1 — Preview● Secure sandbox
PROOF CARD
Creating video editor with gifts
@NDtech · AI-generated · 7/10 checks
  • ✓ 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
CAPABILITIES DEMONSTRATED

Based on this build, not self-reported. Select a skill to find matching builders.

Share to WhatsApp
SHIP READINESS — PRECISE CHECKS
  • ✓ 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.

PROJECT EVIDENCE
Creator identityAvailable — @NDtech
Project filesAvailable — snippet inline
READMEAvailable
Live previewAvailable — runs sandboxed
Security scanChecked — virus clean, no secrets
Project historyAvailable — 1 event
ReviewsNot available — none yet
StarsNot available — no stars yet
Remix lineageAvailable — original project
Build methodAvailable — AI-generated
BUILD METHOD
AI-generated — Substantially produced from an AI workflow.
AI-generated — AI is a tool here, not the author. Provenance is transparent.
PROJECT HISTORY — WHAT CHANGED
Sep 18 First version published
COMMUNITY — COMMENTS · 5
Please sign in to comment.
@PCOATING1 month, 1 week ago

NICE APP

@NDtech

Thank you

@NDtech

Thank you

@NDtech

Try to remix it

@NDtech

Try to remix it

COMMUNITY — REVIEWS · 0
Please sign in to review. Trade or star first.
No witnesses yet.
NEXT ACTIONS
Start with the idea, change it, and publish your version.
Comment
README — REQUIRED FOR EVERY PROJECT

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

FILE TREE
No file tree — this is a snippet. See Code tab.
Click any file to preview (200KB max). Full ZIP has everything.
<!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; }
Ask Nolo — assistant, not author
Compare features side-by-side. You decide what to build.
✓ Checked — Virus-scanned clean · no leaked secrets · dependencies checked. What does this mean?
PROJECT DETAILS
Publisher@NDtech
StackHTML, CSS, JavaScript
Files0 · 0 views
Build methodAI-generated
LicenseMIT
Tip
DOWNLOAD
▶ Run preview
⑂ FORKS — Family tree → · PRs (0) →
No remixes yet.

HOW TO ACCESS

  1. Read README
  2. Explore Files
  3. Check Evidence
  4. Remix or Download
READY TO SHIP?

Deploy your project.

Follow the official launch guide.

Open launch guide ↗
✓ Copied!