A-frame detect when scene is loaded - javascript

I have a scene using A-frame set up with a few assets that require a loading screen before entering the scene. What I'm wondering is how can I detect by logging a message in the console when my assets/scene has loaded? Code for a basic scene:
<html>
<head>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
</head>
<body>
<script>
//When scene is loaded
console.log ("loaded");
</script>
<a-scene>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
</body>
</html>

Listen for this event on the scene element:
https://aframe.io/docs/1.2.0/core/scene.html#events_loaded
Sample code...
<html>
<head>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script>
AFRAME.registerComponent("log", {
init: function () {
this.el.addEventListener("loaded", () => {
console.log ("loaded");
});
}
});
</script>
</head>
<body>
<a-scene log>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4"></a-plane>
<a-sky color="#ECECEC"></a-sky>
</a-scene>
</body>
</html>

Related

A-frame set websubsurface source to a variable

I am using the websurface A-frame component () and I'm wondering how I can make it so when a button is clicked, the url of the websurface will change to the value of a variable I've defined called source. What should happen is for example, if the variable source is set to "https://google.ca" and you click the button, the websurface url will change to https://google.ca. Current code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Example 1</title>
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-websurfaces#1.4.0/dist/aframe-websurfaces.umd.js"></script>
<script>
function updateSource() {
let source = "https://google.ca";
}
</script>
</head>
<body>
<button style="position: fixed; z-index: 100000;" onclick="updateSource()">
update src
</button>
<a-scene>
<!--Camera-->
<a-entity
wasd-controls="acceleration: 20;"
camera="active: true"
look-controls="pointerLockEnabled: false"
position="0 1.6 0"
>
<a-cursor position="0 0 -.05" scale=".04 .04 1"></a-cursor>
</a-entity>
<!--Environment-->
<a-sky color="#aff"></a-sky>
<a-plane
rotation="-90 0 0"
width="20"
height="20"
color="#3fa841"
></a-plane>
<!--Websurface-->
<a-entity
websurface="url:https://aframe.io/; width:4; height:2;"
position="2.25 1.5 -4"
></a-entity>
</a-scene>
</body>
</html>
Fiddle with code: https://jsfiddle.net/AidanYoung/7vye3osa/2/
The component is using an i-frame accessible with the reference:
element.websurface_iframe
You can use it like any other i-frame - like changing the src property:
<script src="https://aframe.io/releases/1.2.0/aframe.min.js"></script>
<script src="https://unpkg.com/aframe-websurfaces#1.4.0/dist/aframe-websurfaces.umd.js"></script>
<script>
function updateSource() {
let source = "https://threejs.org";
const websurfaceEl = document.querySelector("[websurface]")
websurfaceEl.websurface_iframe.src = source
}
</script>
<button style="position: fixed; z-index: 100000;" onclick="updateSource()">
update src
</button>
<a-scene>
<a-entity websurface="url:https://aframe.io/; width:4; height:2;"
position="0 1.6 -2"></a-entity>
</a-scene>
Keep in mind - the originating server may not welcome requests from other origins - like https://google.ca which explicitly tells you, that only websites from the same origin may display it in a frame (check the logs in the snippet below):
X-Frame-Options' to 'sameorigin'
<div>
<iframe src="https://google.ca" width="500" height="250">
</div>

A-frame add enable/disable component on function

I have created a scene using A-frame (https://aframe.io) and I currently have some rain in my scene and a button. What I would like to do is when the button is clicked, a function occurs, I'm wondering how I can make this function remove the rain component from the scene. Code:
<head>
<script src="https://cdn.rawgit.com/aframevr/aframe/v0.4.0/dist/aframe-master.min.js"></script>
<script src="https://rawgit.com/takahirox/aframe-rain/master/build/aframe-rain.min.js"></script>
</head>
<body>
<button onclick="toggleRain()">
Toggle rain
</button>
<a-scene rain>
<a-entity position="0 0 10">
<a-camera></a-camera>
</a-entity>
<a-entity geometry="primitive:sphere"></a-entity>
<a-sky color="#222"></a-sky>
<a-entity light="type:directional;color:#666" position="-10 -10 -10"></a-entity>
</a-scene>
</body>
What I would like to happen is when the toggleRain() function is triggered, the
<a-scene rain> part of the code will change and remove the rain part so there is just
<a-scene>
This should stop the rain from falling when the button is clicked. Just to clarify, when the function is triggered, it should rain property from the <a-scene rain> leaving just
<a-scene>
How can this be done? Link to fiddle containing code: https://jsfiddle.net/AidanYoung/z7qstgua/2/
You could just use removeAttribute() to remove the rain
function toggleRain() {
let a = document.getElementById('a');
if (a.hasAttribute('rain')) {
a.removeAttribute('rain');
} else {
a.setAttribute('rain', '1');
}
console.log ("ok");
}
<head>
<script src="https://cdn.rawgit.com/aframevr/aframe/v0.4.0/dist/aframe-master.min.js"></script>
<script src="https://rawgit.com/takahirox/aframe-rain/master/build/aframe-rain.min.js"></script>
</head>
<body>
<button onclick="toggleRain()">
Toggle rain
</button>
<a-scene id="a" rain>
<a-entity position="0 0 10">
<a-camera></a-camera>
</a-entity>
<a-entity geometry="primitive:sphere"></a-entity>
<a-sky color="#222"></a-sky>
<a-entity light="type:directional;color:#666" position="-10 -10 -10"></a-entity>
</a-scene>
</body>

Aframe issues with interactable components and a random function

I'm trying to create a entity in my Aframe's scene that once clicked bring me in another of my random pages.
I'm a newbie, so my code is a patchwork that sometimes works and other times doesn't. I used this addon (https://github.com/silverslade/aframe_blender_exporter) to translate my 3d Blender scene in an "Aframe" page. It worked very well and this is my result with added javascript lines
<head>
<title>WebXR Application</title>
<link rel="icon" type="image/png" href="index/favicon.ico"/>
<meta name="description" content="3D Application">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://aframe.io/releases/1.0.4/aframe.min.js"></script>
<script src="https://cdn.jsdelivr.net/gh/donmccurdy/aframe-extras#v6.1.0/dist/aframe-extras.min.js"></script>
<script type="text/javascript" src="index/js/webxr.js"></script>
<script type="text/javascript" src="index/js/joystick.js"></script>
<script type="text/javascript" src="index/js/camera-cube-env.js"></script>
<script>
AFRAME.registerComponent('navigate-on-click', {
schema: {
url: {default: ''}
},
init: function () {
var data = this.data;
var el = this.el;
el.addEventListener('click', function () {
window.location.href = data.url;
});
}
});
</script>
<script>
var urls = [
"http://www.findyourface.it/AuroraReinhard/AuroraReinhard.html",
'http://www.findyourface.it//NikideSaintPhalle/NikideSaintPhalle.html',
'http://www.findyourface.it/AmeliaEarthart/AmeliaEarthart.html'
];
function goSomewhere() {
var url = urls[Math.floor(Math.random()*urls.length)];
window.location = url; // redirect
}
</script>
<link rel="stylesheet" type="text/css" href="index/style.css">
</head>
<body onload="init();">
<a-scene shadow="type: basic; autoUpdate: false;">
<!-- Assets -->
<a-assets>
<a-asset-item id="Plane" src="./index/assets/Plane.gltf"></a-asset-item>
<a-asset-item id="segnalefreccia" src="./index/assets/segnalefreccia.gltf"></a-asset-item>
<img id="sky" src="./index/resources/sky.jpg">
<img id="icon-play" src="./index/resources/play.png">
<img id="icon-pause" src="./index/resources/pause.psng">
<img id="icon-play-skip-back" src="./index/resources/play-skip-back.png">
<img id="icon-mute" src="./index/resources/mute.png">
<img id="icon-volume-low" src="./index/resources/volume-low.png">
<img id="icon-volume-high" src="./index/resources/volume-high.png">
</a-assets>
<!-- Entities -->
<a-entity id="#Plane" gltf-model="#Plane" scale="1 1 1" position="0.0 0.0 -0.0" visible="true" shadow="cast: false" ></a-entity>
<a-entity animation-mixer id="#segnalefreccia" gltf-model="#segnalefreccia" scale="0.25 0.25 0.25" position="0.0 0.0 -10.0" visible="true" shadow="cast: false" onClick="goSomewhere(); return false;" ></a-entity>
<!-- Camera -->
<a-entity id="player"
position="0 -0.2 0"
movement-controls="speed: 0.10000000149011612;">
<a-entity id="camera"
camera="near: 0.001"
position="0 1.7000000476837158 0"
look-controls="pointerLockEnabled: true">
<a-entity id="cursor" cursor="fuse: false;" animation__click="property: scale; startEvents: click; easing: easeInCubic; dur: 50; from: 0.1 0.1 0.1; to: 1 1 1"
position="0 0 -0.1"
geometry="primitive: circle; radius: 0.001;"
material="color: #CCC; shader: flat;"
>
</a-entity>
</a-entity>
<a-entity id="leftHand" oculus-touch-controls="hand: left" vive-controls="hand: left"></a-entity>
<a-entity id="rightHand" laser-controls oculus-touch-controls="hand: right" vive-controls="hand: right" ></a-entity>
</a-entity>
<!-- Lights -->
<a-entity light="intensity: 10; shadowBias: -0.001; shadowCameraFar: 501.02; shadowCameraBottom: 12; shadowCameraFov: 101.79; shadowCameraNear: 0; shadowCameraTop: -5; shadowCameraRight: 10; shadowCameraLeft: -10; shadowRadius: 2; angle: 180; decay: 1.3; type: spot; distance: 4.41; penumbra: 0.01" position="0 3.53829 -9.8453"></a-entity>
<!-- Sky -->
<a-sky color="#000000"></a-sky>
</a-scene>
</body>
The first time you open the scene you have to click on it a lot of times but it eventually works, but in the following pages it stops working altogether. I think it’s because this is a Frankenstein monster of a code, but I didn't find a better way to make it.
Thank you for helping!

A-Frame: change "visible" with set.Attribute

I have several entities in my a-scene and I want to hide them, if I click on a button.
That my JS for changing the attribute "visible":
<script>
document.querySelector('#button-right').addEventListener('mouseclick',myEventHandler);
myEventHandler: function (evt) {
let myEl = document.querySelector("#links");
myEl.setAttribute('visible',"false");
}
</script>
The script should be executed if "button_right" is clicked:
<!-- left and right button: button-left = reset background // button-right = hide links -->
<a-entity id="buttons" layout="type: line; margin: 2.5" position="-1.75 -2.5 -4">
<a-entity id="button-left" template="src: #button_reset" data-src="#default"></a-entity>
<a-entity id="button-right" template="src: #button_hide"></a-entity>
</a-entity>
If I click the right button I get this error:
Uncaught DOMException: Failed to execute 'setAttribute' on 'Element':
'0' is not a valid attribute name.
at HTMLElement.setAttribute (http://127.0.0.1:5500/assets/js/aframe-master.js:77507:51)
at HTMLElement.setAttribute (http://127.0.0.1:5500/assets/js/aframe-master.js:76931:40)
at NewComponent.module.exports.setComponentProperty (http://127.0.0.1:5500/assets/js/aframe-master.js:83857:6)
at HTMLElement.s (https://unpkg.com/aframe-event-set-component#5.0.0/dist/aframe-event-set-component.min.js:1:1990)
at HTMLElement.emit (http://127.0.0.1:5500/assets/js/aframe-master.js:77546:16)
at NewComponent.twoWayEmit (http://127.0.0.1:5500/assets/js/aframe-master.js:68002:19)
at NewComponent.onCursorUp (http://127.0.0.1:5500/assets/js/aframe-master.js:67858:12)
at HTMLCanvasElement.bound (http://127.0.0.1:5500/assets/js/aframe-master.js:83391:17)
Here is the full code:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>360° Image</title>
<meta name="description" content="360° Image - A-Frame">
<script src="assets/js/aframe-master.js"></script>
<script src="assets/js/play-all-model-animations.js"></script>
<script src="https://unpkg.com/aframe-template-component#3.x.x/dist/aframe-template-component.min.js"></script>
<script src="https://unpkg.com/aframe-layout-component#4.3.1/dist/aframe-layout-component.min.js"></script>
<script src="https://unpkg.com/aframe-event-set-component#5.0.0/dist/aframe-event-set-component.min.js"></script>
</head>
<body>
<a-scene>
<a-assets>
<!-- background images -->
<img id="oberkirch" src="assets/image/oberkirch.jpg" alt="360 Degree view of the City Oberkirch">
<img id="schauenburg" src="assets/image/schauenburg.JPG" alt="360 Degree view of the Schauenburg">
<img id="city" src="assets/image/360_background.jpg" alt="360 Degree view of a city">
<img id="default" crossorigin="anonymous" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/city.jpg">
<img id="city-thumb" crossorigin="anonymous"
src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/thumb-city.jpg">
<!-- Template for links -->
<script id="circle" type="text/html">
<a-entity class="link"
geometry="primitive: circle; height: 1; width: 1"
material="color: blue"
visible="true"
event-set__mouseenter="material.color: red"
event-set__mouseleave="material.color: blue"
event-set__click="_target: #image-360; _delay: 300; material.src: ${src}"
proxy-event="event: click; to: #image-360; as: image"
></a-entity>
</script>
<!-- Template for button_reset -->
<script id="button_reset" type="text/html">
<a-entity class="button"
geometry="primitive: plane; height: 0,5; width: 1s"
material="color: blue"
event-set__mouseenter="material.color: red"
event-set__mouseleave="material.color: blue"
event-set__click="_target: #image-360; _delay: 300; material.src: ${src}"
proxy-event="event: click; to: #image-360; as: image"
></a-entity>
</script>
<!-- Template for button_hide -->
<script id="button_hide" type="text/html">
<a-entity class="button"
geometry="primitive: plane; height: 0,5; width: 1s"
material="color: blue"
event-set__mouseenter="material.color: red"
event-set__mouseleave="material.color: blue"
event-set__click="_target: #link; link.setA"
></a-entity>
</script>
<!-- Script for hiding the links -->
<script>
document.querySelector('#button-right').addEventListener('mouseclick', myEventHandler);
myEventHandler: function (evt) {
let myEl = document.querySelector("#links");
myEl.setAttribute('visible', "false");
}
</script>
</a-assets>
<!-- Change the background of the scene -->
<a-sky id="image-360" radius="10" src="#default"></a-sky>
<!-- Creates a cursor -->
<a-camera>
<a-cursor id="cursor"
animation__click="property: scale; startEvents: click; from: 0.1 0.1 0.1; to: 1 1 1; dur: 150">
</a-cursor>
</a-camera>
<!-- Links for changing the background -->
<a-entity id="links" visible="true" layout="type: line; margin: 2.5" position="-3 -1 -4">
<a-entity template="src: #circle" data-src="#oberkirch"></a-entity>
<a-entity template="src: #circle" data-src="#schauenburg"></a-entity>
<a-entity template="src: #circle" data-src="#city"></a-entity>
</a-entity>
<!-- left and right button: button-left = reset background // button-right = hide links -->
<a-entity id="buttons" layout="type: line; margin: 2.5" position="-1.75 -2.5 -4">
<a-entity id="button-left" template="src: #button_reset" data-src="#default"></a-entity>
<a-entity id="button-right" template="src: #button_hide"></a-entity>
</a-entity>
</a-scene>
</body>
</html>
Thank you!
myEl.setAttribute('visible',false);
Here true and false is a boolean value so you don't need to add as a "false" in string.
Use single quotes ('#links')
And maybe try not to use numbers for id

Reset orientation does not work in phone

I want reset head orientation. I did but that works in PC but not in phone. There is a button called reset. If I click that it should reset the head orientation. It does on PC but not on phone. Here is my code:
<!DOCTYPE html>
<html>
<head>
<title>Hello, WebVR! - A-Frame</title>
<meta name="description" content="Hello, WebVR! - A-Frame">
<script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script>
<script src="https://rawgit.com/rdub80/aframe-gui/master/dist/aframe-gui.min.js"></script>
<script src="script.js"></script>
</head>
<body>
<a-scene>
<a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow></a-box>
<a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere>
<a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow></a-cylinder>
<a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow></a-plane>
<a-gui-button resetorientation
id="reset"
class="clickable"
position="-0.038 -1.611 -3.011"
rotation="-25 0 0"
width="2.5" height="0.75"
key-code="80"
value="Reset"
font-family="Helvetica"
background-color="#A04000"
>
</a-gui-button>
<a-sky color="#ECECEC"></a-sky>
<a-camera position="0 2 0">
<a-cursor raycaster="objects: .clickable" ></a-cursor>
</a-camera>
</a-scene>
</body>
</html>
Here is my script:
AFRAME.registerComponent('resetorientation', {
init: function () {
this.el.addEventListener('click', function () {
document.querySelector('#reset').emit(reset());
});
}
});
function reset(){
var x = document.querySelector('[camera]').getAttribute('rotation').x;
var y = document.querySelector('[camera]').getAttribute('rotation').y;
console.log(x);
console.log(y);
document.querySelector('[camera]').setAttribute('rotation', {x: 0 * x});
document.querySelector('[camera]').setAttribute('rotation', {y: 0 * y});
var a = document.querySelector('[camera]').getAttribute('rotation').x;
var b = document.querySelector('[camera]').getAttribute('rotation').y;
console.log(a);
console.log(b);
}
You would need to get into the look-controls and manually add an offset to the x-y-z rotations it gets from the gyroscope.
A workaround making sense with only the yaw (y) value, would be wrapping the camera in an entity, and when you click reset, you rotate the wrappers yaw.
Live fiddle here.

Categories