https://framer.com/m/ModelViewer3d-lCbsvJ.js

Io / Enhancements / ModelViewer3d

ModelViewer3d

ModelViewer3d puts a glTF model in the page and lets the reader turn it. One file, five looks — textured, clay, wireframe, hologram or normals — with background, clay, wire and glow read from the theme tokens.

Enhancements57 controlsglTF / glbhotspotsrefines when still
Enhancements9 controlsWebGL pointsthree data modes

Examples

Nine live specimens: eight read the same glb hosted in this project, and one is left without a model to show the placeholder.

Display modes

mode draws the same file five ways. Textured keeps the model’s own materials; Shaded replaces them with one clay colour; Wireframe lays the edges over that clay; Hologram is an additive fresnel shell; Normal maps surface direction to colour.

Textured

Add a .glb file or model URL

Shaded

Add a .glb file or model URL

Wireframe

Add a .glb file or model URL

Hologram

Add a .glb file or model URL

Normal

Add a .glb file or model URL

Hologram

Hologram forces bloom on. hologram sets the shell colour and fresnel decides how hard the rim burns, while alpha and intensity set how solid it reads. The scanline sweeps at speed, in bands of density and width.

fresnel 5 · bloom 1.4 · density 12

Add a .glb file or model URL

Camera and ground

azimuth and elevation park the camera, fov picks the lens and framing decides how much air is left around the model. shadow drops a contact shadow and grid draws a ground plane; both take a theme token for their colour. refine then supersamples the frame and softens those shadows once the view comes to rest — which is what rotateFor and stopOnDrag are for, since a still view is what it needs.

azimuth 120° · elevation 40° · fov 22 · grid on · shadow 1.6

Add a .glb file or model URL

Hotspots

hotspots pins design-system Buttons to a bone or named node in the glb, so they follow the pose and any animation; an empty node means the model centre. Each item sets its text, icon and align, and hotspotButton is the real Button panel for their style. hideBehind fades the ones on the far side. A click only fires an event: onHotspotClick and the window event modelviewer:hotspotclick, carrying eventId as viewerId.

1 hotspot · model centre · icon Info · align Above · layer In component

Add a .glb file or model URL

Placeholder

placeholder sets what shows before the model draws: an optional poster, the Empty, Loading {p}% and Error texts, and a bar or ring tracking the download, which fades out once the first frame lands. Text and indicator colours follow the theme. This specimen has no model, so it holds the Empty state.

No model · Empty text set · Text size Callout · Position Center

No model yet: drop in a .glb or paste a URL

Props

All 57 controls on the instance panel. Rows that say “Needs …” only appear once that switch is on.

PropTypeBehaviour
modelFilefileThe .glb or .gltf to draw, uploaded into the project. Takes priority over the URL.
modelUrlstringA hosted .glb, used when no file is uploaded.
placeholderobjectBefore the model draws: a poster, Empty / Loading {p}% / Error texts, a bar or ring that fades out.
displayModeenumTextured, Shaded, Wireframe, Hologram or Normal — one file, five looks.
backgroundcolorPanel behind the model. Empty follows the theme; Hologram wants a dark one.
clayColorcolorThe white-model colour used by Shaded and Wireframe.
wireColorcolorEdge colour in Wireframe.
wireOpacitynumberHow strongly the edges sit over the clay. 0–1, default 0.35.
holoColorcolorShell colour in Hologram. Empty reads --holo-color.
holoIntensitynumberBrightness of the shell. 0–3, default 1.
holoAlphanumberHow solid the shell reads. 0–1, default 0.9.
holoFresnelnumberHow hard the rim burns. 0.5–6, default 1.5.
holoScanbooleanSweeps scanlines through the shell.
holoScanSpeednumberScanline sweep speed. Needs Scanline on.
holoScanDensitynumberHow many scan bands. 0.5–40, default 2.
holoScanWidthnumberThickness of each band. 0.02–1, default 0.2.
bloombooleanAdds a bloom pass. Hologram forces it on.
bloomStrengthnumberBloom amount. 0–3, default 0.8. Needs Bloom on.
bloomRadiusnumberHow far the bloom spreads. Needs Bloom on.
bloomThresholdnumberHow bright a pixel must be before it blooms.
exposurenumberTone-mapping exposure. 0–3, default 1.
envIntensitynumberStrength of the room environment light.
toneMappingenumACES · Neutral · AgX. Neutral keeps product colours true. Hologram mode ignores it.
fovnumberCamera lens, 15–75°. Lower reads flatter.
azimuthnumberStarting turn of the camera, −180…180°.
elevationnumberStarting height of the camera, −20…80°.
paddingnumberAir left around the model. 1 is tight, 3 is loose.
autoRotatebooleanTurns the model until the reader grabs it.
rotateSpeednumberAuto-rotate speed. Needs Rotate on.
rotateFornumberSeconds of auto-rotation before it stops; 0 never stops. Refine only works on a still view.
stopOnDragbooleanStops the auto-rotation for good once the reader drags the model.
enableZoombooleanLets the wheel zoom the camera.
enablePanbooleanLets a drag move the model off centre. Off by default.
shadowbooleanContact shadow under the model.
shadowColorcolorShadow colour. Takes a theme token.
shadowStrengthnumberShadow opacity. 0–2, default 1.
refinebooleanSupersamples the frame and softens the shadows once the view stops moving.
softShadownumberHow far those shadows are softened when it does, 0 to 1.
gridbooleanDraws a ground plane under the model.
gridColorcolorGrid line colour. Takes a theme token.
playAnimationbooleanPlays the animation clips inside the file.
clipIndexnumberWhich clip to play. Needs Animation on.
hotspotsarrayButtons pinned to a bone or node (empty = model centre) that follow the pose: text, icon and align each.
hotspotButtonobjectThe hotspot style: the design-system Button's own panel, reused as is.
hotspotHideBehindbooleanFades hotspots on the far side of the model. Default on.
hotspotLayerenumPage top keeps hover and click working under other layers; In component stays inside the viewer.
hotspotZnumberZ-index of the page-top layer, default 10; lower it if hotspots cover the nav. Needs Layer Page top.
eventIdstringSent as viewerId with every hotspot click, to tell several viewers on one page apart.
onLoadeventFires once the model has finished loading.
onHotspotClickeventFires on a hotspot click with viewerId, index, node, text, trigger; also as modelviewer:hotspotclick.
scrollDrivenbooleanHands the camera to the scroll schema instead of the panel's azimuth and elevation.
schemaJSONstringScroll pose engine plus an optional hotspots list. Generated with the modelviewer-scroll-schema skill.
smoothnumberSmoothing between scroll keyframes.
betweenenumWhich scroll range the keyframes are measured against.
animModeenumHow a GLB's own animation is driven — on its own clock, or scrubbed by scroll.
previewKeystringPose key held while editing on the canvas, so you can see one keyframe without scrolling.
showHUDbooleanShows the Pose HUD readout, which is how you capture camera values for the schema.
PropTypeBehaviour
modelFilefileThe .glb or .gltf to draw, uploaded into the project. Takes priority over the URL.
modelUrlstringA hosted .glb, used when no file is uploaded.
placeholderobjectBefore the model draws: a poster, Empty / Loading {p}% / Error texts, a bar or ring that fades out.
displayModeenumTextured, Shaded, Wireframe, Hologram or Normal — one file, five looks.
backgroundcolorPanel behind the model. Empty follows the theme; Hologram wants a dark one.
clayColorcolorThe white-model colour used by Shaded and Wireframe.
wireColorcolorEdge colour in Wireframe.
wireOpacitynumberHow strongly the edges sit over the clay. 0–1, default 0.35.
holoColorcolorShell colour in Hologram. Empty reads --holo-color.
holoIntensitynumberBrightness of the shell. 0–3, default 1.
holoAlphanumberHow solid the shell reads. 0–1, default 0.9.
holoFresnelnumberHow hard the rim burns. 0.5–6, default 1.5.
holoScanbooleanSweeps scanlines through the shell.
holoScanSpeednumberScanline sweep speed. Needs Scanline on.
holoScanDensitynumberHow many scan bands. 0.5–40, default 2.
holoScanWidthnumberThickness of each band. 0.02–1, default 0.2.
bloombooleanAdds a bloom pass. Hologram forces it on.
bloomStrengthnumberBloom amount. 0–3, default 0.8. Needs Bloom on.
bloomRadiusnumberHow far the bloom spreads. Needs Bloom on.
bloomThresholdnumberHow bright a pixel must be before it blooms.
exposurenumberTone-mapping exposure. 0–3, default 1.
envIntensitynumberStrength of the room environment light.
toneMappingenumACES · Neutral · AgX. Neutral keeps product colours true. Hologram mode ignores it.
fovnumberCamera lens, 15–75°. Lower reads flatter.
azimuthnumberStarting turn of the camera, −180…180°.
elevationnumberStarting height of the camera, −20…80°.
paddingnumberAir left around the model. 1 is tight, 3 is loose.
autoRotatebooleanTurns the model until the reader grabs it.
rotateSpeednumberAuto-rotate speed. Needs Rotate on.
rotateFornumberSeconds of auto-rotation before it stops; 0 never stops. Refine only works on a still view.
stopOnDragbooleanStops the auto-rotation for good once the reader drags the model.
enableZoombooleanLets the wheel zoom the camera.
enablePanbooleanLets a drag move the model off centre. Off by default.
shadowbooleanContact shadow under the model.
shadowColorcolorShadow colour. Takes a theme token.
shadowStrengthnumberShadow opacity. 0–2, default 1.
refinebooleanSupersamples the frame and softens the shadows once the view stops moving.
softShadownumberHow far those shadows are softened when it does, 0 to 1.
gridbooleanDraws a ground plane under the model.
gridColorcolorGrid line colour. Takes a theme token.
playAnimationbooleanPlays the animation clips inside the file.
clipIndexnumberWhich clip to play. Needs Animation on.
hotspotsarrayButtons pinned to a bone or node (empty = model centre) that follow the pose: text, icon and align each.
hotspotButtonobjectThe hotspot style: the design-system Button's own panel, reused as is.
hotspotHideBehindbooleanFades hotspots on the far side of the model. Default on.
hotspotLayerenumPage top keeps hover and click working under other layers; In component stays inside the viewer.
hotspotZnumberZ-index of the page-top layer, default 10; lower it if hotspots cover the nav. Needs Layer Page top.
eventIdstringSent as viewerId with every hotspot click, to tell several viewers on one page apart.
onLoadeventFires once the model has finished loading.
onHotspotClickeventFires on a hotspot click with viewerId, index, node, text, trigger; also as modelviewer:hotspotclick.
scrollDrivenbooleanHands the camera to the scroll schema instead of the panel's azimuth and elevation.
schemaJSONstringScroll pose engine plus an optional hotspots list. Generated with the modelviewer-scroll-schema skill.
smoothnumberSmoothing between scroll keyframes.
betweenenumWhich scroll range the keyframes are measured against.
animModeenumHow a GLB's own animation is driven — on its own clock, or scrubbed by scroll.
previewKeystringPose key held while editing on the canvas, so you can see one keyframe without scrolling.
showHUDbooleanShows the Pose HUD readout, which is how you capture camera values for the schema.

Usage

Guidance carried over from the component definition.

Reach for ModelViewer3d

A product, part or prop should be inspectable rather than photographed.

One glb has to carry several looks — a clay study and a finished render.

The model must sit on the page’s own colours instead of a baked backdrop.

The object should keep turning on its own, and stop when the reader grabs it.

Parts of the model need labelled, clickable callouts that follow its pose and animation.

Reach for something else

The subject is a diagram or an ordered stack — SolarIso draws that as line art.

The page wants a globe or cloud of points rather than a mesh — this renders glTF geometry only.

The device cannot be asked to run WebGL, or a still image would say the same thing.

Io — Enhancements

Every specimen above is a live component instance; eight share one glb hosted in this project and one has no model. Background, clay, wire, glow, shadow and grid resolve from the project theme tokens.

io

An experiment in what a design system becomes when AI can consume it.

© 2026 io

Contact me

Create a free website with Framer, the website builder loved by startups, designers and agencies.