Build your identity. Edit your image. Let the city react.
Most image editors end the moment you hit save. VICE ID starts there.
You create a character, edit their portrait with Unlayer React Image Editor, and that exact export becomes a wanted poster across Vice Coast, a fictional GTA VI inspired coastal city. Then you walk into that city in 3D and live with it. Pedestrians recognise the face you made. A witness calls it in. VMPD starts looking for you.
The editor does not stay behind on the previous screen. Inside the district there is a Draw / Edit dock that is open from the first frame and never goes away. Stand in front of a wall, a shutter, a notice panel or almost any upright surface, and the editor opens on that surface. Your strokes land on it in 3D while the street keeps moving around you. Whether anyone finds out depends on where you painted. The three prepared street walls are public, so painting one is reported straight away. A surface you found yourself down a side street stays quiet until somebody walks past it, reads it, and connects it to the face on your poster.
Built for Unlayer's Build with React Image Editor Challenge.
#BuiltWithImageEditor
Play it · Source · React Image Editor
There are five places you open React Image Editor, and every one of them feeds something downstream.
| Session | You start from | What you get |
|---|---|---|
| VICE Studio | Your uploaded portrait | The edited portrait, used in the police dossier, the wanted poster and the final ID card |
| Wanted Poster Studio | The generated poster, portrait already in it | The published poster: street panels, billboard, dossier evidence, VICEFEED, download |
| Street Signal Studio | A brick wall, shutter or notice panel | Live paint on that surface in 3D, plus a street signal other characters react to |
| Free-surface painting | A blank transparent canvas pinned to whatever you are facing | A mark stuck to that exact spot in the world |
| In-game poster remix | The poster currently on the streets | Every poster stand and the billboard in this run, repainted |
The first screenshots are the identity and poster journey. The later ones show street painting. They were captured while the project was being built, so some on screen wording has changed since, but each shot still shows the feature described under it. Click any image for the full size.
Enter Vice Coast and begin building the identity the city will remember.
| Identity registration Enter a name, alias and optional crew while the live preview updates. |
District and lifestyle Select one of seven districts and a reputation profile. |
VICE Studio embeds the official React Image Editor with crop, resize, filters, drawing, text, shapes, stickers and frames.
| Wanted Poster Studio Customise, save and publish the generated poster. |
City Impact Track sightings, police units, social buzz and district activity. |
District entry introduces movement, camera, sprint, jump and interaction controls before the simulation begins.
VICE ID places the published wanted poster inside the selected 3D district. The initial layout combines the edited portrait with the character's alias, wanted level, district, profile and reward. Opening Customize Poster lets the player edit that whole composition with Unlayer React Image Editor. Any saved text, stickers, drawing, filters or frames become part of the image displayed in the city. Players can also publish the initial composition without this optional second editing session.
One editor export, multiple city surfaces. The street panel on the right presents a close physical copy while the distant billboard broadcasts the same wanted poster across Sunset Strip.
| Poster presence | Purpose inside the experience |
|---|---|
| Street panels and poster stands | Make the edited asset discoverable at pedestrian level and give the player something physical to approach and inspect. |
| District billboard | Displays the published poster after 25 seconds of active gameplay, or earlier when local buzz reaches 90. |
| Nearby witnesses | Posters create suspicion. Once the player publishes a wall mark, nearby witnesses can report the character's location. |
| Police response | Painting one of the three public street walls is reported at once and starts a ten second delay before dispatch. A surface the player finds themselves is only reported once a bystander sees it and later recognises the face. Poster recognition alone does not start a pursuit; firing a weapon reports the player's location immediately. |
| Persistent visual identity | The same saved poster appears in the city preview, dossier evidence, VICEFEED and poster downloads. The final identity card separately uses the edited portrait and updated story details. |
Recognition is a fictional gameplay simulation based on poster activation, proximity and line of sight. The application does not analyse the uploaded face or perform real facial recognition.
| Police awareness Visual contact increases awareness according to distance and exposure. |
Active pursuit Break line of sight and remain hidden to escape VMPD. |
District outcome records the arrest in the city story or lets the player retry.
These screenshots show the current street-editing flow. The important connection is visible in the painting views: the image being edited with Unlayer React Image Editor on the right becomes artwork on the 3D surface on the left. Unlayer provides the image tools; VICE ID exports the canvas and applies it to the scene.
The drawing tools are not decorative controls. The exported artwork remains visible when the editor closes. The pursuit and outcome screenshots show the surrounding game loop, not features supplied by the image editor itself.
The editor is the whole game, not a step in it. Five separate sessions, and each one changes something you can walk up to afterwards. The poster you customise is the poster on the billboard. The wall you paint is the wall people report you for.
Painting happens live, in 3D. Open a surface and the editor sits beside the scene. Every changed export lands on that surface about once a second while patrols keep walking past. You watch the wall fill in as you draw it.
Almost anything upright is a canvas. Three prepared walls plus any surface you can stand in front of. A raycast checks the angle and reach, then pins a transparent canvas to that exact spot at the right orientation. Floors and ceilings are out, everything else is fair game.
The city finds out through people, not a magic camera. A bystander who can see fresh paint walks over to read it, and from then on can link that mark to the face on your poster. Recognising you without having seen a mark is only gossip. Having seen it, or watching you make it, is what puts someone on the phone to VMPD.
The police actually think. Line of sight detection with real ray casts, A* pathfinding that routes them around buildings instead of through them, awareness that builds with distance and exposure, and a dispatch system that only knows where you were last seen. Crouch and they spot you at 62% of their usual range.
Pedestrians walk the district properly. Waypoint routes on the same acceleration model the player uses, with recovery if one gets wedged against geometry, and they break off to investigate paint when they notice it.
Movement is built on real physics. Rapier handles gravity and collision. On top of that: acceleration limited velocity so you build speed and brake, coyote time after a ledge, jump buffering, a jump cut so a tap is smaller than a hold, and step-up so kerbs do not stop you dead.
Choices carry weight. Painting starts a clock. Firing skips it entirely and pins your location. Hit a bystander and the street scatters while your record gets worse. Five seconds after your first shot the response arms up and shoots back.
Seven districts, each with its own layout, landmarks, palette and atmosphere, all running through one shared scene system.
A minimap that tells you what matters. Roads drawn from the district's own layout, your position and heading, published posters once they go up, and cyan diamonds marking every paintable street wall. It shows when a patrol is active but deliberately never shows you where officers are.
Recognition is simulated, by design. Nothing analyses your photo. Whether someone recognises you comes down to poster activation, proximity and line of sight, which keeps it a game mechanic you can read and play around rather than a black box.
Runs entirely in the browser. No backend, no account, no login. Your character, images and progress are kept in your own browser with IndexedDB, with a memory fallback if storage is blocked.
Built to degrade gracefully. A WebGL check with a real fallback screen, editor load timeouts with retry, upload validation, and reduced motion support.
49 logic tests covering the city simulation, police detection and pathfinding, wall response timing and which surfaces are public, the witness model, movement and escape speeds, paintable surfaces and weapon state. They run in Node with npm test.
- Open viceid.vercel.app and enter the creator.
- Upload a portrait, fill in a name and alias, pick a district.
- Build My Look, make a visible edit, Lock Identity.
- In the dossier, Issue Wanted Poster, then Customize Poster and add something obvious like text or a sticker.
- Save & Preview, then Publish to City.
- Enter a district, Start Exploring, and go find your poster on the street.
- Open Draw / Edit, pick one of the marked street walls, and draw. Watch it appear on the wall behind the panel. That wall is public, so the first stroke is reported and a ten second clock starts. Use Stop and Run before it ends.
- Walk up to any other upright surface and press E to paint that instead.
- Finish or leave the district, go through VICEFEED, and download your ID card and poster.
No account, no login.
Everything goes through one wrapper, ViceImageEditor.tsx, which mounts @unlayer/react-image-editor and bridges its exports into the rest of the app.
All eight native tools are on: crop, resize, filters, draw, text, shapes, stickers and frames. Nothing is reimplemented on top.
Exports. onSave({ dataUrl }) handles saves. Lock Identity, Save & Preview and Publish call the editor instance's getImage() directly to grab the current canvas.
Live painting. This is the part worth explaining, because it is not a feature of the editor. While a surface is open, the app checks hasChanges() and pulls a getImage() export every 850 ms through a non-throwing peekImage() wrapper. Each changed export is written onto that surface's texture as a CanvasTexture. So you are not painting in 3D inside Unlayer. You are painting on a normal 2D canvas, and the app keeps copying the result onto the wall about once a second. The 850 ms cadence is a tradeoff: faster feels more live but calls toDataURL more often.
Why peekImage exists. The normal export path shows an error panel if it fails, which is right for a button press and wrong for a poll. peekImage swallows the failure and skips that frame instead of tearing down the editor mid-drawing.
Session continuity. The source image is frozen for the life of an editing session, so saving does not reload the canvas and throw away that session's undo history.
Storage. The portrait export lives in editedImage, the poster in wantedPosterImage, both in Zustand and persisted to IndexedDB. Street art and in-game poster remixes are deliberately run-local and are not persisted.
The pipeline:
Uploaded portrait
→ React Image Editor (portrait)
→ editedImage
→ dossier, final ID card
→ wanted poster composition
→ React Image Editor (poster, optional)
→ wantedPosterImage
→ street panels, billboard, VICEFEED, download
→ React Image Editor (in-run remix)
Wall texture or blank surface canvas
→ React Image Editor (draw, text, shapes, stickers)
→ export every 850 ms
→ live 3D surface texture
→ Publish Signal: message or false trail
The app composes the initial poster layout and the final ID card with the plain Canvas API. Everything a player actually edits is done by React Image Editor.
Movement runs on Rapier physics. Velocity is acceleration limited rather than snapped to a target, so you build speed and have to brake. There is coyote time after leaving a ledge, a jump buffer so an early press still fires on landing, a jump cut so a tap is a smaller hop than a hold, and step-up so kerbs do not stop you.
| Action | Key |
|---|---|
| Move | WASD or arrows |
| Camera | Drag |
| Sprint | Shift, costs stamina |
| Jump | Space |
| Crouch | Hold C |
| Paint the surface in front of you, or inspect a poster | E |
| Reopen the last thing you edited | Q |
| Leave a wall mid-paint | Escape, or Stop and Run |
| Draw or holster the pistol | G |
| Aim | Hold right mouse, or toggle F |
| Fire while aiming | Left click or Control |
| Reload | R |
| Pause | Escape |
Touch layouts get movement, run, jump, crouch, interact, aim and fire buttons, plus the same Draw / Edit dock.
Getting noticed depends on where you paint. The three prepared walls are public fixtures out on the street. Painting one is seen at once, a ten second clock starts, and VMPD comes to search that wall. Note what they search: the wall, not you. Since the dock reaches every prepared wall from anywhere in the district, you can tag a distant one on purpose and send the response somewhere you are not.
A surface you found yourself is different. Nothing happens. No clock, no police. It stays that way until a bystander with a clear view notices it, walks over to read it, and from then on knows what your face means. When that person later sees you, they call it in. Being watched while you paint is worse again and skips the middle step entirely.
So recognition alone is only gossip. Somebody has to connect the mark to the face, or catch you making it, before anyone is dispatched. Police awareness then climbs while an officer has line of sight, faster the closer they are.
Crouching drops you to a lower profile and officers spot you at 62% of their normal range, and identify you about 40% slower once they do.
Running. Past 50% awareness, or during a pursuit, escape speed engages on its own at 8.5 units per second against a pursuing officer's 6.1. No Shift, no stamina drain. You are meant to be able to outrun them.
The gun is optional and it is a bad idea. Firing reports your position immediately and skips the painting grace period entirely. Hit an officer and that unit is out for fourteen seconds. Hit a bystander and the street scatters, awareness jumps much harder, and it goes on your record. Five seconds after your first shot VMPD arms, two more units roll out, and they close to nine metres before holding and shooting back. Enough return fire and you are Downed instead of arrested.
Escaping. At 100% awareness pursuit starts. Break line of sight, get below 55%, and stay unseen for five seconds.
Street art, free-surface marks and poster remixes last for the current district run and clear on restart. Painting does not pause the world. The pause menu and the poster editor do.
Node 22.6 or newer, because the test runner uses --experimental-strip-types to run TypeScript directly. You need a connection for the editor runtime and fonts, and WebGL for the 3D district.
git clone https://github.com/Anand-240/VICE-ID.git
cd VICE-ID
npm ci
npm run dev| Command | What it does |
|---|---|
npm run dev |
Dev server |
npm run build |
Type check, then build to dist/ |
npm run preview |
Serve the production build |
npm test |
Run the logic tests |
React 18 and TypeScript on Vite. Zustand for state, IndexedDB for persistence, Canvas API for composing the poster and ID card. Three.js with React Three Fiber, Drei and Rapier for the district. Framer Motion and Lucide for the interface.
src/
├── App.tsx Screen flow from landing to final ID
├── components/editor/
│ └── ViceImageEditor.tsx The editor wrapper and export bridge
├── game/
│ ├── ViceDistrictGame.tsx Gameplay flow, awareness, outcomes, HUD
│ ├── NeonHarborScene.tsx The 3D scene, characters and physics
│ ├── locomotion.ts Acceleration, coyote time, jump buffer, step-up
│ ├── movement.ts Walk, sprint, crouch and escape speeds
│ ├── police.ts Detection, awareness, patrol pathfinding
│ ├── weapon.ts Ammo, hitscan, damage, armed response
│ ├── walls.ts Prepared public walls, signals, dispatch delay
│ ├── witness.ts How a bystander turns a mark into a police call
│ ├── tags.ts Paintable surfaces and decal placement
│ └── districts.ts Seven district configurations
├── lib/ Poster and card composition, city sim, storage
└── store/characterStore.ts Shared state, persisted to IndexedDB
NeonHarborScene.tsx is badly named. It renders the shared scene for all seven districts, not just Neon Harbor.
npm test
Eight files covering city simulation and district config, police detection and pathfinding, wall interaction and which surfaces are public, how a bystander turns a mark into a police call, speeds and the escape boost, the locomotion model, paintable surfaces and patch limits, and weapon state.
These are logic tests. They run in Node without a browser, so they cover the rules, not the rendering. The editor itself, downloads, touch controls and anything visual still need checking by hand in a browser.
Vercel, Vite preset, repo root, npm run build, output dist. No environment variables.
| Asked for | What is here |
|---|---|
| A GTA VI inspired experience | Vice Coast, an original fictional coastal city where your edited identity, posters and street marks are the thing you play with. Original names and procedural characters, no Rockstar assets |
| React Image Editor as a core component | Five editor sessions: portrait, poster, in-run poster remix, prepared walls, free surfaces. Remove it and the project has no creative loop left |
| Let users customise at least one visual | Both personal images and city surfaces, using the editor's own tools |
| Public repo and clear docs | This repository |
| A deployed link | viceid.vercel.app |
| Show the experience | The screenshots above |
| Share it with #BuiltWithImageEditor | The hashtag is at the top of this README, and the build is posted publicly under it |
This README describes what the code does. The submission form is handled separately.
Image editing by Unlayer React Image Editor. 3D with Three.js, React Three Fiber, Drei and Rapier. Icons from Lucide. Type is Anton, Manrope and IBM Plex Mono. District and lifestyle illustrations are original SVG work, the 3D scenes are procedural, and portraits come from whoever is playing.
Independent project, GTA inspired, not affiliated with Rockstar Games.