AFrame Animation Start\End Condition - aframe

I'm trying to get the cylinder to begin and pause rotating on mouse click but I can only get it to begin, not stop. I'm not sure what else would work? When I add the end condition it stops working all together. My question is, how can I get the begin and end conditions to be the same input?
<<html>
<head>
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-environment-component/dist/aframe-
environment-component.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/annyang/2.5.0/annyang.min.js">
</script>
<script src="/components/voice-commands.js"></script>
</head>
<body>
<button>Go</button>
<a-scene>
<a-assets>
<img id="sky" src="sky2.0.jpg">
</a-assets>
<a-camera position="0 1.6 0">
<a-cursor></a-cursor>
</a-camera>
<a-box position="0 -2 0" color="grey" scale="30 2.5 20"></a-box>
<a-cylinder id="center" position="17 0 0" color="grey" scale="4 4 4"
rotation="0 0 90">
<a-sphere position="0 -0.375 0" color="grey" scale="1 1 1"
rotation="0 0 90"></a-sphere>
<a-box position="8 0 0" color="grey" scale="15 0.25 1" rotation="-20
0 0"></a-box>
<a-box position="-3.5 0 6" color="grey" scale="15 0.25 1"
rotation="-20 240 0"></a-box>
<a-box position="-3.5 0 -6" color="grey" scale="15 0.25 1"
rotation="-20 -240 0"></a-box>
<a-animation attribute="rotation" begin="click" end="click"
dur="20000" to="360 0 90" repeat="indefinite" easing="linear"></a-animation>
</a-cylinder>
<a-sky src="#sky"></a-sky>
<a-cylinder position="0 -402 0" color="grey" scale="5 800 5" rotation="0 0
0">
<a-entity id="annyang" annyang-voice-recognition></a-entity>
</a-scene>
</body>
</html>

I would threw the logic to a seperate a-frame component.
Having a setup like this:
<a-cylinder animation-controller
animation="resumeEvents: start; pauseEvents: pause">
</a-cylinder>
When clicked - switch a boolean, and depending on the value start or stop the animation:
<script src="https://aframe.io/releases/1.3.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent("animation-controller", {
init: function() {
this.running = false
this.el.addEventListener("click", (e) => {
if (!this.running) {
this.el.emit("start") // animation not running - start it
} else {
this.el.emit("pause") // animation running - stop it
}
this.running = !this.running // flip the flag
})
}
})
</script>
<a-scene cursor="rayOrigin: mouse">
<a-cylinder animation-controller position="0 1 -3" color="red"
animation="property: rotation; to: 0 0 360; dur:1000; loop: true; resumeEvents: start; pauseEvents: pause">
</a-cylinder>
</a-scene>
Original answer - for aframe < 1.0.0
I would threw the logic to a seperate a-frame component.
Having a setup like this:
<a-cylinder anim-controller>
<a-animation begin="start" end="stop" (...)></a-animation>
</a-cylinder>
When clicked - switch a boolean, and depending on the value start or stop the animation:
AFRAME.registerComponent("anim-controller", {
init: function() {
this.running = false
this.animComp = document.querySelector("a-animation")
this.el.addEventListener("click", (e) => {
if (!this.running) {
this.animComp.emit("start") // animation not running - start it
} else {
this.animComp.emit("stop") // animation running - stop it
}
this.running = !this.running // flip the flag
})
}
})
Simple - if the animation is running - start it. Otherwise stop it.
Fiddle here.

Related

How can I make A-frame AR.js Marker tracking more stable and not hide the objects when marker not detected?

I am using AFrame and Ar.js with marker tracking.
The marker detection is quite bad, is there a way to improve it? also, is there a way to make the objects visible even if the marker is not being detected? keeping them in the same screen position for example.
This is my code
<script>
AFRAME.registerComponent('marker-handler', {
init: function () {
this.el.addEventListener('markerFound', () => {
this.el.setAttribute('visible', true);
});
this.el.addEventListener('markerLost', () => {
this.el.setAttribute('visible', true);
});
}
});
</script>
<body style="margin: 0; overflow: hidden;">
<a-scene
vr-mode-ui="enabled: false;"
loading-screen="enabled: false;"
renderer="logarithmicDepthBuffer: true;"
arjs="trackingMethod: best; sourceType: webcam; debugUIEnabled: false; sourceWidth:1280; sourceHeight:960; displayWidth: 1280; displayHeight: 960;"
id="scene"
embedded
gesture-detector
>
<a-assets>
<a-asset-item
id="animated-asset"
src="assets/asset.gltf"
></a-asset-item>
<a-asset-item
id="M-asset"
src="assets/M.gltf"
></a-asset-item>
</a-assets>
<a-marker
id="animated-marker"
type="pattern"
preset="custom"
url="assets/marker.patt"
raycaster="objects: .clickable"
emitevents="true"
cursor="fuse: false; rayOrigin: mouse;"
id="markerA"
>
<a-entity
id="bowser-model"
position="-0.7 0 0"
scale="0.5 0.5 0.5"
animation-mixer="loop: repeat"
gltf-model="#animated-asset"
rotation="0 30 -10"
class="clickable"
marker-handler
event-set__markerLost="_visible: true"
></a-entity>
<a-entity
id="M-model"
position="0.7 0 0"
scale="0.5 0.5 0.5"
gltf-model="#M-asset"
rotation="0 -30 -10"
animation-mixer="loop: repeat"
class="clickable"
marker-handler
event-set__markerLost="_visible: true"
></a-entity>
</a-marker>
<a-entity camera></a-entity>
</a-scene>
</body>
</html>
It looks like 'markerLost' attribute makes the object not visible even if visible is set to true.

use animation-mixer for playing glb file, why not start from the beginning? It always start from the middle of the animation where I am using nft

Below is the code I use:
I use glb file and it should start animation from the beginning when marker is activated, but It start from the middle of the animation.
<div class="arjs-loader">
<div>Loading, please wait...</div>
</div>
<a-scene vr-mode-ui="enabled: false;"
renderer="logarithmicDepthBuffer: true;"
embedded arjs="trackingMethod: best; sourceType: webcam; debugUIEnabled: false;">
<a-assets>
<a-asset-item id="dja" src="./arfile2.glb"></a-asset-item>
</a-assets>
<a-nft type='nft' url='./demo/marker/djarum'
smooth='true' smoothCount='10' smoothTolerance='0.01' smoothThreshold='5'>
<a-entity gltf-model='#dja'
scale="90 90 90"
position="100 -200 0"
rotation="-90 0 0"
animation-mixer >
</a-entity>
</a-nft>
<a-entity camera>
</a-entity>
</a-scene>
<!--<a-scene>
<a-assets>
<a-asset-item id="tree" src="./tesla/scene.gltf"></a-asset-item>
</a-assets>
<a-entity gltf-model="#tree" scale="0.6 0.6 0.6" position="0 0.15 -3"></a-entity>
</a-scene>-->
The animation-mixer starts the animation when the model is loaded, not when it's visible.
You can wait until the image is detected, and then attach the animation-mixer:
const model = document.querySelector("[gltf]")
const nft = document.querySelector("a-nft");
nft.addEventListener("markerFound", () => {
model.setAttribute("animation-mixer", "")
})

A-Frame version 8 to version 9 unable to move model or camera from within inspector

Issue upgrading from A-FRAME 8 to 9 with a project. The reason for the upgrade was due to inconsistent mouse clicks from registered components using addEventListener. It was just not consistent however moving to verison 9 seemed to correct that issue but at the cost of breaking the rest of the project.
Animations are not working, I am unable to move objects or cameras when in inspector mode yet elements do appear in inspector mode, you just cannot select the xyz arrows to move them.
I'm wondering if anyone else has experienced similar issues as described above when migrating from version 8 to 9 of A-FRAME?
The closest example of this is the code below. If you change it to version 9 of A-FRAME nothing works yet it is ok with version 8. I could not find any glaring differences between my markup and the A-FRAME documentation. Anyone else?
Re-creating every element seems to work however camera positioning within the inspector is not functional, unable to spectate to see what the camera angle would look like, and adding objects with OBJ and MTL files only shows an outline of the object whereas with version 8 everything worked 100%.
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent('cursor-hotpsot-1', {
init: function () {
var COLORS = ['purple', 'green', 'blue'];
this.el.addEventListener('click', function (evt) {
var randomIndex = Math.floor(Math.random() * COLORS.length);
this.setAttribute('material', 'color', COLORS[randomIndex]);
console.log('Clicked:' + this);
});
}
});
</script>
<a-scene class="fullscreen"
inspector=""
keyboard-shortcuts=""
screenshot=""
vr-mode-ui="enabled: false"
cursor="rayOrigin: mouse">
<!--
<a-camera active="true" spectator="true"
wasd-controls="wsEnabled:false;enabled:false"
look-controls="enabled: false"
zoom="2.4"
position="0.3 0.0 -1.8"
rotation="0.0 132.5 0.0"
camera="zoom:1.5"
look-controls=""
camera="active:true"
data-aframe-inspector-original-camera=""
look-controls="enabled: false"></a-camera>
-->
<a-obj-model id="diagram"
position="-0.8 0 -3.5"
scale="0.2 0.2 0.2"
shadow=""
rotation="-90 180 0"
material="metalness: .5; src: #issTexture; src: #issTexture; " obj-model=""
wasd-controls="wsEnabled:false;enabled:false"
look-controls="enabled: false">
<!-- CURSOR HOTSPOTS -->
<!-- TOP RIGHT -->
<a-sphere geometry="primitive: sphere"
cursor-hotpsot-1 sphere="2"
position="-3.5 0.1 2.0"
scale="0.250 0.250 0.250"
color="red"
id="hotspot_tr"></a-sphere>
<!-- BOTTOM LEFT -->
<a-sphere geometry="primitive: sphere"
cursor-hotpsot-1 sphere="2"
position="3.3 0.1 -2.3"
scale="0.250 0.250 0.250"
color="green"
id="hotspot_bl"></a-sphere>
<!-- CENTER TOP -->
<a-sphere geometry="primitive: sphere"
cursor-hotpsot-1 sphere="2"
position="-0.040 0.1 0.1"
scale="0.250 0.250 0.250"
color="blue"
id="hotspot_ct"></a-sphere>
</a-obj-model>
<a-camera active="true" spectator="true"
wasd-controls="wsEnabled:false;enabled:false"
look-controls="enabled: false"
zoom="2.4" position="0.28042 0.01891 -1.85751"
camera="zoom:1.5"
look-controls=""
camera="active:true"
data-aframe-inspector-original-camera=""
look-controls="enabled: false">
<a-animation attribute="position"
dur="2500"
fill="forwards"
from="0.2058 0.29058 -1.96409"
to="0 0 -1.5"
repeat="0">
</a-animation>
</a-camera>
</a-scene>
/////////////////////////////////////////////////
<script src="https://aframe.io/releases/0.9.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent('cursor-hotpsot-1', {
init: function () {
var COLORS = ['purple', 'green', 'blue'];
this.el.addEventListener('click', function (evt) {
var randomIndex = Math.floor(Math.random() * COLORS.length);
this.setAttribute('material', 'color', COLORS[randomIndex]);
console.log('Clicked:' + this);
});
}
});
</script>
<a-scene class="fullscreen"
inspector=""
keyboard-shortcuts=""
screenshot=""
vr-mode-ui="enabled: false"
cursor="rayOrigin: mouse">
<!--
<a-camera active="true" spectator="true"
wasd-controls="wsEnabled:false;enabled:false"
look-controls="enabled: false"
zoom="2.4"
position="0.3 0.0 -1.8"
rotation="0.0 132.5 0.0"
camera="zoom:1.5"
look-controls=""
camera="active:true"
data-aframe-inspector-original-camera=""
look-controls="enabled: false"></a-camera>
-->
<a-obj-model id="diagram"
position="-0.8 0 -3.5"
scale="0.2 0.2 0.2"
shadow=""
rotation="-90 180 0"
material="metalness: .5; src: #issTexture; src: #issTexture; " obj-model=""
wasd-controls="wsEnabled:false;enabled:false"
look-controls="enabled: false">
<!-- CURSOR HOTSPOTS -->
<!-- TOP RIGHT -->
<a-sphere geometry="primitive: sphere"
cursor-hotpsot-1 sphere="2"
position="-3.5 0.1 2.0"
scale="0.250 0.250 0.250"
color="red"
id="hotspot_tr"></a-sphere>
<!-- BOTTOM LEFT -->
<a-sphere geometry="primitive: sphere"
cursor-hotpsot-1 sphere="2"
position="3.3 0.1 -2.3"
scale="0.250 0.250 0.250"
color="green"
id="hotspot_bl"></a-sphere>
<!-- CENTER TOP -->
<a-sphere geometry="primitive: sphere"
cursor-hotpsot-1 sphere="2"
position="-0.040 0.1 0.1"
scale="0.250 0.250 0.250"
color="blue"
id="hotspot_ct"></a-sphere>
</a-obj-model>
<a-camera active="true" spectator="true"
wasd-controls="wsEnabled:false;enabled:false"
look-controls="enabled: false"
zoom="2.4" position="0.28042 0.01891 -1.85751"
camera="zoom:1.5"
look-controls=""
camera="active:true"
data-aframe-inspector-original-camera=""
look-controls="enabled: false">
<a-animation attribute="position"
dur="2500"
fill="forwards"
from="0.2058 0.29058 -1.96409"
to="0 0 -1.5"
repeat="0">
</a-animation>
</a-camera>
</a-scene>
Viewing the example with version 8 of A-FRAME will show three spheres that will appear towards the lower left screen. Version 9 will show nothing. I would expect version 9 to work as version 8 did.
a-animation has been deprecated in A-Frame 0.9.0 in favor of the animation component:
https://aframe.io/docs/0.9.0/components/animation.html#sidebar
The camera actualy moves but the visual representation remains in place. I filed a bug to to cover it:
https://github.com/aframevr/aframe-inspector/issues/582

Unable to Control Camera Position in VR on Oculus Go

I am using aframe to create an experience for Oculus Go. I have a simple "world" and I am able to move around it using the Oculus Go controller. However, I don't seem to be able to set the initial camera position or reset the camera location at any point. The initial problem means that my viewpoint is always close to the ground.
Here is my code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Pailou Gate</title>
<meta name="description" content="Pailou Gate">
<script src="../aframe/dist/aframe-master.js"></script>
<script src="//cdn.rawgit.com/donmccurdy/aframe-extras/v4.1.2/dist/aframe-extras.min.js"></script>
</head>
<body>
<a-scene background="color: #9cf" antialias="true">
<a-assets>
<a-asset-item id="pl" src="pl.dae"></a-asset-item>
</a-assets>
<a-entity wasd-controls mouse-controls look-controls movement-controls="fly: false" position="0 0 0">
<a-entity camera position="0 4 0"></a-entity>
<a-entity oculus-go-controls></a-entity>
<a-entity laser-controls="hand: right"></a-entity>
</a-entity>
<a-light position="0 0.5 1" intensity="0.8"></a-light>
<a-light type="point" position="20 30 -40" intensity="0.9" light="castShadow: true;"></a-light>
<a-collada-model src="#pl" position="0 0.4 0" rotation="0 0 0" scale="1 1 1" shadow="cast: true; receive: false"></a-collada-model>
<a-circle rotation="-90 0 0" radius="40" color="#393" position="0 -0.1 0" shadow="receive: true" roughness="1"></a-circle>
<a-torus radius="40" arc="360" color="#6c6" rotation="-90 0 0"></a-torus>
</a-scene>
</body>
</html>
I think the relevant bit is the entity surrounding the camera and the camera itself. Notice that I do set the camera high, but this seems to be ignored.
Any thoughts?
Sean
Set the position and movement controls on the camera rig (parent entity of the camera) and look-controls on the camera:
<a-entity wasd-controls position="0 4 0">
<a-entity camera look-controls></a-entity>
</a-entity>

Aframe - How to Retrieve the text from textarea in Aframe

I Am unable to retrieve the text from the textarea as I just want to scale a box by typing the x-factor as the input. But the input is not being retrieved for some reason. Please help!...here is the code:
<html>
<head>
<title>My A-Frame Scene</title>
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-textarea-component/dist/aframe-textarea-component.min.js"></script>
</head>
<body>
<a-scene>
<a-sky color="#6EBAA7"></a-sky>
<a-box id="redbox" position="3 2.5 -2" color="red"></a-box>
<a-entity position="0 1 -2" id="inputText" textarea="backgroundColor:white; color:black; cols:5; rows:1;value:2;"></a-entity>
<a-input postion="0 2 -2"></a-input>
<a-text id="outputText" position="0 2 -2" value="Hello"></a-text>
<a-camera position="0 1 1">
<a-cursor color="yellow"></a-cursor>
</a-camera>
<a-entity id="select-button" geometry="primitive: box" material="color:red" position="0 0 -2"></a>
</a-scene>
<script>
var box = document.querySelector('#redbox')
var printText = document.querySelector('#inputText');
document.querySelector('#select-button').addEventListener('click',function(){
box.setAttribute("scale",
{
x : parseInt(printText.getAttribute('textarea').value),
y : 1.5,
z : 1.5
}
);
});
</script>
</body>
</html>
Edit: I tried changing the code in javascript as follows:
parseInt(printText.getAttribute('textarea').text
It still does not work!!
The textarea component does not expose the value directly but you can do:
document.querySelector('#inputText').components.textarea.textarea.value
The latest version (0.3.0) of aframe-textarea-component now includes a getText() method which you can use to get the current text.
document.querySelector('#inputText').components.textarea.getText();

Resources