Use <model-viewer> to make your models interactive.
This page showcases how you can add hotspots to your scene. Child elements are hotspots if their slot
begins with "hotspot".
The data-position attribute specifies the 3D position of the hotspot in model coordinates, using the same
format as the
camera-target attribute. The data-normal attribute specifies the normal vector defining the "front" of the
hotspot.
When this normal is pointed away from the viewer, the hotspot's opacity becomes --min-hotspot-opacity. The
Editor lets you drag and drop your own models and add hotspots by clicking
and displays the corresponding position and normal attributes which you can copy into your own page.
You can also specify an attribute to be toggled when the hotspot changes between hidden and visible with
data-visibility-attribute.
For example, if you set data-visibility-attribute="visible", then <model-viewer> will toggle the
data-visible attribute on
that hotspot element. This makes it easier to write CSS that styles a hotspot based on its visibility.
When a hotspot's visibility changes, it will dispatch a "hotspot-visibility" event, and
event.detail.visible will be true or false
depending on whether the hotspot is facing the camera.
Add hotspots
This annotation is fixed in screen-space
<style>.hotspot{display: block;width: 20px;height: 20px;border-radius: 10px;border: none;background-color: blue;box-sizing: border-box;pointer-events: none;}.hotspot[slot="hotspot-hand"]{--min-hotspot-opacity: 0;background-color: red;}.hotspot[slot="hotspot-foot"]:not([data-visible]){background-color: transparent;border: 3px solid blue;}.annotation{background-color: #888888;position: absolute;transform:translate(10px, 10px);border-radius: 10px;padding: 10px;}/* This keeps child nodes hidden while the element loads */:not(:defined)>*{display: none;}</style><model-viewerid="hotspot-demo"arar-modes="webxr"camera-controlstouch-action="pan-y"src="../../shared-assets/models/Astronaut.glb"poster="../../assets/poster-astronaut.webp"tone-mapping="aces"shadow-intensity="1"alt="A 3D model of an astronaut."><buttonclass="hotspot"slot="hotspot-visor"data-position="0 1.75 0.35"data-normal="0 0 1"></button><buttonclass="hotspot"slot="hotspot-hand"data-position="-0.54 0.93 0.1"data-normal="-0.73 0.05 0.69"><divclass="annotation">This hotspot disappears completely</div></button><buttonclass="hotspot"slot="hotspot-foot"data-position="0.16 0.1 0.17"data-normal="-0.07 0.97 0.23"data-visibility-attribute="visible"></button><divclass="annotation">This annotation is fixed in screen-space</div></model-viewer>
Animated Hotspots.
Hotspots can follow a point on the surface of an animated model by
specifying the data-surface attribute instead of world-space
position and normal. You can use the surfaceFromPoint
method to get this data-surface string, or even easier, just load
your model in our editor and add the
hotspots there.
Hotspots can be queried to build custom overlays in screen space.
For example, by using an SVG canvas and updating the line nodes we
can draw label standoff lines.
By using WebXR mode, this markup works equally well in AR. Note that
because the text is not part of the 3D rendering it is easier to
read and more accessible.
Hotspots don't have to be on the model; they can be at arbitrary
points in 3D space. Here we demonstrate using hotspots to show a
model's dimensions, entirely styled with CSS. A JavaScript function
is used to automatically set the dimension values by querying the
<model-viewer> element.
Hotspots can be queried to build custom overlays in screen space.
For example, by using an SVG canvas and updating the line nodes we
can draw rudimentary dimension lines. Note that this kind of
extended functionality cannot support occlusion in the 3D scene, as
it always draws on top of the model.
By using WebXR mode, this markup works equally well in AR. Note that
because the text is not part of the 3D rendering it is easier to
read and more accessible.