npm.io
0.1.0 • Published yesterday

screenframe3d

Licence
MIT
Version
0.1.0
Deps
0
Size
2.5 MB
Vulns
0
Weekly
0

Screenframe3D

Composite an app screenshot onto a real 3D phone. Live demo.

Phone GLBs are not included in the npm package (Sketchfab licenses). You download a model once, drop it in public/models/, and Screenframe does the rest. First-party devices are planned.

Install

npm install screenframe3d three

React apps also need react / react-dom. Vite apps should add the plugin below so the HDRI (and later, posters) land automatically.

1. Get a device model from Sketchfab

device is a path. Screenframe loads /models/{device}.glb from your site.

Device device id Put the file at Sketchfab
iPhone 5s apple/iphone-5s public/models/apple/iphone-5s.glb IPhone 5s by Eternal Realm (CC-BY-4.0)
iPhone 12 Pro apple/iphone-12-pro public/models/apple/iphone-12-pro.glb iPhone 12 Pro by DatSketch (CC-BY-4.0)
iPhone 14 Pro apple/iphone-14-pro public/models/apple/iphone-14-pro.glb No single listing is embedded in the file. Search downloadable iPhone 14 Pro models. You want a body_mat (or similar) whose emissive map includes a bright portrait screen.
iPhone 17 Pro apple/iphone-17-pro public/models/apple/iphone-17-pro.glb Iphone 17 pro by Ibrahim.Bhl (CC-BY-4.0)
Download steps
  1. Make a free Sketchfab account.
  2. Open the model. Confirm it is downloadable and that the license fits your project (CC-BY requires credit).
  3. Download 3D modelglTF (or GLB if offered).
  4. If you get a folder, use the .glb (often scene.glb). If you only get scene.gltf + scene.bin + textures/, keep that folder structure or convert to a single .glb.
  5. Rename / move it to the path in the table. The filename must match device exactly: apple/iphone-12-promodels/apple/iphone-12-pro.glb.
What Screenframe looks for on the glass

Any downloadable phone can work if Screenframe can find the display:

  • A material or mesh named screen, wallpaper, Screen_BG, display, or lcd, or
  • A material named body_mat whose emissive map has a bright portrait rectangle (atlas).

The four rows above are the combinations this repo is tested against. Catalog in code: DEVICES from screenframe3d.

2. Environment map (glass and metal)

Reflections use /env/greenwich_park_1k.hdr by default (Greenwich Park, CC0, Poly Haven).

The Vite plugin copies that file into public/env/ when it is missing. Without the plugin, download the 1K HDR and save it as public/env/greenwich_park_1k.hdr.

import { defineConfig } from 'vite';
import { screenframe } from 'screenframe3d/vite';

export default defineConfig({
  plugins: [screenframe()],
});

That plugin:

  • Copies the bundled HDRI into public/env/
  • Writes extracted device textures to public/textures/ on first run
  • Captures a still (poster) so the next load can show an image before WebGL is ready

It does not download Sketchfab models.

4. Use it

Vanilla
<div id="device"></div>
<script type="module">
  import { initDeviceShowcase } from 'screenframe3d';

  initDeviceShowcase({
    container: document.getElementById('device'),
    screenshot: '/screenshot.png',
    device: 'apple/iphone-12-pro',
    publicBase: import.meta.env.BASE_URL,
  });
</script>
React
import { DeviceShowcase } from 'screenframe3d/react';

<DeviceShowcase
  screenshot="/screenshot.png"
  device="apple/iphone-12-pro"
  publicBase={import.meta.env.BASE_URL}
/>

publicBase matters if the app is not served from / (GitHub Pages, a Vite base, etc.).

Options

Passed to initDeviceShowcase() or <DeviceShowcase />:

Option Description
container DOM node for the canvas (vanilla only)
screenshot URL of the image on the glass (not downscaled)
device Path id, e.g. apple/iphone-12-pro/models/apple/iphone-12-pro.glb
publicBase Prefix for models, env, posters, textures
environment HDRI URL (default /env/greenwich_park_1k.hdr)
fov, zoom, baseTilt Camera / rest pose
tiltEnabled, spring, scrollTilt Pointer and scroll motion
poster false / omit = no still. true / 'auto' = hashed /posters/...webp. Or pass a URL.
cachePoster, cacheDeviceTextures Persist stills and maps during vite dev (needs the plugin)
fallbackCondition, fallbackImage Opt-in static image instead of WebGL

Development (this repo)

npm install
npm run dev      # landing + playground (models already in public/)
npm run build    # library → dist/

Phone GLBs in public/models/ are for the demo only. They are not published to npm.

License

MIT for the library code.

Device models you download remain under their Sketchfab licenses; CC-BY models need attribution. The default HDRI is CC0 (Poly Haven).

Keywords