Skip to content

Fibbl Model Viewer

An element to display a 3D model of product in a special viewer.

This is an expandable element. Read how it handles its styles in the Expandable elements section.

Code example

html
<script
    src="https://cdn.fibbl.com/fibbl.js"
    type="module"
></script>
<fibbl-model-viewer
    data-product-id="@demo-shoe"
    style="width: 300px; height: 300px"
></fibbl-model-viewer>

Custom attributes

TIP

The data- attributes can be overridden via the remote config

  • data-product-id - a unique id of product in Fibbl's databases.
  • data-initial-zoom - a float value from 1 to 2 (it's clamped). By default, it's 1. The value roughly corresponds to the linear size of the model in the viewport relatively to the initial size (which is set automatically, so that the whole model is always visible in the viewport, even if it's rotated).
  • data-initial-rotation - a string with 2 integer values in degrees separated with 1 space, e.g. "15 25". Each number is a rotation around X (right) and Y ( up) axes correspondingly. Z axis points forward. The coordinate system is right-handed, that is, positive rotation is counterclockwise.
  • data-dimensions-visibility - a dynamic prop that can be used to show and hide dimensions. If you want to hide the dimensions, then remove this attribute. If you want to show the dimension, then use one of the following values:
    • visible - the dimensions are always visible;
    • when-expanded - the dimensions are visible only when the model viewer is expanded.
  • data-annotations-visibility - a dynamic prop that can be used to show and hide annotations (if they are present in the model data). If you want to hide the annotations, then remove this attribute. If you want to show them, then set the attribute to visibile.
  • data-ui-config - a JSON object with options. It can be used to hide or reposition certain elements inside the viewer and disable zoom. The object structure is the following:
    ts
    const allowedPositionValues = ['left', 'right', 'left top', 'left bottom', 'right top', 'right bottom'] as const;
    type Position = (typeof allowedPositionValues)[number];
    interface UiConfig {
      'expand-button': boolean | { position: Position };
      'collapse-button': { position: 'left' | 'right' };
      'hint-text': boolean | { position: 'top' | 'bottom' };
      'light-control': boolean;
      zoom: boolean;
      'dimensions-control': boolean | { position: Position }; // works only if model has dimensions
      'annotations-control': boolean | { position: Position }; // works only if model has annotations
    }
    The user-provided config object is merged with the default config, so you can specify only the options you need. The false value hides the corresponding element. We recommend using single quotes for this property in HTML, because inside the JSON you have to use double quotes. An example:
    html
    <fibbl-model-viewer
      data-product-id="@demo-shoe"
      style="width: 300px; height: 300px"
      data-ui-config='{
          "expand-button": { "position": "left top" },
          "collapse-button": { "position": "left" },
          "hint-text": { "position": "bottom" },
          "light-control": false,
          "zoom": false,
          "dimensions-control": true,
          "annotations-control": false
      }'
    ></fibbl-model-viewer>

TIP

The dimensions and annotations controls are shown, only if the dimensions and annotations data has been added to the model. And in the case of annotations, their availability depends on the locale. If there is no data, the controls will not be shown, even if they are enabled via the UI config. The logic is the same as in the case of components themselves - if the model or a certain feature isn't available, the component hides itself.

Custom events

All events are CustomEvents

  • fibbl-load-start - fired when the viewer starts to load the model. The event has no payload.
  • fibbl-load-end - fired when the model has been loaded. The event has no payload.
  • fibbl-dispose - fired when the viewer disposes itself. It happens when the element is removed from the DOM, hidden with display: none, loses the WebGL context and so on. If the element is disposed, but used again, it will reinitialize itself, so the fibbl-load-* events will be fired again. Thus, fibbl-load-* and fibbl-dispose can be fired many times in certain circumstances (e.g. when the component is added and removed from the DOM several times). The event has no payload.

Slots

You can replace certain parts of the element inner markup via slots.

Currently, the following slots can be used:

  • expand-button - allows one to completely replace the expand button (e.g. to use another icon). Note, that the default expand button is exposed for styling (read further).

Example:

html
<script src="https://cdn.fibbl.com/fibbl.js" type="module"></script>

<style>
  .custom-expand {
    margin: 0.5em;
    padding: 0.5em;
    background: orange;
    border-radius: 100px;
  }
</style>

<fibbl-model-viewer
  data-product-id="@demo-shoe"
  style="width: 300px; height: 300px"
  data-ui-config='{ "hint-text": false }'
>
  <div slot="expand-button" class="custom-expand">Expand</div>
</fibbl-model-viewer>

Shadow DOM parts exposed for styling

Using the ::part() pseudo-element you can apply custom styles to the following parts of the shadow DOM:

  • expand-button - the expand button (by default it's located in the top right corner).

You must NOT use styles that rely upon the structure, containers, and the CSS variables of the shadow DOM, because they are not a part of the public API and, once they are changed, your styles may break.

Example:

css
fibbl-model-viewer::part(expand-button) {
  all: unset;
  display: block;
  margin: 5px;
  width: 25px;
  height: 25px;
}

fibbl-model-viewer::part(expand-button):hover {
  transform: scale(1.1);
}

Live demo

See the Pen fibbl-model-viewer by Fibbl (@Fibbl) on CodePen.