import React, { useState } from 'react'; import { Copy, RefreshCw, Sparkles, Camera, Clapperboard, Music, Sun, Film, ChevronDown, Video, Layout, Hammer, ZoomIn, Info } from 'lucide-react'; // --- DATA PRESETS --- const PRESETS = { subjects: [ "Traditional Japanese Ramen Shop", "New York City Newsstand", "Parisian Corner Bakery", "Vintage 1950s Gas Station", "Cluttered Artist Studio", "Cozy Log Cabin Living Room", "Busy Laundromat at Night", "Old School Boxing Gym", "Modern Minimalist Coffee Shop", "Rusty Car Mechanic Garage", "Traditional Indonesian 'Warteg' Stall", "Classic 'Bakso' Cart on Street Corner", "Busy 'Pasar Malam' (Night Market)", "Old Dutch Colonial House", "Balinese Temple Entrance", "Subway Train Car Interior", "Street Food Taco Truck", "Classic American Diner", "Quiet Library Reading Nook", "Greenhouse filled with Plants", "Fish Market Stall", "Antique Watchmaker Shop", "Jazz Club Stage", "Camping Tent by the Lake", "Urban Rooftop Garden" ], locations: [ "a busy intersection in Tokyo", "a quiet rainy street in London", "a sun-drenched Italian piazza", "a snowy sidewalk in New York", "a dusty highway in Arizona", "a lush backyard garden", "a gritty industrial alleyway", "a peaceful forest trail", "a crowded market in Marrakech", "a foggy harbor dock", "a roadside in rural Java", "a narrow alley in Jakarta", "a clean suburban driveway", "a mountain hiking path", "a wet cobblestone road" ], materials: [ "hand-painted polymer clay", "weathered reclaimed wood", "crystal clear epoxy resin water", "distressed rusted metal", "fine textured miniature grass", "intricately carved balsa wood", "miniature bricks and real mortar", "delicate papercraft details", "soft felt and fabric textures", "glossy ceramic-like finish" ], scales: [ "1:12 Standard Scale", "1:24 Half Scale", "1:48 Quarter Scale", "1:87 HO Scale (Hyper Micro)", "Microscopic 1:144 Scale" ], interiors: [ "chef chopping vegetables rapidly", "mechanic tightening bolts on an engine", "barista pouring latte art", "artist painting on a canvas", "tailor sewing fabric on a machine", "musicians playing saxophone and bass", "customers eating hot food", "students reading books quietly", "barber cutting hair", "florist arranging bouquets" ], exteriors: [ "rain dripping from awnings", "pigeons flying off the roof", "autumn leaves blowing in the wind", "steam rising from manholes", "street cats sleeping on a bench", "bicycles parked against a wall", "traffic lights changing colors", "neon signs flickering softly", "wet pavement reflecting lights", "dust motes dancing in sunbeams" ], moods: [ "golden hour, warm and nostalgic", "overcast, soft diffused light", "rainy night, cinematic noir", "harsh high-noon sunlight", "misty morning, cool tones", "cozy candlelight, warm interior", "fluorescent office lighting", "blue hour, twilight city", "snowy white, bright and clean", "neon cyberpunk, pink and blue" ], sequences: [ { label: "Morning Routine", value: "Scene 1: The shop is closed, streets are empty.\nScene 2: Owner arrives and unlocks the door.\nScene 3: Interior lights flicker on, prep begins.\nScene 4: 'Open' sign flips, first customer enters." }, { label: "Weather Shift", value: "Scene 1: Sunny day, people walking.\nScene 2: Clouds gather, lighting turns grey.\nScene 3: Rain starts falling, umbrellas open.\nScene 4: Heavy downpour, puddles forming." }, { label: "Crafting Process", value: "Scene 1: Wide shot of artisan workshop.\nScene 2: Extreme close-up of raw materials.\nScene 3: Hands working with miniature tools.\nScene 4: Finished diorama displayed on a shelf." }, { label: "Indonesian Life", value: "Scene 1: Early morning mist over the warung.\nScene 2: Bubur ayam vendor preparing bowls.\nScene 3: Motorbikes passing with motion blur.\nScene 4: Night falls, warm bulbs glow dimly." } ], ratios: [ { label: "16:9 (Cinematic)", value: "16:9" }, { label: "9:16 (TikTok)", value: "9:16" }, { label: "1:1 (Square)", value: "1:1" }, { label: "21:9 (Ultrawide)", value: "21:9" } ] }; const App = () => { const [formData, setFormData] = useState({ subject: '', location: '', material: 'hand-painted polymer clay', scale: '1:12 Standard Scale', interiorDetails: '', exteriorDetails: '', mood: 'golden hour, warm and nostalgic', sequenceLogic: '', aspectRatio: '16:9' }); const [generatedPrompt, setGeneratedPrompt] = useState(null); const [isCopied, setIsCopied] = useState(false); const [activeTab, setActiveTab] = useState('standard'); const handleInputChange = (e) => { const { name, value } = e.target; setFormData(prev => ({ ...prev, [name]: value })); }; const handlePresetSelect = (field, value) => { setFormData(prev => ({ ...prev, [field]: value })); }; const randomizeAll = () => { const random = (arr) => arr[Math.floor(Math.random() * arr.length)]; setFormData({ subject: random(PRESETS.subjects), location: random(PRESETS.locations), material: random(PRESETS.materials), scale: random(PRESETS.scales), interiorDetails: random(PRESETS.interiors), exteriorDetails: random(PRESETS.exteriors), mood: random(PRESETS.moods), sequenceLogic: random(PRESETS.sequences).value, aspectRatio: random(PRESETS.ratios).value }); }; const generatePrompt = () => { const { subject, location, material, scale, interiorDetails, exteriorDetails, mood, sequenceLogic, aspectRatio } = formData; const s = subject || "Miniature Scene"; const l = location || "a detailed environment"; const mtr = material || "handcrafted materials"; const sc = scale || "1:12 scale"; const id = interiorDetails || "tiny life-like details"; const ed = exteriorDetails || "intricate landscape elements"; const m = mood || "atmospheric lighting"; const ar = aspectRatio || "16:9"; const promptStructure = { visuals: `Hyper-realistic ${sc} miniature diorama of ${s} at ${l}. Handcrafted using ${mtr} with realistic weathering. Open-back cutaway reveals ${id}. Exterior environment shows ${ed}. 8K resolution, macro photography style, extreme depth of field, handcrafted artisan aesthetic.`, camera: `Slow, cinematic macro dolly-zoom orbit around the diorama. Smooth tilt-shift focus transition between the foreground ${ed} and background interior.`, animation: `Subtle stop-motion style movement: figures blinking or shifting slightly, ${ed} moving in the breeze, interior lights flickering warmly.`, sound: `Macro-audio soundscape: the tiny click of wood, rustle of miniature fabric, muffled ambient sounds of ${l}, zero dialogue.`, lighting: `${m}, high-contrast cinematic shadows, tiny warm LEDs glowing inside the cutaway.`, parameter: `--ar ${ar} --v 6.0 --stylize 300`, sequence: sequenceLogic ? `STORYBOARD SEQUENCE:\n${sequenceLogic}` : null, veo: "" }; // VEO Consistency Logic const veoBase = `Cinematic 8K video (${ar}) of a ${sc} miniature ${s} diorama in ${l}. Material: ${mtr}. Style: Macro photography, handcrafted artisan. Lighting: ${m}.`; if (sequenceLogic) { const scenes = sequenceLogic.split('\n').filter(line => line.trim().length > 0); promptStructure.veo = scenes.map((sceneLine) => { const splitIndex = sceneLine.indexOf(':'); const sceneLabel = splitIndex !== -1 ? sceneLine.substring(0, splitIndex) : "SCENE"; const sceneAction = splitIndex !== -1 ? sceneLine.substring(splitIndex + 1).trim() : sceneLine; return `[PROMPT FOR ${sceneLabel.toUpperCase()}]\n${veoBase}\nFOCUS ACTION & DETAILS: ${sceneAction}. Interior shows ${id}.`; }).join('\n\n' + '-'.repeat(30) + '\n\n'); } else { promptStructure.veo = `${veoBase} The scene features ${ed} and a cutaway revealing ${id}. Slow orbit camera motion.`; } setGeneratedPrompt(promptStructure); setIsCopied(false); }; const copyToClipboard = () => { if (!generatedPrompt) return; let textToCopy = ""; if (activeTab === 'veo') { textToCopy = generatedPrompt.veo; } else { textToCopy = `--- MINIATURE DIORAMA PROMPT ---\n\n` + `VISUALS: ${generatedPrompt.visuals}\n\n` + `CAMERA: ${generatedPrompt.camera}\n\n` + `ANIMATION: ${generatedPrompt.animation}\n\n` + `SOUND: ${generatedPrompt.sound}\n\n` + `LIGHTING: ${generatedPrompt.lighting}\n\n` + `PARAMETERS: ${generatedPrompt.parameter}`; if (generatedPrompt.sequence) { textToCopy += `\n\n${generatedPrompt.sequence}`; } } const textArea = document.createElement("textarea"); textArea.value = textToCopy; document.body.appendChild(textArea); textArea.select(); try { document.execCommand('copy'); setIsCopied(true); setTimeout(() => setIsCopied(false), 2000); } catch (err) { console.error("Gagal menyalin", err); } document.body.removeChild(textArea); }; const InputGroup = ({ label, name, value, options, icon: Icon, isTextArea = false }) => (
Mastering Miniature Prompts for VEO 3.1
Waiting for your creativity...
Fill the config on the left to start generating diorama prompts.
{generatedPrompt.camera}
{generatedPrompt.lighting}
{generatedPrompt.parameter}
Model video (VEO) membutuhkan pengulangan deskripsi dasar untuk menjaga konsistensi objek di setiap klip.