Prismatic <ml-model> HTML Element
The <ml-model></ml-model>
is an HTML element with inline attributes and CSS styling that allows web developers to easily render 3D content that pops off of the page. You can grab and place the 3D content into your physical environment.
- The width and height of the models are specified with CSS and the breadth of the models is specified via the breadth attribute.
- The position of the model on the x (horizontal) and y (vertical) axes are specified with CSS and the position on the z (out of the browser) axis is specified using the z-offset attribute.
<!-- model at the center of viewport on the x and y axis and 400px forward on the z axes -->
<!-- model has a width of 300px, height of 350px and breadth of 300px -->
<ml-model
id="balloon"
src="/models/balloon.glb"
style="position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
width: 300px; height: 350px;"
breadth="300px"
z-offset="400px">
</ml-model>
Supported File types
The following file types are supported:
- GLB
- FBX
Model Attributes
The <ml-model></ml-model>
HTML element supports attributes to manage or alter a model on an HTML page. These attributes can be set inline or with JavaScript.
src
This is the path to the model file.
src="(path to model)"
<ml-model
src="/models/balloon.glb">
</ml-model>
...
balloon.src = '/models/balloon.glb';
alt-img
This specifies a path to an alternate image used for the model. Use this as a fallback when viewing the page on a non-Prismatic browser or if the model doesn't load.
alt-img="(path to image)"
<ml-model
src="/models/balloon.glb"
alt-img="images/balloon.jpg">
</ml-model>
materials
Specify a kmat path and textures to be applied to a FBX model. Multiple textures can be listed, either with a comma or space separator. The .kmat file tells our engine which resources should be mapped to which textures. See Materials and Textures Guide for more information.
materials="(kmat: path to kmat file; textures: comma or space delimited list of texture paths)"
<ml-model
src="/models/turkey.fbx"
materials="
kmat: models/turkey/turkey.kmat;
textures:
models/turkey/textures/turkey-basecolor.png,
models/turkey/textures/turkey-normal.png">
</ml-model>
...
turkey.materials = 'kmat: models/turkey/turkey.kmat;\
textures: models/turkey/textures/turkey-basecolor.png,\
models/turkey/textures/turkey-normal.png';
visibility
This sets the visibility of a model. Parameters are either visible
or hidden
.
visibility="(visible|hidden)"
<ml-model
id="balloon"
src="/models/balloon.glb"
visibility="hidden">
</ml-model>
...
balloon.visibility = 'hidden';
color
This sets a color overlay on the model. The color value could be of any type of CSS color value.
color="(color value)"
<ml-model
id="balloon"
src="/models/balloon.glb"
color="#FF6347">
</ml-model>
...
balloon.color = '#FF6347';
breadth
This sets the breadth dimension of a model. Provide the breadth value in pixels (default), cm, or mm. When the value is provided in cm or mm, it is converted to pixels. The breadth value does not correspond to a real life dimension.
Models are uniformly scaled by default so the scaling factor will be same for each dimension.
Thefill
attribute could be used to skip this and non-uniformly scale a model.
breadth="(value in pixels, cm, or mm)"
<!-- Create a model with a breadth of 300px, width of 300px and height of 350px -->
<ml-model
id="balloon"
src="/models/balloon.glb"
breadth="300px"
style="width: 300px; height: 350px;">
</ml-model>
...
balloon.breadth = '300px'; //Set breadth of the balloon 300px.
balloon.style.width = '300px'; //Set the width of the balloon 300px.
balloon.style.height = '350px'; //Set the height of the balloon 350px.
fill
Models are uniformly scaled by default. The fill
attribute can be used to skip this and not uniformly scale the model.
When the attribute is true, the model is not uniformly scaled. The scaling factor changes to match each provided dimension. When the attribute is false or not included, the model is uniformly scaled.
fill="(true|false)"
<!-- Model is not uniformly scaled. Scaling factor changes for each dimension to match the dimensions provided. -->
<ml-model
id="balloon"
src="/models/balloon.glb"
style="width: 300px; height: 350px;"
breadth="300px"
fill="true">
</ml-model>
/* Model is not uniformly scaled. Scaling factor changes for each dimension to match the dimensions provided.*/
balloon.fill = true;
balloon.breadth = '300px'; //Set breadth of the balloon 300px.
balloon.style.width = '300px'; //Set the width of the balloon 300px.
balloon.style.height = '350px'; //Set the height of the balloon 350px.
z-offset
This attribute sets the position of the model on the z axes (out of the browser). By default, models are positioned 150px forward on the z axis. Provide the z-offset
value in pixels (default), cm, or mm. When the value is provided in cm or mm, it is converted to pixels. The z-offset value does not correspond to a real life dimension.
z-offset="(value in pixels, cm, or mm)"
<!-- Position model 300px behind the browser, left position to 100px, and top position to 250px-->
<ml-model
id="balloon"
src="/models/balloon.glb"
z-offset="-300px"
style="position: absolute; left: 100px; top:250px; width: 300px; height: 350px;" >
</ml-model>
...
balloon.zOffset = '-300px'; //Set z position to 300px behind the browser
balloon.style.left = '100px'; //Set left position to 100px
balloon.style.top = '250px'; //Set top position to 250px
scale
This attribute applies a static transform scale
on the model. It accepts a scale value for each of the axis as a percentage delimited by a space or a comma.
scale="(x, y, z)"
<!-- Scale down the whale model on the x and y axes to 50% of the specified size. -->
<ml-model
id="whale"
src="/models/whale.fbx"
scale="0.5, 0.5, 0">
</ml-model>
...
//Scale down the whale model on the x and y axes to 50% of the specified size.
whale.scale = '0.5, 0.5, 0';
raycast
The raycast
attribute offers direct interaction with digital content through Raycasting. The raycast events are dispatched when the Head position or the Control's pointer raycast points directly to a node.
Models have raycast
enabled by default. This attribute can be used to disable raycasting on a model.
raycast="(true|false)"
<ml-model
id="balloon"
src="/models/balloon.glb"
raycast="false">
</ml-model>
...
balloon.raycast = false;
extractable
The extractable
attribute is used to allow users to grab 3D models off of the web page and place it in their physical environment. Models are not extractable by default. This attribute must be set to make a model extractable.
Note that models that are placed outside the viewport must have raycast enabled in order for extraction to work. Models have raycast
enabled by default.
extractable="(true|false)"
<ml-model
id="balloon"
src="/models/balloon.glb"
extractable="true">
</ml-model>
...
balloon.extractable = true;
extracted-size
The extracted-size
attribute is used to specify the dimensions of the model in meters once the model is placed in your physical space.
extracted-size="width, height, breadth"
<!-- Model will be resized once extracted to have a width of 0.78 meters, height of 0.9 meters, and breadth of 0.86 meters. -->
<ml-model
id="balloon"
src="/models/balloon.glb"
extractable="true"
extracted-size="0.78, 0.9, 0.86">
</ml-model>
...
//Model will be resized once extracted to have
//width of 0.78 meters
//height of 0.9 meters
//breadth of 0.86 meters.
balloon.extractedSize = '0.78, 0.9, 0.86';
extracted-scale
As an alternative to using extracted-size, you can use the extracted-scale
attribute to specify a multiplier which will scale your model once the model is placed in your physical space.
extracted-scale="(number)"
<!-- Model will be resized once extracted to be 5 time bigger than the size on the web page . -->
<ml-model
id="balloon"
src="/models/balloon.glb"
extractable="true"
extracted-scale="5">
</ml-model>
...
//Model will be resized once extracted to be 5 time bigger than the size on the web page
balloon.extractedScale = '5';
extracted-link
All extracted content link back to its origin page by default when you click on it, even after you have closed the web page. The extracted-link
attribute is used to link your extracted content to a different page.
extracted-link="(URL)"
<ml-model
id="helio"
src="/models/helio.glb"
extractable="true"
extracted-link="magicleaphelio.com">
</ml-model>
...
//Make the helio model extractable
helio.extractable = true;
//Link to the extracted helio model to magicleaphelio.com
helio.extractedLink = 'magicleaphelio.com';
rotation
This attribute applies a static transform rotation
on the model. It accepts angle of rotation for each of the axis in radians (default unit) or degrees, delimited by a space or a comma.
rotation="(angle on x, angle on y, angle on z)"
<!-- Rotate the model 45 degrees on the y axes -->
<ml-model
id="helio"
src="/models/helio.glb"
rotation="0, 45deg, 0">
</ml-model>
...
//Rotate the model 45 degrees on the y axes
helio.rotation = '0, 45deg, 0';
instance
This attribute is used to create an instance of another <ml-model>
by reusing the model resources. The value of the instance
attribute must be the id name of the <ml-model>
from which you are instancing. One or more instances of the same <ml-model>
can be created.
instance="(id name of <ml-model>)"
<!-- Create two instances of the duck model -->
<ml-model id="duck" src="./models/Duck.glb"></ml-model>
<ml-model id="red-duck" instance="duck" color="red" rotation="0, 0, 90deg"></ml-model>
<ml-model id="blue-duck" instance="duck" color="blue" z-offset="400"></ml-model>
Transform Animations
Transform animations differ from static transforms in that the transform is animated over a period of time. There are several transform animations supported in Prismatic:
You can apply one or more transform animations to the same model. When there are more than one transform animations applied on the same model, the parameter Track Number can be used to allow you to queue your transform animations on your models.
If you want your transform animations to run sequentially, place them on the same Track Number (for example, track 1). If you want your animations to run simultaneously, place them on a separate Track Number (for example, track 1, track 2, and so on).
You can stop a transform animation immediately by calling the method stopTransformAnimations()
on the <ml-model> HTML element with the transform animation.
move-to
This attribute applies a move-to
transform animation on the model on each of the axis specified over a period of time. It accepts offset values for each of the axis, the duration of the transform animation in seconds and the track number.
Parameters | |
---|---|
Offset | Offset values to move the model to on each of the axis. The values are relative to the browser window calculated from the window top/left edge (0, 0) for the x and y axes and on top the browser window for the z axes (0). Each value is delimited by comma. For x axes you can use: left, middle, center, right or a number in pixels, where 0 is on the left edge of the browser. You can use stay to not move on the axis. For y axes you can use: top, middle, center, bottom or a number in pixels, where 0 is the top edge of the browser. You can use stay to not move on this axis. For z axes you can use a number in pixels where 0 is on top of the browser window. You can use stay to not move on this axis. |
Duration | Duration of the move-to animation in seconds |
Track Number | The track number to do the move-to animation. |
move-to="(offset: x, y, z; duration: time in seconds; track: track number)"
<!-- Move the model to: 200px from the left of the browser window on the x axes, the middle of the browser window on the y axes, and 200px behind the browser window on the z axes in 10 seconds on track 1-->
<ml-model
id="helio"
src="/models/helio.glb"
move-to="offset: 200px, middle, -200px; duration: 10s; track: 1">
</ml-model>
//Move the model to: 200px from the left of the browser window on the x axes,
//Move the model to: middle of the browser window on the y axes,
//Move model to: 200px behind the browser window on the z axes
//Move the model in 10 seconds on track 1
helio.moveTo='offset: 200px, middle, -200px; duration: 10s; track: 1';
move-by
This attribute applies a move-by
transform animation on the model on each axis over a period of time. It accepts the axes values to move by on each of the axis, the duration of the transform animation in seconds, and the track number.
Parameters | |
---|---|
Axes | Axes values to move the model by on each axis. |
Duration | Duration of the move-by animation in seconds |
Track Number | The track number to do the move-by animation. |
move-by="(axes: x, y, z; duration: time in seconds; track: track number)"
<!-- Move the model by: 200px on the x axes, stay in place on the y axes, and 200px forward on the z axes in 10 seconds on track 1.-->
<ml-model
id="helio"
src="/models/helio.glb"
move-by="axes: 200px, 0, -200px; duration: 10s; track: 1">
</ml-model>
//Move the model by: 200px on the x axes,
//Move the model by: 0px (stay in place) on the y axes
//Move the model by: 200px forward on the z axes
//Move the model in 10 seconds on track 1
helio.moveBy='axes: 200px, 0, -200px; duration: 10s; track: 1';
scale-to
This attribute applies a scale-to
transform animation on the model on each axis over a period of time. It accepts the axes percentage values to scale-to for each of the axis, the duration of the transform animation in seconds, and the track number.
Parameters | |
---|---|
Axes | Axes percentage values to scale to the model on each of the axis. |
Duration | Duration of the scale-to animation in seconds. |
Track Number | The track number to do the scale-to animation. |
scale-to="(axes: x, y, z; duration: time in seconds; track: track number)"
<!--Animate the scale down of model on the x, y and z axes to 50% of the specified size-->
<ml-model
id="whale"
src="/models/whale.fbx"
scale-to="axes: 0.5, 0.5, 0.5; duration: 10s; track: 1">
</ml-model>
...
//Animate the scale down of model on the x, y and z axes to 50% of the specified size
whale.scaleTo = 'axes: 0.5, 0.5, 0.5; duration: 10s; track: 1';
scale-by
This attribute applies a scale-by
transform animation on the model on each of the axis over a period of time. It accepts the axes percentage values to scale-by for each of the axis, the duration of the transform animation in seconds, and the track number.
Parameters | |
---|---|
Axes | Axes percentage values to scale by the model on each of the axis. |
Duration | Duration of the scale-by animation in seconds. |
Track Number | The track number to do the scale-by animation. |
scale-by="(axes: x, y, z; duration: time in seconds; track: track number)"
<!-- Animate the scale up of the model on the x, y and z axes to 50% of the specified size.-->
<ml-model
id="whale"
src="/models/whale.fbx"
scale-by="axes: 1.5, 1.5, 1.5; duration: 10s; track: 1">
</ml-model>
...
//Animate the scale up of model on the x, y and z axes to 50% of the specified size.
whale.scaleBy = 'axes: 1.5, 1.5, 1.5; duration: 10s; track: 1';
spin
This attribute applies a spin
transform animation on the model around a specified axis and rate for a duration of time.
Parameters | |
---|---|
Axes | Array of three elements, one for each axes [x, y, z] and with values of 0 or 1 to specify on which axis the spin occurs. |
Rate | An angle in radians (default unit) or degrees to specifies the angles per second. This is NOT how many degrees the model will spin. |
Duration | Duration of the spin animation in seconds. |
Track Number | The track number to do the spin animation. |
spin="(axes: [x, y, z]; rate: angle; duration: time in seconds; track: track number)"
<!-- Spin model around the y axes at 90 degrees per second for 300 seconds on track 1 -->
<ml-model
id="helio"
src="/models/helio.glb"
spin="axes: 0 1 0; angle: 90deg; duration: 300s; track: 1">
</ml-model>
...
//Spin model around the y axes at 90 degrees per second for 300 seconds on track 1
helio.spin = 'axes: 0 1 0; angle: 90deg; duration: 300s; track: 1';
rotate-by-angles
This attribute applies a rotation
transform animation on the model over a period of time. It accepts angles to rotate-by
for each axis in radians (default unit) or degrees delimited by a space or a comma, the duration of the transform animation in seconds, and the track number.
Parameters | |
---|---|
Angles | Angles to rotate-by each of the axis in radians (default unit) or degrees, delimited by a space or a comma. |
Duration | Duration of the rotate-by-angles animation in seconds. |
Track Number | The track number to do the rotate-by-angles animation. |
rotate-by-angles="(angles: x, y, z; duration: time in seconds; track: track number)"
<!-- Animate rotation of the model by 90 degrees on the x axes for 10 seconds on track 1 -->
<ml-model
id="helio"
src="/models/helio.glb"
rotate-by-angles="angles: 90deg, 0, 0; duration: 10s; track: 1">
</ml-model>
...
//Animate rotation of the model by 90 degrees on the x axes for 10 seconds on track 1
helio.rotateByAngles='angles: 90deg, 0, 0; duration: 10s; track: 1';
rotate-to-angles
This attribute applies a rotation
transform animation on the model over a period of time. It accepts angles to rotate-to
for each axis in radians (default unit) or degrees delimited by a space or a comma, the duration of the transform animation in seconds, and the track number.
Parameters | |
---|---|
Angles | Angles to rotate-to each axis in radians (default unit) or degrees, delimited by a space or a comma. |
Duration | Duration of the rotate-to-angles animation in seconds. |
Track Number | The track number to do the rotate-to-angles animation. |
rotate-to-angles="(angles: x, y, z; duration: time in seconds; track: track number)"
<!-- Animate rotation of the model to 1.57 radian on the y axes for 5 seconds on track 1 -->
<ml-model
id="helio"
src="/models/helio.glb"
rotate-to-angles="angles: 0 1.57 0; duration: 5s; track: 1">
</ml-model>
...
//Animate rotation of the model to 1.57 radian on y axes for 5 seconds on track 1
helio.rotateToAngles='angles: 0 1.57 0; duration: 5s; track: 1';
Model Animation
3D models can have animations that are baked into the models. These model animations have an animation name
given by the authors. The animation name
is used by Prismatic to initiate the model animation.
You can stop a model animation after it has been initiated by calling the method stopModelAnimation()
on the <ml-model></ml-model> HTML element with the animation.
model-animation
This attribute is used to animate models that have baked animation using the animation name.
Parameters | |
---|---|
Animation Name | The name of the baked animation on the model. |
Animation Paused | A boolean to pause the animation. This is false by default, so the animation automatically plays. |
Animation Iterations | How many times the animation plays. By default this is -1 to iterate indefinitely. |
model-animation="(animation name; true|false; number)"
<!-- The Animation Name is "swim", paused is set to false (meaning that it animates immediately), and it iterates indefinitely by setting iterations to -1.-->
<ml-model
id="whale"
src="/models/whale.fbx"
model-animation="swim, false, -1">
</ml-model>
...
//The Animation Name in the whale model is "swim"
//The parameter Paused is set to false, meaning that it animates immediately
//The parameter Iterations is set to -1, meaning it will iterates indefinitely.
whale.animation = 'swim, false, -1';
animation-speed
The animation-speed
attribute is a multiplier used to control the speed of the model animation. A default value of 1
is used, meaning that the model animation plays forward at standard speed. The value can be a negative in which case the animation is reverted.
animation-speed="(number)"
<!-- Model animation playing forward at twice the standard speed -->
<ml-model
id="whale"
src="/models/whale.fbx"
model-animation="swim"
animation-speed="2">
</ml-model>
...
//Model animation playing forward at twice the standard speed.
whale.modelAnimation='swim';
whale.animationSpeed = 2;
Model Effects:
Prismatic currently offers three methods for adding effects to nodes.
fadeIn
The fadeIn()
method gradually modifies the color alpha channel (opacity) of a model to go from visible to hidden. This method takes an optional speed
parameter to control how fast the model goes from visible to hidden. By default the speed value is 0.1
, but you can enter any value between 0 to 1, inclusive.
turkeyModel.fadeIn();
fadeOut
The fadeOut()
method gradually modifies the color alpha channel (opacity) of a model to go from hidden to visible. This method takes an optional speed
parameter to control how fast the model goes from hidden to visible. By default the speed value is 0.1
, but you can enter any value between 0 to 1, inclusive.
turkeyModel.fadeOut(0.5);
wiggle
The wiggle()
method creates a back and forward movement on the specified axis.
The wiggle method takes an optional parameter referring to the axis in which the wiggle effect occurs. This parameter is an array of three elements, one for each axes [x, y, z] and with values of 0 or 1.
If no array is specified, the default value for this parameter is [0, 1, 0], which performs the wiggle in the Y axes.
turkeyModel.wiggle([1,0,0]);
Model Events
There are several events that can be dispatched from the <ml-model></ml-model>
HTML element.
model-animation-loop
This event is dispatched once for each iteration of the model animation.
The number of iteration of an animation can be specified using the model-animation attribute.
In the detail property of the event you can find the animationName
property, which contains the name of the animation.
//Activate the "Walk" model animation for 5 iterations
turkey.animation = 'Walk, false, 5';
//This event is dispatched 5 times (one for each iteration)
turkey.addEventListener('model-animation-loop', (event) => {
//speed up the animation by 0.25 for every iteration.
if (event.detail.animationName === 'Walk') {
turkey.animationSpeed += 0.25;
}
});
model-animation-end
This event is dispatched once the animation of a model ends. This event is exclusively for model animations baked into the models and NOT for transform animations. The model animations are set using the model-animation attribute.
In the detail property of the event you can find the animationName
property, which contains the name of the animation that just ended.
//Activate the "Walk" model animation for 5 iterations
turkey.animation = 'Walk, false, 5';
turkey.addEventListener('model-animation-end', (event) => {
//fade out model once the "Walk" model animation ends after 5 iterations
if (event.detail.animationName === 'Walk') {
turkey.fadeOut();
}
});
transform-animation-end
This event is dispatched once a transform animation set on a model ends. This event applies for all transform animations: move-to, move-by, scale-to, spin, rotate-by-angles, and rotate-to-angles.
In the detail property of the event you can find the track
property, which contains the track number of the transform animation that just ended.
//Move the model by: 100px forward on the z axes in 10 seconds on track 1
whale.moveBy='axes: 0, 0, 100px; duration: 10s; track: 1';
//Spin the model on the x axes at 45 degrees per second for 300 seconds on track 2
whale.spin = 'axes: 1 0 0; angle: 45deg; duration: 300s; track: 2';
whale.addEventListener('transform-animation-end', (event) => {
//Move model back 100px in 5 seconds when the spin transform animation on track 2 ends
if (event.detail.track === 2) {
whale.moveBy='axes: 0, 0, -100px; duration: 5s; track: 1';
}
});
model-displayed
This event is dispatched once the model is ready to be displayed.
Note that this event is dispatched even if the model is hidden using the visibility attribute.
//Start playing a video once the duck model is ready to be displayed
duck.addEventListener('model-displayed', (event) => {
myVideo.play();
});
node-raycast
This event is dispatched when the Head position or the Control's pointer raycast points directly to a model.
In the detail property of the node-raycast
event, you can find the inputType property (event.detail.inputType) which is the input type of the raycast event. Possible values are headpos and control.
- Input type is headpos when the head position points directly to the node.
- Input type is control when the Control's Cursor points directly to the node.
You can also find in the detail property of the node-raycast
event, the type property (event.detail.type).
The possible values for the type property change depending of the inputType.
When the input type is headpos, these are the possible values for the type property:
nodeOnHeadEnter
, when the head position raycast enters the nodenodeOnHeadMove
, when the head position raycast moves within the nodenodeOnHeadExit
, when the head position raycast exits the node
//Start spin transform animation when you look at the model
//Stop transform animation when the you look away from the model
earth.addEventListener('node-raycast', function (event) {
if (event.detail.inputType === 'headpos') {
if (event.detail.type === 'nodeOnHeadEnter') {
//Spin model on the y axes at 45 degrees per second for 3000 seconds on track 1
earth.spin = 'axes: 0 1 0; angle: 45deg; duration: 3000s; track: 1';
}
else if (event.detail.type === 'nodeOnHeadExit') {
earth.stopTransformAnimations();
}
}
})
When the input type is control, these are the possible values for the type property:
nodeOnControlEnter
, when the raycast of the Control pointer enters the nodenodeOnControlMove
, when the raycast of the Control pointer moves within the nodenodeOnControlExit
, when the raycast of the Control pointer exits the node
// Start model animation named Fly when the control raycast points to the model
// Stop model animation when the control raycast exits the model
birdModel.addEventListener('node-raycast', function (event) {
if (event.detail.inputType === 'control') {
if (event.detail.type === 'nodeOnControlExit') {
birdModel.stopModelAnimation();
}
if (event.detail.type === 'nodeOnControlEnter') {
birdModel.animation = 'Fly';
birdModel.animationSpeed = 0.01;
}
}
});
mlextraction
This event is dispatched when the trigger on the Control registers a long press while the cursor is on the model.
Prismatic listens for this mlextraction
event on 3D models with the extractable attribute set to true
to initiate the placement of the model in your physical space.
//Event is dispatched when user long press the trigger on the control while cursor is on the model
duck.addEventListener('mlextraction', function (event) {
console.log(`trigger was long pressed on the Duck model.`)
});
extracting-node
This event is dispatched from the <ml-model></ml-model>
HTML element when the extractable attribute is set to true
, right before Prismatic initiates the placement of the model in your physical environment.
//Play audio when the duck model is about to be extracted
duck.addEventListener('extracting-node', function (event) {
extractingAudio.play();
});
node-extracted
This event is dispatched from the <ml-model></ml-model>
HTML element when the extractable attribute is set to true
, right after the placement of the model in your physical environment.
//Do a wiggle effect on the model on the page once the model is extracted
duck.addEventListener('node-extracted', (e) => {
duck.wiggle();
});