Scripting (Javascript)
We use AFrame's Compatible Entity-Component-System to build our scenes. This is a powerful pattern that allows us to create reusable components that can be attached to any entity in the scene. This enables us to create a scene that is made up of many different components that can be reused and shared across scenes.
Web Components is a suite of different technologies allowing you to create reusable custom elements — with their functionality encapsulated away from the rest of your code — and utilize them in your web apps more Infos to Framework independent Web Components.
This documentation outlines the structure, methods, and optional rendering of the SampleElement
Lit A-Frame component. Developers can extend and customize this component to suit their A-Frame scene requirements.
const { Color, Vector3 } = THREE
class SampleElement extends CapElement {
schema = {}
// Do something when the component is first attached.
async init() {
// this.el.sceneEl reference to A-Frame a-scene
// this.el.sceneEl.renderer refers to the Three.js renderer
}
// Do something on every scene tick or frame.
tick = (time, deltaTime) => {}
// Do something when the component or its entity is detached.
remove = () => {}
// Do something when the component's data is updated.
update = (oldData) => {}
#showInfo = () => {
const dialog = document.querySelector('dialog')
dialog.addEventListener('click', (e) => {
const dialogDimensions = dialog.getBoundingClientRect()
if (
e.clientX < dialogDimensions.left ||
e.clientX > dialogDimensions.right ||
e.clientY < dialogDimensions.top ||
e.clientY > dialogDimensions.bottom
) {
dialog.close()
}
})
//dialog.show() // Opens a non-modal dialog
dialog.showModal() // Opens a modal
}
// Optional Render TemplateResult
render() {
return html`
<!-- CSS Styles 2D -->
<style>
#info {
width: 100px;
height: 50px;
border-radius: 20px;
cursor:pointer;
background-color:rgb(230, 0, 0);
color:white;
margin-top:10px;
font-size:xx-large;
border-width:0.1px;
}
dialog {
z-index: 10;
margin-top: 100px;
background-color:hsl(0deg 0% 100% / 75%);
border: none;
border-radius: 0.5rem;
backdrop-filter: blur(15px);
width:400px;
height: 50vh;
}
dialog::backdrop {}
</style>
<!-- Dialog Element 2D -->
<dialog>
<div>
<img
style="display:flex;height:300px;"
src="https://aomediacodec.github.io/av1-avif/testFiles/Link-U/kimono.avif"
sizes="(max-width: 800px) 100px, 200px"
/>
<h1
style="margin: 0px; color: rgb(156, 187, 54); --fontSize: 42; line-height: 1.4;"
data-fontsize="42"
data-lineheight="58.8px"
>
<span style="color: #301d1d;"
>Authors: Momiji Jinzamomi(@momiji-san) and Kaede
Fujisaki(@ledyba)</span
>
</h1>
<form action="https://google.com" method="get" target="_blank">
<button id="info">Info</button>
</form>
</div>
</dialog>
<!-- A-Frame Entities 3D -->
<a-entity
id="boxRounded"
position="-15 1.1 -5"
rotation="0 0 0"
box-rounded="envMapIntensity:1.0;curveSegments:128;zOffset:-0.1;yOffset:0.0;xOffset:0.0;material:physical;color:lightblue;width:4;depth:0.1;height:1;borderRadius:0.1;opacity:0.9;"
class="interactable"
troika-text="color:black;font:https://db.onlinewebfonts.com/t/82562c746c45bf39231fbf430dc5e0c2.woff;maxWidth:8;fontSize:0.3;value:Our options leave nothing to be desired, with be banana® the watch always fits! Individual design, handmade by the master watchmaker."
>
</a-entity>
<a-entity
position="5 2.5 6"
rotation="0 180 0"
troika-text="color:black;font:https://db.onlinewebfonts.com/t/82562c746c45bf39231fbf430dc5e0c2.woff;maxWidth:10;fontSize:0.5;value:Our options leave nothing to be desired, with be banana® the watch always fits! Individual design, handmade by the master watchmaker."
>
</a-entity>
<a-entity
position="-33.2 3.3 -8.5"
rotation="0 90 0"
troika-text="color:black;font:https://db.onlinewebfonts.com/t/82562c746c45bf39231fbf430dc5e0c2.woff;maxWidth:5;fontSize:0.29;value:Assemble your own watch or simply be up close and personal with the production process. This set includes exclusive, private glimpses behind the scenes of the watchmaker's craft in our newly equipped show workshop. First, we configure the desired model together before we arrive at the finished model step by step following the production process. Of course, every single step is explained in detail to create a precise product with expert support."
>
</a-entity>
<a-entity
class="interactable"
position="-15 4.5 -6"
geometry="primitive:box;width:3;height:3;"
material="src:https://aomediacodec.github.io/av1-avif/testFiles/Link-U/kimono.avif;side:double;"
@click="${this.#showInfo}"
>
</a-entity>
`
}
}
export default SampleElement;
Result
Import Scripts
class SampleElement extends CapElement {
schema = {}
// Do something when component first attached.
async init() {
// this.el.sceneEl reference to aframe a-scene
// Import script module from jsdelivr or unpkg.com
const { helloWorld } = await import(
'https://cdn.jsdelivr.net/gh/vschetinger/captic/helloWorldExport.js'
)
helloWorld()
}
}
export default SampleElement;
Last updated