3D Product Previews
The 3D product preview is a feature that allows you to display a 3D model of a product in your application. This is a great way to give your customers a better understanding of the product they are purchasing. The 3D preview interface has been designed to be configurable and customizable to fit your needs. We provide a 3D solution out of the box, but you can also use your own 3D solution. As long as your solution adheres to the interface that we have built any 3D solution suitable for the web can be plugged into a workflow experience. Read further to learn more about the interface and how you use it.
Using the Spiff Commerce 3D solution
Our in-house solution for 3D is published as a convenient npm package that you can plug straight into our platform. This solution adheres to the ThreeDPreviewService
interface just as any bespoke solution would. The only difference being that you don't have to build it yourself.
yarn add @spiffcommerce/preview@latest
Injecting a Workflow Experience into the preview service
Once you have your reference to the preview service, you can also inject an existing workflow experience into the preview service. This is useful if you have a workflow experience that you have already loaded and want to use the preview service with it. Workflow experiences can only be injected into one preview service at a time.
This can be achieved by calling injectIntoPreviewService
on the workflow manager of the workflow experience.
When you're done with a particular workflow experience you can remove it from the preview service by calling the ejectFromPreviewService
method.
import { SpiffCommerce3DPreviewService } from "@spiffcommerce/preview";
// COnstruct the preview service, this should generally be singleton.
const previewService = new SpiffCommerce3DPreviewService();
// Inject a workflow experience into the preview service.
await workflowExperience.getWorkflowManager().injectIntoPreviewService(previewService);
// To know when to render there are two components to await. The preview load and the model load.
await Promise.all([
previewService.getInitializationPromise(),
workflowExperience.getWorkflowManager().getModelContainer()?.getInitializationPromise(),
]);
// Once the load is complete you can frame and animate to the desired position.
previewService.animateToLastCameraFocus();
// Later...
// Eject a workflow experience from the preview service.
workflowExperience.getWorkflowManager().ejectFromPreviewService();
Model Animations
In order to play animations on a loaded model, you'll need to get a reference to a ModelContainer
instance. There are a few ways you can do this:
const modelContainer = workflowExperience.getWorkflowManager().getModelContainer();
You can use the getAnimations()
function on a loaded ModelContainer
to retrieve a list of available animations.
This function will return an empty array if the model has not been loaded yet.
interface ModelAnimation {
name: string;
from: number;
to: number;
loop: boolean;
}
// If you pass true to this function, the returned array will include animations for all loaded variants.
const animations: ModelAnimation[] = modelContainer.getAnimations(false);
You can use the executeAnimation()
function on a loaded ModelContainer
to play an animation. If you are already aware of the animation parameters prior to the model loading, you can safely call this function and the animation will be played once the model has loaded.
All fields on the input object are optional.
modelContainer.executeAnimation({
name: "animationName", // If this is not provided, all animations will be played
from: 0, // Defaults to the first frame of the animation
to: 1, // Defaults to the end of the animation
loop: true, // Defaults to the animation's loop property
});
Enabling material highlighting
To enable material highlighting, and event hooks for when a material is hovered over, you can pass the following options to the preview service:
const previewService = new SpiffCommerce3DPreviewService({
highlightOnMaterialHover: true,
highlightColor: "#ff0000", // Defaults to #fafafa
});
Once you have retrieved a reference to a modelContainer, you can then use the registerMaterialSelectedCallback
and unregisterMaterialSelectedCallback
functions to register callbacks for when a material is hovered over.
const materialSelectedCallback = (materialHandle: MaterialHandle) => {
const {
id, // Raw material id.
name, // Human readable material name.
} = materialHandle;
// Do something with the material handle.
};
modelContainer.registerMaterialSelectedCallback(materialSelectedCallback);
// Later on...
modelContainer.unregisterMaterialSelectedCallback(materialSelectedCallback);