Add function on clicking specific entity [duplicate] - three.js

I am using a networked A-frame to generate a new entity when the page is loaded. I want to add a few functionalities on those entities like hover, on click, etc. I tried making it clickable but it didn't work.
function rigClick(){
console.log("Entity Clicked");
}
<a-scene>
<a-entity id="rig" onclick="rigClick()">
<a-entity
id="foo"
networked="template:#rig-template;attachTemplateToLocal:false;"
camera="active:true;"
position="-27 2.5 24"
wasd-controls="acceleration:12;"
look-controls
spawn-in-circle="radius:2"
>
</a-entity>
</a-entity>
</a-scene>
I also tried using the register component but I am unable to get the results.
AFRAME.registerComponent('click-handler', {
init: function () {
let entity = document.querySelector('#rig')
entity.addEventListener('click', (e) => {
console.log("You just clicked on entity");
})
}
});
<a-scene>
<a-entity id="rig">
<a-entity
id="foo"
networked="template:#rig-template;attachTemplateToLocal:false;"
camera="active:true;"
position="-27 2.5 24"
wasd-controls="acceleration:12;"
look-controls
spawn-in-circle="radius:2"
click-handler
>
</a-entity>
</a-entity>

If you want to use your mouse, you need a cursor which will map 2D mouse clicks onto 3D rays checking whats under the mouse cursor:
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script>
// declare a component
AFRAME.registerComponent("click-detector", {
// called upon initialisation
init: function() {
// when a click is detected
this.el.addEventListener("click", () => {
// log "clicked"
console.log("clicked")
})
}
})
</script>
<a-scene cursor="rayOrigin: mouse" raycaster="objects: a-sphere">
<a-sphere position="0 1.25 -2" radius="1.25" color="#EF2D5E" click-detector></a-sphere>
</a-scene>
Works the same in aframe-networked as long as you add the component to the networked-template so that every new 'player' has the component attached:
<template id="avatar-template">
<a-entity class="avatar">
<a-sphere class="head" scale="0.45 0.5 0.4" click-detector></a-sphere>
</a-entity>
</template>

Related

Unmount aFrame on Sveltekit

I'm running an AR application inside Sveltekit with aFrame and AR.js. The augmented reality runs fine with some details. My problem is that when I exit the component (I go to another page) it stays mounted and the webcam stays on. At the moment what I do is to use the onDestroy hook and every time I exit I remove the video tag generated by AR.js. This works partially but I would like to know if there is another way to disassemble. Any help is welcome.
This is my code
<script>
//componente para sombra en camera background
AFRAME.registerComponent("apply-shadowmaterial", {
init: function() {
// grab the mesh
let mesh = this.el.getObject3D("mesh");
// keep the reference to the old material
let tmp = mesh.material;
// assign the new material
mesh.material = new THREE.ShadowMaterial({ opacity: 0.1 });
mesh.receiveShadow = true;
// free memory
tmp.dispose();
}
});
</script>
<a-scene id="escena" class="a-frame" gesture-detector physicallyCorrectLights="true" vr-mode-ui="enabled: false" embedded arjs ="sourceType: webcam; trackingMethod: best; detectionMode: mono; sourceWidth:2048; sourceHeight:1536; displayWidth: 2048; displayHeight: 1536" always-fullscreen renderer="precision: high; antialias: false; logarithmicDepthBuffer:true; colorManagement: true" loading-screen="dotsColor: #DBDADA; backgroundColor: #282828">
<a-assets>
<a-asset-item id="blackM" src={`${storeData.assets.vectorFile}`}></a-asset-item>
<!-- <a-asset-item id="blueM" src="/Blue.glb"></a-asset-item>
<a-asset-item id="orangeM" src="/Orange.glb"></a-asset-item> -->
</a-assets>
<a-entity id="luzdirectional" light="type: directional; color: #DDD; groundColor: #DDD; intensity: 0.2; castShadow:true; target:#marcador; shadowCameraBottom:-6.0; shadowCameraTop:6.0; shadowCameraLeft:-6.0; shadowCameraRight:6.0; " position="-5.0 6.520 5.127">
</a-entity>
<a-marker id="marcador" raycaster="objects: .clickable" emitevents="true" cursor="fuse: false; rayOrigin: mouse;" type='pattern' url='/hiro.patt' smooth='true' smoothCount='3' smoothTolerance='0.01' smoothThreshold='2'>
<a-plane id="planosombras" position="0 -0.2 0" height="500" width="500" rotation="-90 0 0" apply-shadowmaterial></a-plane>
<a-entity
id="plato"
position="0 0 0"
rotation="0 60 0"
scale="0.1 0.1 0.1"
gltf-model={`${storeData.assets.vectorFile}`}
shadow="receive: true; cast: true"
animation__pos="property:position; from:0 0 0; to:-6 0 0; dur: 1000; startEvents:pos"
animation__scale="property:scale; from:0.1 0.1 0.1; to:0 0 0; dur: 1000; startEvents:scale"
class="clickable"
gesture-handler
>
</a-entity>
</a-marker>
<a-entity id="camera" camera="far:10000.00; fov:80.00; near:0.005">
</a-entity>
<a-entity id="luz" light="type: ambient; color: #DDD; groundColor: #DDD; intensity: 0.6" position="0 2 0">
</a-entity>
</a-scene>
</div>

Add follow camera

I want to add follow camera which will follow the object when I move it. As I am using a networked a-frame so my object is in the template.
<a-assets>
<a-asset-item id="bee" src="./bee/scene.gltf"></a-asset-item>
</a-assets>
This is model.
<template id="bee-template">
<a-entity
id="fly"
gltf-model="#bee"
animation-mixer="clip: Rig|bee_idle"
scale="0.02 0.02 0.02"
look-controls
wasd-controls
>
</a-entity>
</template>
This is a template that I'm adding to the networked scene.
<a-entity
id="model"
networked="template:#bee-template;attachTemplateToLocal:false;"
position="0 1 0"
spawn-in-circle="radius:3"
wasd-controls="acceleration: 10"
look-controls
>
</a-entity>
So, by using this I want that camera to follow bee. Please help in this!

AR.js aframe object show also without pointing marker

In my AR project I use arjs with aframe to make my gltf object visibe when I point with my phone camera on my hiro pattern:
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<!-- include ar.js for A-Frame -->
<script src="https://jeromeetienne.github.io/AR.js/aframe/build/aframe-ar.js"></script>
<script src="https://unpkg.com/aframe-orbit-controls#1.2.0/dist/aframe-orbit-controls.min.js"></script>
<body style='margin : 0px; overflow: hidden;'>
<a-scene embedded arjs>
<!-- define your gltf asset -->
<!--This is for add a text-->
<!--<a-text value="Hello, World!"></a-text>-->
<!--This is for add an image-->
<!--<a-image src="another-image.png"></a-image>-->
<a-assets>
<a-asset-item id="tree" src="models/gltf/manovella.gltf"></a-asset-item>
</a-assets>
<a-entity gltf-model="#tree" position="0 0 0" rotation="0 90 0" scale="10 10 10"></a-entity>
<a-entity camera look-controls orbit-controls="target: 0 1.6 -0.5; minDistance: 0.5; maxDistance: 180; initialPosition: 0 5 15">
<!-- define a camera which will move according to the marker position -->
<a-marker-camera preset='hiro'></a-marker-camera>
</a-entity>
</a-scene>
</body>
when I point to my marker all was done, the problem is then also when I start my app without pointing to any market the object appears and when I no longer see the marker in the frame, the object remains on the screen.
How can I manage my gltf show/hide only related to my marker?
So many thanks in advance
Your object should be inside your marker. Try to use this in your scene:
<a-assets>
<a-asset-item id="tree" src="models/gltf/manovella.gltf"></a-asset-item>
</a-assets>
<!-- define a camera which will move according to the marker position -->
<a-marker-camera preset='hiro'><a-entity gltf-model="#tree" position="0 0 0" rotation="0 90 0" scale="10 10 10"></a-entity></a-marker-camera>
<a-entity camera look-controls orbit-controls="target: 0 1.6 -0.5; minDistance: 0.5; maxDistance: 180; initialPosition: 0 5 15"></a-entity>

Aframe Trigger Animation of Element through event-component & proxy-component

I'm trying to trigger animations on other elements while a certain element is being looked at. So what I'm trying to achieve is: When I hover the ball, the text should fade in. And when I leave the ball, the text should fade out.
I was told this should be possible with the aframe-proxy-event-component but I couldn't find any example or documentation on how to use this.
The code looks something like that:
<script src="https://unpkg.com/aframe-animation-component#5.1.2/dist/aframe-animation-component.min.js"></script>
<script src="https://unpkg.com/aframe-event-set-component#4.0.0/dist/aframe-event-set-component.min.js"></script>
<script src="https://unpkg.com/aframe-proxy-event-component/dist/aframe-proxy-event-component.min.js"></script>
<a-mixin id="scaleUpMixin" animation__scale="property: scale; dur: 500; easing: easeInOutQuad; to: 1.5 1.5 1.5;"></a-mixin>
<a-mixin id="scaleDownMixin" animation__scale2="property: scale; dur: 500; easing: easeInOutQuad; to: 1 1 1;"></a-mixin>
<a-mixin id="fadeInText" animation__opacity="property: text.opacity; dur: 500; to: 1"></a-mixin>
<a-mixin id="fadeOutText" animation__opacity2="property: text.opacity; dur: 500; to: 0"></a-mixin>
<a-entity rotation="0 -10 0">
<!-- Planet -->
<a-sphere color="yellow" position="0 1.8 -5" radius="0.5" scale="1 1 1"
mixin="scaleUpMixin scaleDownMixin"
animation__scale="startEvents: mouseenter;"
animation__scale2="startEvents: mouseleave;">
</a-sphere>
<!-- Text -->
<a-text id="TextMercury" class="textbox" text="value: Merkur; align: center; color:#FFF" opacity="0" scale="0.8 0.8 0.8"
position="0 1.8 -1"> </a-text>
</a-entity>
Here's a live demo: https://gorgeous-badge.glitch.me/
An the code: https://glitch.com/edit/#!/gorgeous-badge?path=index.html:30:61
Thanks!
You need to attach the proxy-event component to the sphere. Its quite well documented (with an example) #github
If you have a button, you can redirect any event like this:
<a-box proxy-event="event: event; to: targetSelector; as: newname"></a-box>
<a-entity animation="(...) startEvents: newname"></a-entity>
Check it out in this fiddle.

a-frame navigation bar, that moves horizontal only

I need to know, how to creat a navigation bar with a pre, home and next button.
The bar should be under the cursor and follow it horizontal. so that you can click on the button when you look down.
I have already the 3 buttons and they move the cursor, but now they should only move horizontal and not vertical.
<a-assets>
<a-mixin id="pre" geometry="primitive: circle; radius: 0.1" material="color:blue; opacity:0.2"></a-mixin>
<a-mixin id="home" geometry="primitive: circle; radius: 0.1" material="color:green; opacity:0.2"></a-mixin>
<a-mixin id="next" geometry="primitive: circle; radius: 0.1" material="color:#fe0000; opacity:0.2"></a-mixin>
</a-assets>
<a-entity camera look-controls>
<a-cursor ></a-cursor>
<a-entity mixin="pre" position="-0.2 -0.5 -2"></a-entity>
<a-entity mixin="home" position="0.05 -0.5 -2"></a-entity>
<a-entity mixin="next" position="0.3 -0.5 -2"></a-entity>
</a-entity>
When You put the entity inside the cursor, it will move exactly like the cursor, unless You make a script blocking it in the desired position. However in my opinion, you should create a entity consisting of the buttons:
<a-entity id="button_wrapper" position="0 0 -3" camera-check>
<a-entity mixin="pre" position="-0.2 -0.5 -2"></a-entity>
<a-entity mixin="home" position="0.05 -0.5 -2"></a-entity>
<a-entity mixin="next" position="0.3 -0.5 -2"></a-entity>
</a-entity>
<a-entity id = "camera" camera look-controls>
<a-cursor >
</a-cursor>
</a-entity>
Having it this way, You can create a script moving the entity with the camera either moving the object when the camera changes, or moving it on tick():
AFRAME.registerComponent('camera-check', {
init: function () {
var rotation;
camera = document.querySelector('#camera');
camera.addEventListener('componentchanged', function(evt) {
if (evt.detail.name === 'rotation') {
// here You have your new rotation reference in evt.detail.newData
// and Your old rotation reference in evt.detail.oldData
this.el.setAttribute("rotation","0 "+evt.detail.newData.y+" 0");
}
});
},
tick: function(){
// this.el.setAttribute("rotation","0 "+document.querySelector('a-box').getAttribute("rotation").y)+" 0");
}
});
working fiddle here.

Resources