Skip to content
On this page

Eshop product viewer

An e-shop 3D product viewer is a feature that allows online shoppers to interact with and view a product in 3D on an e-commerce website. It allows users to rotate and zoom in on the product, giving them a more realistic and detailed view of the item. This can be helpful in making purchasing decisions and can also improve the overall customer experience on the website.

We utilize a <GLTFLoader> to load a chair model. A simple variant picker is controlling the color of the chair fabric.

In this example, the scene consists of

  • single perspective camera
  • orbit controls
  • GLTF loader


<div class="eshop-product-viewer">
  <div class="renderer">
    <Renderer :antialias="true">
      <PerspectiveCamera :position="[0, 2, 2]">
      <Scene background="#f9f9f9">
        <AmbientLight :position="[0, 0, 10]" :intensity="1" />
          :scale="[2, 2, 2]"

  <!-- The variant picker -->
  <div class="options">
  <!-- Clicking color variant will trigger mesh material color change -->
      v-for="(variant, i) in variants"
      :class="{active: ===}"
      class="option" :style="`background: ${variant.color};`"
import { Renderer, Scene } from "@janvorisek/drie";
import { GLTFLoader, AmbientLight } from "@janvorisek/drie";
import { PerspectiveCamera, OrbitControls } from "@janvorisek/drie";

import { ref, onMounted } from "vue";

// reference to the GLTFLoader component
const model = ref(null);

// Variants for the color picker
const variants = [
    name: 'Red sofa',
    color: 'red'
    name: 'Yellow sofa',
    color: '#e6e600'
    name: 'Green sofa',
    color: 'green'

// reference to the active variant
const activeVariant = ref(variants[0]);

// method called by clicking the color button
const setVariant = (i) => {
  activeVariant.value = variants[i];

// method called when glTF loaded and whenever color variant is pressed
const onLoad = () => {
  if(model.value === null) return;
  // In our case the fabric mesh has a name 'SheenChair_fabric' (in the glTF file)
  // fabricMesh is instance of THREE.Mesh
  const fabricMesh = model.value.three.children[0].children.find(m => === 'SheenChair_fabric');

  // fabricMesh.material is instance of THREE.Material
  .eshop-product-viewer {
    position: relative;
    width: 320px;
    height: 320px;
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid #ccc;

  .eshop-product-viewer .renderer {
    width: 100%;
    height: 100%;
  .eshop-product-viewer .options {
    position: absolute;
    top: 12px;
    right: 12px;

  .eshop-product-viewer .option {
    border-radius: 6px;
    width: 32px;
    height: 32px;
    margin-bottom: 6px;

  .eshop-product-viewer .option:hover {
    cursor: pointer;

  .eshop-product-viewer {
    border: 2px solid black;
    box-shadow: 0 0 4px rgba(0,0,0,0.25);

Released under the MIT License.