Guides

Why your mockup looks flat, and what you can actually adjust

A screenshot dropped into a frame reads as printed paper. Here is what this editor actually draws, what you can adjust, and what it does not support.

Updated 25 September 2026Next review 20 November 2026

Sources

Drop a screenshot into a device frame and it usually looks wrong. Even with the color and the aspect ratio correct, the screen reads as something printed on paper. Switching to a more detailed frame or retaking the screenshot rarely removes that feeling.

The cause is not the quality of the frame. It is everything that sits on top of the screen. A real photograph of a device carries things a screenshot never has: light caught in the glass, a faint shade around the edge of the display, and the shadow the device casts on whatever it is resting on. A photograph also carries a thin layer of grain across the whole image.

This article maps that gap onto the editor you are actually using. It splits into three parts: what really reaches the canvas today, what you can change yourself, and what this service does not support, so you have to solve it elsewhere. The organising idea is not how many layers the design calls for. It is what survives into the exported image.

The symptom and what you can do about it
What you noticeWhat is missingWhat you can do here
The screen looks as flat as paperLight caught in the glassTurn on glass glare, the checkbox in the finishing panel
The screen looks stuck onto the frame like a stickerThe shade around the edge of the displayThe depth ring and frame art are applied for you
The device looks like it is floating on the backgroundThe shadow it casts on the surfaceNot supported. You have to add it after downloading
The whole image is so clean that it reads as made, not shotThe fine grain a photograph carriesRaise the grain slider, which starts at 8 percent

Which symptom bothers you decides which section to read. You can jump straight to it instead of reading in order.

What actually reaches the canvas today

Pick a frame and four things go onto a single device: your uploaded screenshot, the depth ring around the edge of the display, the frame art that forms the body of the device, and the glass glare. Only the glare follows a control, the checkbox in the finishing panel. The other three are applied the moment you choose a frame.

Once every device is drawn, one layer of grain covers the whole canvas. Grain does not belong to a device. It is a separate overlay across the entire image. So the full count of what survives into the export is four things per device plus one canvas wide overlay.

Anything not on that list is not drawn today. The two obvious ones are the ground shadow under the device and the foreground mask where a hand covers the screen. Both have their own entries in the section on what is not supported. If the shadow is missing, there is no setting to go hunting for.

All of this compositing happens inside your own browser. Your uploaded image is not sent to a server, and the layers described above are drawn on the device you are working on.

The edges of your image get cropped (screenshot)

Your uploaded image fills the screen area. If the aspect ratio differs, the overflow is cropped. A screenshot taken at the same aspect ratio as the screen of the frame loses nothing to that crop. A slot with no image yet shows a dashed outline and an upload prompt instead.

Here the frame type decides the result. Pick a phone frame whose screen area is a transparent cutout, which covers both Phone (notch) and Phone (Android), and the screenshot stays behind the frame and shows through the hole. Frames with an opaque screen, such as Laptop, Tablet, Desktop, and Browser window, do the opposite and place the screenshot on top of the frame. The test is not whether the frame has a notch. It is whether the frame image has a transparent cutout.

The screen looks stuck onto the frame (depth ring and frame art)

When the screen and the bezel read as one flat plane, the depth ring is what is missing. The depth ring is a very faint darkening that follows the edge of the screen. On a real device the glass sits slightly below the bezel, which leaves a thin shade around the border. The frame art is the image of the device body itself, except on the Browser window frame, where the chrome is drawn in code rather than loaded as an image.

These two are drawn as one group, and the frame type decides whether the group lands in front of or behind the screenshot. On phone style frames, where the screen shows through the frame, the group is drawn after the screenshot and the depth ring lands on top of the image. On laptop and tablet style frames, where the screenshot goes over the frame, the group is laid down first and the screenshot arrives last, which hides the depth ring completely.

That is why the same screenshot shows no shade around its edge in a laptop frame. The ring itself is a stroke of black at 40 percent opacity following the rounded edge of the screen, blurred by 2 percent of the short edge. The stroke is 0.4 percent of the short edge, with a floor of one pixel. Values have to stay this small to read as shade, since anything heavier looks like a black border drawn onto the screen (inference).

The depth ring is applied only when the screen is computed as a rectangle. Every frame renders front facing today, so on phone style frames the ring is always there. When phones look slanted in Diagonal stagger or Diagonal cascade, the screen is not tilted. The whole device is rotated 12 degrees in the plane, so it still counts as a rectangle.

The screen does not read as glass (glass glare)

With no light caught in the glass, the screen reads as print rather than a display. The reflection is built from two layers: a crisp one running at 155 degrees and a soft one at 135 degrees, at opacities of 0.07 and 0.06. Both stay under 10 percent. The two layers are combined with a screen blend.

Splitting the reflection in two follows the idea that a real glass reflection is not a single sheet of light (inference). Keeping the opacity low is meant to stop the reflection from hiding the content of the screen (inference). Neither sentence has a basis in the code, so both are the author's reading rather than fact.

The glare is switched with the checkbox in the finishing panel. It starts on everywhere except the two formats built around browser chrome, Browser window and Browser + phone, which both start with it off. The window chrome in those two is drawn in code rather than photographed, so a film of glass laid over it sits oddly on the surface. The preset code records that same reason in a comment (inference: a comment is the author's stated intent, not a value you can confirm from behavior). If the screen looks too shiny, unchecking that box is the only control you have. There is no way to change the angle or the strength of the reflection.

Like the depth ring, the glare is applied only when the screen is computed as a rectangle. The path that warps a screen into a quadrilateral gets no reflection. No format uses that path right now, so with the box checked you get a reflection in every format available today.

The whole image is too clean (canvas wide grain)

Even with every layer in place, the image can still read as artificial. Grain does not belong to a device. It is a separate overlay laid across the whole canvas once every device has been drawn. A digital image is uniform to a degree that reads as artificial, and a light noise breaks that uniformity.

The texture is a 256 pixel tile generated with the SVG fractalNoise filter, at a base frequency of 0.8 over two octaves, repeated across the canvas and composited with soft light. The default strength is 0.08. The slider runs to 100 percent, but the render opacity is clamped at 0.2. Past 20 percent the image stops changing. If you push the slider to the end and nothing moves, that clamp is the reason, not a fault.

What this service does not support

The three items below do not appear in your image. This is not a note about work in progress. It means you cannot make them with this editor today. If your mockup needs one of them, you have to solve it outside this editor.

The ground shadow under the device

No shadow is drawn under a device. The default shadow strength is fixed at 0, and a strength of 0 returns before anything is drawn. Every format preset carries the same value, and reopening a document from an earlier session resets it to 0 as well. The finishing panel has no shadow slider, so there is no way to raise it either.

The design of the layer is still in the code. A rectangle inset from the body of the device by 4 percent of the short edge carries a stack of four shadows at different blurs and opacities, so the frame covers the hard edge and only the blurred part spills out. It was pulled because at certain angles and aspect ratios the frame image failed to cover that rectangle, and the result read as a black card behind the device rather than a shadow.

If you need a shadow now, the only route is to add one to the downloaded image in another tool. Choosing a darker solid or gradient background also softens the boundary between the device and the background, which helps as a stopgap.

A hand holding the device (foreground mask)

A composite where a hand holds the device needs a foreground layer with fingers crossing over the screen. This service has no code that draws it. The frame data defines an optional slot for a foreground mask, and no component in the canvas folder renders one. Reserving a slot and shipping a feature are two different things.

The format list has no format with a hand holding the device either. All 18 formats in the list place their devices front facing.

Tilting the device and the tilted warp

No format in the list shows a device tilted at an angle, because there are no frame images rendered from an angle.

The code that warps a screen into a quadrilateral does exist, in the perspective projection maths and the bezel drawn for tilted devices. No format preset uses that path, so it is never called. No frame carries a pre rendered left or right perspective image either. Every device you can build in this editor today is front facing.

Diagonal stagger and Diagonal cascade look like perspective, but they are plane rotations. The devices sit at 12 degrees, the screen stays a front facing rectangle, and that is why the depth ring and the glare still apply to them. Real perspective has to be added to a front facing export in another tool.

What matters for all three is that they do not work today. The value behind each state is listed one row at a time in the current support scope table at the end.

What you can adjust yourself

The list below is everything you can change in the editor. It is also the limit of what you can do about a mockup that looks wrong.

Finishing: two controls

The finishing panel holds a grain slider and a glass glare checkbox, and nothing else. Grain runs from 0 to 100 percent and starts at 8 percent, and as noted above it stops changing anything past 20 percent. Glare is on or off, with no strength to set. There is no shadow control in this panel.

Background: four kinds

The background panel offers gradient, solid, image, and transparent. Solid takes one color. Gradient takes a start color, an end color, and an angle from 0 to 360 degrees, starting at 135. Choosing image opens a file picker that accepts PNG, JPG, and WebP. Transparent leaves the background empty when you export to PNG or WebP.

18 formats

Single, Multi-device, Responsive (3), Diagonal stagger, Repeating grid, Diagonal cascade, Phone trio, Flat-lay and Browser window, plus Tablet trio, Desktop, Full lineup, Laptop duo, Browser + phone, Tablet + phone, Mixed phone trio and Diagonal grid 1 and 2 added in August 2026, for 18 formats in total. All 18 buttons in the list apply the moment you press them.

Repeating grid also exposes a count of 3, 6, 9, or 12 and a gap control. Diagonal stagger and Diagonal cascade use fixed coordinates, so they take neither. Formats with a phone slot let you switch the phone type between the notch and Android frames, and that choice applies to phone slots only, leaving tablets and laptops as they are.

Devices: six frames and per device controls

The device panel adds Phone (notch), Phone (Android), Laptop, Tablet, Desktop, and Browser window to the canvas. The bezel free flat screens used inside presets are not on that list.

Select a device and you can set its corner radius from 0 to 120 pixels, then lock, duplicate, reorder, or delete it. Rotation runs in 45 degree steps, and with nothing selected the buttons rotate everything. A device dragged off the canvas comes back with the centering button. Dragging also raises alignment guides against the other devices and the center of the canvas.

Export

Pick PNG, JPG, or WebP, and a scale from 1x to 4x. The transparent background checkbox is disabled for JPG only. Without transparency you choose the color that fills the background, and JPG and WebP add a quality setting from 50 to 100 percent. The result downloads as a file or goes to the clipboard.

Any control not listed above is not in the editor. If you went looking for a shadow slider and could not find it, this list being the whole set is the reason, not a rendering problem.

When the preview and the downloaded file differ

The editor and the download share the same canvas, but they are not identical. Two things differ.

First, the export hides the editing tool layers. The selection handles and alignment guides you saw on screen never reach the result. Exporting on a transparent background hides the background layer as well.

Second, the resolution differs. The on screen render caps the pixel ratio at 2x. On a high density display, redrawing a large canvas on every change would cost memory and speed. The final resolution is set separately by the export scale.

When a 4x export still looks soft

An uploaded image is scaled down to a long edge of 2000 pixels before you work with it. That keeps memory use in check during editing. So exporting at 4x does not bring back the original resolution of your screenshot.

Export scales run from 1x to 4x. Uploads accept PNG, JPG, and WebP at up to 25MB per file.

External fact: browser canvas limits

The ceiling on canvas size is set by the browser engine, not by our code. WebKit, the engine behind Safari, caps area rather than edge length, and this service tests area the same way while applying the 2015 value of 16,777,216 as its safe floor. The history of that cap, the primary sources W1, W2, and W3, and the calculated table of output sizes per scale are all in the article below.

Read next

Can you use the download commercially

The frames are generic designs with manufacturer wordmarks removed. Anything you download from the editor is yours to use, commercial work included.

Attribution for the original frame artwork and a Korean intellectual property review are still in progress. The license and credits page carries the current terms.

Current support scope

The states described in the section on what is not supported are gathered here. The reasons and the workarounds live in that section. This table carries only the value that produces each state, so it is the first thing to change when the code does.

State today, read from the code
ItemState todayThe value behind it
Ground shadow under the deviceNever drawnThe default strength constant is 0, and a strength of 0 returns before the render. No preset overrides it, and a restored session is normalized back to 0.
Shadow slider in the finishing panelAbsentThe slider block is commented out, so it never renders. The code was kept in place in case the control returns.
Foreground mask, the layer where a hand covers the screenNo render codeThe frame data defines an optional slot for it, and no component in the canvas folder draws one.
Formats with a hand holding the device or a tilted deviceNot in the listEvery slot in the 18 format presets is front facing. With no hand photos and no angle renders, neither kind of format is offered.
Tilted warp, quadrilateral screens and the tilt bezelNever calledThe projection maths and the bezel exist, but no preset uses that path. Every preset slot is front facing.
Left and right perspective frame imagesNoneNo frame in the frame data defines an angle variant. Every frame carries a single front facing image.
How to read the markers in this article
Kind of basisMarkerWhat it means
Confirmed in codeno markerThe evidence table names the file and constant
Reading with no basis in code(inference)The author's explanation, not a verified fact
External factown sectionSet by browser vendors, so our code cannot confirm it

What this article is based on

What this article is based on
StatementWhere it comes from
What actually reaches the canvas per device: screenshot, depth ring, frame art, glass glarethe components canvas/DeviceNode.tsx renders (GroundShadow, ScreenshotRect/ScreenshotQuad, InsetRing, FrameArt, GlareLayer, TiltBezel), narrowed to the ones that produce output
The foreground mask has no render code, only a reserved fieldthe optional foregroundMask field in frames/frameTypes.ts, no matching component in canvas/, and no frame in frames.data.ts defining it
Grain is a canvas wide overlay, not a device layercanvas/EditorStage.tsx, inside Layer and outside DeviceNode, plus canvas/GrainOverlay.tsx
The shadow is inset by 4 percent of the short edge, with four stacked shadowscanvas/GroundShadow.tsx, editorConstants.SHADOW_STACK
The ground shadow is disabled, fixed at 0 with an early returneditorConstants.DEFAULT_SHADOW = 0, the strength <= 0 early return in GroundShadow, the fixed value across every preset, and normalization to 0 on session restore
The finishing panel has no shadow slider, the block is commented outthe commented SliderRow block in panels/FinishPanel.tsx
Finishing exposes exactly two controls, the grain slider and the glare checkboxthe render tree of panels/FinishPanel.tsx
Four background kinds, gradient angle from 0 to 360 degreesKINDS in panels/BackgroundPanel.tsx, editorConstants.DEFAULT_GRADIENT_ANGLE
18 formats, all applying the moment you press themPRESETS in presets/presets.data.ts: 18 entries, every status 'active'
No format with a hand holding the device or a tilted device is listedno preset in presets/presets.data.ts uses formatId 'handheld' or 'device-tilt' (both names remain unused in the FormatId type in state/types.ts)
The tilted warp path is never calledno slot in presets.data.ts carries tilt, and the header comment in engine/tiltQuads.test.ts records the bare plus tilt branch as unreached
No frame defines an angle variantframes/frames.data.ts, where no frame sets angles, and the front facing fallback in frameTypes.screenForAngle
Only Repeating grid exposes count and gap, counts of 3, 6, 9, 12, plus the phone type segmentGRID_PRESETS, COUNTS, and PHONE_FRAME_CHOICES in panels/FormatPanel.tsx
Six selectable device frames, bezel free flat screens excludedSELECTABLE_FRAMES in frames/frameRegistry.ts, active and chrome not bare
Corner radius from 0 to 120 pixels, rotation in 45 degree steps, centeringSliderRow, rotateSelected, and centerNodes in panels/DevicePanel.tsx
The slant in Diagonal stagger and Diagonal cascade is a 12 degree plane rotationrotation: -12 in presets.data.ts, which is not tilt
The behind or over decision and the reversed render orderscreenLayer in frames.data.ts, the branch in DeviceNode.tsx
Depth ring and glare apply to front facing rectangles onlythe rectPx null branch in DeviceNode.tsx
The depth ring is a black 40 percent stroke at 0.4 percent of the short edge, floored at 1px, blurred by 2 percentcanvas/InsetRing.tsx
Glare at 155 and 135 degrees, opacities 0.07 and 0.06, screen blendGLARE in frames.data.ts, canvas/GlareLayer.tsx
The two browser chrome formats, Browser window and Browser + phone, are the ones that start with glare offfinish({ glare: false }) on browser-window and on browser-phone in presets.data.ts. Every other preset calls finish() with no argument, which defaults to glare: true. Those two are the only glare: false occurrences in the file
Grain uses fractalNoise, a 256px tile, base frequency 0.8 over two octaves, soft light, default 0.08, clamped at 0.2canvas/GrainOverlay.tsx, editorConstants.DEFAULT_GRAIN
Empty slots show a dashed outline and an upload promptcanvas/ScreenshotRect.tsx, editorConstants.EMPTY_SLOT_FILL/STROKE/TEXT
The Browser window frame art is drawn in code rather than loaded as an imagethe chrome === 'browser' branch in canvas/FrameArt.tsx, canvas/BrowserChrome.tsx
The export hides the editing tool layersengine/exportImage.ts
The on screen render caps the pixel ratio at 2xeditorConstants.KONVA_MAX_PIXEL_RATIO, canvas/EditorStage.tsx
The working bitmap is capped at a 2000px long edgeeditorConstants.WORK_MAX_EDGE, engine/uploadImage.ts
Scales 1x to 4x, uploads up to 25MB, PNG, JPG, and WebP, quality 50 to 100 percent on JPG and WebPeditorConstants.EXPORT_SCALES, MAX_UPLOAD_BYTES, ACCEPTED_IMAGE_MIME, panels/ExportPanel.tsx
Compositing and export finish inside the browser, with nothing uploadedcreateImageBitmap in engine/uploadImage.ts, toCanvas then canvas.toBlob in engine/exportImage.ts (no fetch or transfer code anywhere in features/editor)
Frames have wordmarks removed, attribution is required, and the IP review is in progressMETA in frames.data.ts
The canvas area limit the app applies, 16,777,216editorConstants.SAFARI_MAX_AREA (the value comes from W1 and W3, not from our code)
External fact: the canvas limit is set by the browser vendor, not by our codeW1 · W2 · W3 (the change history and the comparison against the primary sources are in the export-resolution guide)
Why the glare is split in two, why the opacities are low, why the depth ring is kept small, and why the two browser chrome formats start with glare off(inference), no basis in code

Related guides