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
Code
template
<div class="eshop-product-viewer">
<div class="renderer">
<Renderer :antialias="true">
<PerspectiveCamera :position="[0, 2, 2]">
<OrbitControls
:target="[0,0.5,0]"
:enable-pan="false"
:min-distance="1"
:max-distance="5"
/>
</PerspectiveCamera>
<Scene background="#f9f9f9">
<AmbientLight :position="[0, 0, 10]" :intensity="1" />
<GLTFLoader
ref="model"
url="https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/master/2.0/SheenChair/glTF-Binary/SheenChair.glb"
:scale="[2, 2, 2]"
@load="onLoad"
/>
</Scene>
</Renderer>
</div>
<!-- The variant picker -->
<div class="options">
<!-- Clicking color variant will trigger mesh material color change -->
<div
v-for="(variant, i) in variants"
@click="setVariant(i)"
:class="{active: variant.name === activeVariant.name}"
class="option" :style="`background: ${variant.color};`"
:title="variant.name"
></div>
</div>
</div>
ts
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];
onLoad();
}
// 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 => m.name === 'SheenChair_fabric');
// fabricMesh.material is instance of THREE.Material
fabricMesh.material.color.set(activeVariant.value.color)
}
css
<style>
.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 .option.active {
border: 2px solid black;
box-shadow: 0 0 4px rgba(0,0,0,0.25);
}
</style>