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>
Related
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>
I don't want to have my a-scene in fullscreen. I tried to add "embedded" to the scene and then change it with css but that does not work.
My html:
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="css/style.css">
<script src="aframe/aframe.js"></script>
<script src="js/aframe-ar.js"></script>
<script src="js/gestures.js"></script>
<body style="margin : 0px; overflow: hidden;">
<a-scene embedded arjs renderer="logarithmicDepthBuffer: true;" gesture-detector
id="scene">
<a-marker type="pattern" preset="custom" url="/pattern/ifgi-pattern.patt" id="a-marker">
<a-entity position="0 0 0" scale="0.8 0.8 0.8" gltf-model="/gltf/car_model/scene.gltf" class="clickable"
gesture-handler="minScale: 0.25; maxScale: 10" id="a-entity"></a-entity>
</a-marker>
<a-entity camera id="camera">
</a-scene>
<script src="js/main.js"></script>
</body>
</html>
and my css:
.a-scene { display: block; width: 50%; }
Does anyone knows how to solve this? I just want to add a bootstrap navbar but the scene always overlaps the navbar.
Thanks for your help!
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!
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
I Want To Show A Preloading Screen Till All Assets Loads And Renders.
I Tried Using Assets Event loaded but its not working . When We Augment 3d Model , Image and video , So These Assets Are Almost 50-60mb . So it takes time to load the assets and augment . The video when we augment for 4-8 seconds the black screen comes and plays,if the network is slow (In inspect Network Tab Select 3G Slow We Test).
Please Edit My Code in Glitch
<!DOCTYPE html>
<html lang="en">
<head>
<title>Hello!</title>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<script type="text/javascript" src="https://aframe.io/releases/0.8.2/aframe.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/jeromeetienne/AR.js/1.7.2/aframe/build/aframe-ar.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/donmccurdy/aframe-extras/v6.0.0/dist/aframe-extras.min.js"></script>
<script src="https://unpkg.com/aframe-animation-component#5.1.2/dist/aframe-animation-component.min.js"></script>
<script>
AFRAME.registerComponent("vidhandler", {
init: function () {
// Set up initial state and variables.
this.toggle = false;
this.vid = document.querySelector("#vid");
this.vid.pause();
console.log('************* Vid Paused');
},
tick: function () {
if (this.el.object3D.visible == true) {
if (!this.toggle) {
this.toggle = true;
this.vid.play();
console.log('************* Vid Play');
}
} else {
this.toggle = false;
this.vid.pause();
//console.log('************* Vid Paused');
}
}
});
</script>
</head>
<body>
<a-scene vr-mode-ui="enabled: false" artoolkit='sourceType: webcam; detectionMode: mono; maxDetectionRate: 90;' arjs='debugUIEnabled: false;detectionMode: mono_and_matrix; matrixCodeType: 3x3;'>
<!-- ALL ASSETS -->
<a-assets>
<!-- 3D MODEL -->
<a-entity id="model" src="https://cdn.glitch.com/c3106e6c-98cb-40e4-b0c1-85257680d25a%2Fygark.glb?v=1564472468760" crossorigin="anonymous" rotation="-90 0 -90">
</a-entity>
<!-- VIDEO -->
<video preload="auto" id="vid" response-type="arraybuffer" loop="false" crossorigin webkit-playsinline playsinline controls>
<source src="https://cdn.glitch.com/c3106e6c-98cb-40e4-b0c1-85257680d25a%2Fvid.mp4?v=1564472320471" type="video/mp4">
</video>
<!-- IMAGE -->
<img id="img" src="https://cdn.glitch.com/c3106e6c-98cb-40e4-b0c1-85257680d25a%2Fsun.png?v=1564472507237">
</a-assets>
<!-- ALL ASSETS -->
<a-marker type="pattern" preset="hiro" vidhandler>
<a-entity position="0 0 0">
<a-video width="2" height="2" rotation="-90 0 0" material='transparent:true;shader:flat;side:double;src:#vid'></a-video>
</a-entity>
<a-image width="2" height="2" material='transparent:true;shader:flat;side:double;src:#img' position="2 0 0" rotation="-90 0 0"></a-image>
<a-entity position="-1.5 0 0" gltf-model="#model" material='transparent:true;shader:flat;side:double;metelness:2' rotation="0 0 0" scale="0.5 0.5 0.5" shadow="receive: false" >
</a-entity>
</a-marker>
<a-entity camera>
<a-entity cursor="rayOrigin: mouse;fuse: false;"></a-entity>
</a-entity>
</a-scene>
</body>
</html>
Asset loaded event is not working . Please Edit My Code in Glitch
Thanks In Advance
There are a couple different options.
Aframe has a built in loading screen that is enabled within the <a-scene> declaration
<a-scene loading-screen="dotsColor: red; backgroundColor: black"></a-scene>
Another option is to follow the steps in the response from Noam Almosnino
Use a component like, Aframe Preloader
Note: I am not associated with this component and have not tested it. Please see the demo page for some examples
Update
Based on your comment (below) I would recommend #2 (above)
create a listener for the scene's loaded event
document.addEventListener('DOMContentLoaded', function() {
var scene = document.querySelector('a-scene');
scene.addEventListener('loaded', function (e) {
// hide splash screen
});
});