How to detect when video texture is done in A-Frame? - aframe

I want to transition out of the videospheres once the video ends, is there any event that is triggered when a video is over or some other way to go about doing this?
<a-scene>
<a-assets>
<video id="vid" src="a.mp4"></video>
</a-assets>
<a-videosphere src="#vid"></a-videosphere>
</a-scene>

Use the events from the native video element.
var video = document.getElementById('vid);
video.addEventListener('ended', function (evt) {
// ...
});

Related

A-frame click event doesn't work for object intersecting cursor when entering VR

I have created an A-frame scene, and I am using a large invisible sphere to catch any mouse click to change an image. This works perfectly before entering VR mode, however, on entering VR mode, the click events are not caught until you look away from the object and look back.
From reading the documentation my guess is that this isn't counting the cursor as intersecting the object if it starts the scene in that position?
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent('clickhandler', {
init: function () {
this.el.addEventListener('mousedown', function (evt) {
document.querySelector("#sky").setAttribute("src", "photo1.jpg");
});
}
});
</script>
<a-scene embedded background="color: black">
<a-entity camera look-controls position="0 0 0">
<a-cursor visible="false"></a-cursor>
</a-entity>
<a-sky id="sky" src="photo-initial.jpg"></a-sky>
<a-entity id="circle" cursor-listener geometry="primitive: circle; radius: 25" visible="false" material="color: blue" clickhandler position="-2.5 0.25 -1.5" rotation="0 15 0"></a-entity>
</a-scene>
So when this scene starts, the image is in front of the view, a large invisible sphere fills the whole view - from the browser, I can immediately click to trigger the click event. But if I reload the page and go straight into VR and click, nothing happens until I click to look 180 degrees away, and then look back. Then if I click, the event triggers.

Wrong position of a clickable object on AR.js scene

I have a simple AR.js scene that should display a clickable white box on a hiro marker. After click the box's colour should change to red. In fact, the box is clickable and the colour is changing, but it's position and the position of it's clickable area are not the same. In my case this area is beneath the box. Here's a code example:
<!DOCTYPE html>
<html>
<script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script>
<script src="https://rawgit.com/jeromeetienne/ar.js/master/aframe/build/aframe-ar.js"></script>
<script>
AFRAME.registerComponent('clickhandler', {
init: function () {
this.el.addEventListener('click', () => {
this.el.setAttribute('material', 'color: red;');
});
},
});
</script>
<body>
<a-scene embedded arjs>
<a-marker cursor="rayOrigin: mouse;" preset="hiro">
<a-box
material="color: white;"
position="0 0 0"
depth="0.2"
height="0.01"
width="0.2"
clickhandler
/>
</a-marker>
<a-entity camera></a-entity>
</a-scene>
</body>
</html>
However, if you open the aframe inspector (Ctrl + Alt + I) and then close it, box's clickable area and it's position will be correct and I don't understand how is that happening. So how can I make this scene to display the right way?
I've explored how the aframe inspector works and found that it inserts a new raycaster programmatically after it's initialization, so I've decided to do the same and it worked!
All you need to do to place clickable area in the same spot with it's object is to execute these lines after the scene is fully initialized.
const scene = AFRAME.scenes[0];
if (!scene) {
return;
}
const mouseCursor = document.createElement('a-entity');
mouseCursor.setAttribute('cursor', 'rayOrigin', 'mouse');
scene.appendChild(mouseCursor);

How in a-frame to cyclically play the next sound after the first start?

How in a-frame to cyclically play the next sound after the first start?
Animation does not work.
<a-sky src="#room" sound="src:#soundstart; autoplay:true; loop:false" rotation="0 300 0" animation="property:sound.src; to:#soundfon; autoplay:true; delay:5000; loop:true"></a-sky>
This seems like a job for an custom a-frame component:
Play the first sound
Wait until it's finished
Play the second sound.
Lets say you have a setup like this:
<a-entity manager></a-entity>
<a-box id="first" sound="src: url(sound1.mp3);"></a-box>
<a-box id="second" sound="src: url(sound2.mp3);"></a-box>
You can easily manage the sounds with a component as such:
AFRAME.registerComponent('manager', {
init: function() {
// grab the boxes
let first = document.querySelector("#first")
let second = document.querySelector("#second")
// play the first sound
first.components.sound.playSound();
// wait for it to end
first.addEventListener("sound-ended", function() {
// play the second one
second.components.sound.playSound();
})
}
}
check it out in this glitch

OnClick on model in AFrame-AR.js scene

I am working on an Augmented reality scene using Aframe and ARJS. I am currently rendering obj models when the marker is detected. My requirement is to be able to click on individual models upon rendering and manipulate them. For some reason onclick doesnt seem to be working on aframe model entities but it works fine on other primitive entities like box . This is my approach -
AFRAME.registerComponent('cursor-listener', {
init: function () {
this.el.addEventListener('click', function (evt) {
console.log('I was clicked at: ', evt.detail.intersection.point);
});
}
});
</script>
</head>
<body>
<a-scene embedded arjs='trackingMethod: best; debugUIEnabled: false;' foo>
<a-assets>
<a-asset-item id="crate-obj" src="model.obj"></a-asset-item>
<a-asset-item id="crate-mtl" src="model.mtl"></a-asset-item>
<img id="texture" src="brick.jpg">
</a-assets>
<a-marker preset='hiro'>
<a-entity ><a-obj-model class="collidable" cursor-listener id="animated-marker" src="#crate-obj" position="0 -1.6 0" mtl="#crate-mtl" rotation="-90 0 0" scale="0.004 0.004 0.004" material="" obj-model=""></a-obj-model></a-entity>
//onclick doesn't work
<a-entity material=" src: url(box.png) " class="collidable" cursor-
listener position="0 -1 0"></a-entity> //onclick works here
</a-marker>
<a-camera-static/>
</a-scene>
</body>
</html>
Is there anything I might be overlooking ? Or is there any other way to achieve this requirement.Thanks.
You need to use the cursor component, since the click event is based on raytracing in 3D.
<a-marker preset='hiro' cursor='rayOrigin: mouse'></a-marker>

Text animation not occurring on event emission (or event not emitting)

I have a text element and a skybox in my scene. When the scene initialises, I want the text to animate its position once.
<!-- scene elements -->
<a-scene coogee2006-scene embedded style="width:100%;height:400px;">
<a-assets>
<img
id="coogee2006"
src="/assets/vr/sydney-coogee-3-peter-gawthrop.jpg"
preload="auto">
<audio
id="beachsound"
src="/assets/vr/beach1.wav"
preload="auto">
</a-assets>
<a-sky src="#coogee2006"
rotation="0 -90 0">
</a-sky>
<!-- text animates in on startup (see searise_vr.js) -->
<a-text
id="coogee2006-text"
value="Coogee, Sydney\n2006"
position="5 12.5 -50"
rotation="0 -15 0"
scale="20 20 20"
visible="true"
text="anchor:align;alphaTest:0.2;width:5;
value:COOGEE, SYDNEY\n2006;
zOffset:0;color:#000;font:exo2bold"
sound="src:#beachsound;autoplay:true;loop:true;volume:20;">
<a-animation
attribute="position"
dur="3000"
begin="coogeetour"
to="12.5 12.5 -50"
easing="ease-in"
fill="both"
repeat="0">
</a-animation>
</a-text>
</a-scene>
If I set a static delay with begin=5000, it works fine, but if I try to set it on an event, like begin="coogeetour", the animation doesn't occur. I've tried firing the event two ways:
First, by registering a component for the scene, in a script tag above the a-scene tag, and using document.querySelector() identify the text element:
<script>
AFRAME.registerComponent('coogee2006-scene', {
// emit text events when the scene is initialised
init: function () {
console.log('Running coogee2006-scene.init()');
document.querySelector("#coogee2006-text").emit('coogeetour');
}
});
</script>
Second, by registering a component for the text element and using this.el, as in the A-Frame Writing a Component section, and putting this in an external file that is linked:
AFRAME.registerComponent('coogee2006-text', {
// emit text events when the scene is initialised
init: function () {
console.log('Initialising text element');
this.el.emit('coogeetour');
}
});
In either case, the console.log works, so the component is initialising, but the animation isn't happening. I can't find coogeetour in the elements' event listeners when debugging, but I don't know if that's because emit() isn't working properly or because it oughtn't show up in the debugging.
EDIT: here's my console log on loading:
Navigated to http://127.0.0.1:4000/private/JoQyfM/
index.js:73A-Frame Version: 0.5.0 (Date 10-02-2017, Commit #110055d)
index.js:74three Version: ^0.83.0
index.js:75WebVR Polyfill Version: dmarcos/webvr-polyfill#a02a8089b
browser.js:117 core:a-assets:warn Asset loading timed out in +0ms 3000 ms
three.js:19590 THREE.WebGLRenderer 83
(index):81 Running coogee2006-scene.init()
browser.js:117 components:sound:warn All the sounds are playing. If you need to play more sounds simultaneously consider increasing the size of pool with the `poolSize` attribute. +118ms
three.js:17507 THREE.WebGLRenderer: image is not power of two (5980x2990). Resized to 8192x4096 <img crossorigin=​"anonymous" src=​"/​assets/​vr/​sydney-coogee-3-peter-gawthrop.jpg">​
I am not sure exactly why, but it looks like the component methods are swallowing the emit() event. I tried putting that same call in the update() function but it still did not work.
What did work was to put the emit call in a timeout:
setTimeout(function() { document.querySelector("#coogee2006-text").emit('coogeetour'); }, 0);
Codepen: http://codepen.io/shanabus/pen/zZYBaa
Okay, it looks like begin only works with numerical values; delay works with both numerical values and event names. To be fair, this is described in the attribute table for animations, but the block below it on the begin attribute shows an example of it being used with an event name. Maybe a depreciated attribute?
EDIT: okay, maybe this isn't the answer. I'm not entirely sure why delay and begin both exist—is it so there can be a delay following an event trigger, or is delay just depreciated?

Resources