I have an A-Frame scene that I want to place on a page, but I want it to load only when I tell it to. That means it should not be rendering or running until I emit an event or call a method.
<body>
<!-- Don't play yet. -->
<a-scene>
</a-scene>
</body>
There is currently no built-in + documented way, but there will be a feature for this later. However, there are a couple ways to do this manually:
Create <a-node>
Nodes (which every <a-entity> inherits from will block the scene from loading until it calls the .load() event.
Create a dummy node in the scene. and call .load() when ready.
<a-node id="dummy"></a-node>
document.getElementById('dummy').load();
Leverage asset system
You can create an asset that will never load until you tell it to, and set the timeout to effectively indefinite (later we will add a feature to not timeout).
<a-scene>
<a-assets timeout="999999999">
<a-asset-item id="trigger" src="NEVERLOADUNTILITELLITTO.whatever"></a-asset-item>
</a-assets>
</a-scene>
Then trigger.
document.querySelector('#trigger').load();
Inject scene only when ready
You could keep your scene in a separate file, template, or as a string, or using a framework with concept of Views. Only inject the scene into the DOM when you are ready for it to render. This is the most work, but currently the most air-tight method.
sceneEl.appendChild(document.createRange().createContextualFragment(str));
Pause the scene as soon as you can
This will pause the scene from rendering. However, the scene will probably have initialized some components and rendered a few frames already. So it is not air-tight.
document.querySelector('a-scene').pause();
Related
By default the Networked A-Frame component for A-Frame uses LERPing to smooth the animation between position and rotation updates for objects synced through the networked component. I'd like to disable that feature but the docs show a syntax example of NAF.options.useLerp which isn't an attribute that I can set on the networked-scene component which instead looks like this:
<a-scene networked-scene="
room: handcontrollers;
debug: true;
">
Where do I put the NAF.options.useLerp command to disable LERPing?
This code goes in a JavaScript tag anywhere in your page source after you import networked-aframe.
Simplified example that worked for me inside of <head> tag:
<script>window.NAF || document.write('<script src="https://unpkg.com/networked-aframe/dist/networked-aframe.min.js">\x3C/script>')</script>
<script>NAF.options.useLerp = false;</script>
In the following scene, I'm trying to understand why after clicking the sphere to switch cameras and cursors (via.removeAttribute/.setAttribute) still seems to swap back even if I click outside the sphere--even though the scene inspector shows no cursor or raycaster on firstCursorEl to cause the ghost click event. The test scene's at http://codepen.io/anon/pen/GWJrXe, let me know if I'm missing something important! (jhsu mentioned needing to bind render-target-loaded to wait for a loaded canvas element if .removeAttribute('cursor') was called on-init, but I'm assuming that doesn't need to happen on-click.) Here's what the entity HTML given by the inspector looks like after a swap, if it helps:
<a-entity print-onenter="" id="firstCursorEl" mixin="avatarCursor"></a-entity>
<a-entity print-onenter="" mixin="avatarCursor" id="secondCursorEl" raycaster="" cursor=""></a-entity>
Where firstCursorEl is a child of the starter camera, and secondCursorEl a child of the camera we swap to. Since secondCursorEl's cursor/raycaster are aimed away from the swap-button-sphere (unless they're somehow out of sync with the camera gaze's direction?), and firstCursorEl seems to have no such components, how does it still swap back?
This issue was fixed by Don McCurdy: https://github.com/aframevr/aframe/pull/2397 to implement cursor remove handlers.
You can use this build: <script src="https://rawgit.com/aframevr/aframe/84c6431/dist/aframe-master.min.js"></script> to pull it in until 0.5.1 or 0.6.0 is out.
I am doing setAttribute or $.attr() on entities in A-Frame. For example,
el.setAttribute('position', '2 2 2');
The position updates, but I don't see it updating in the HTML/DOM inspector. I just set <a-entity position> How come?
https://aframe.io/docs/0.3.0/components/debug.html
By default, for performance reasons, A-Frame does not update the DOM with component data. If we open the browser’s DOM inspector, we will see that many entities will have only the component name visible:
<a-entity geometry material position rotation></a-entity>
The component data is stored internally. Updating the DOM takes CPU time for converting component data, which is stored internally, to strings. However, when we want to see the DOM update for debugging purposes, we can attach the debug component to the scene. Components will check whether the debug component is enabled before trying to serialize to the DOM. Then we will be able to view component data in the DOM:
<a-entity geometry="primitive: box" material="color: red" position="1 2 3" rotation="0 180 0"></a-entity>
To manually serialize to DOM on demand:
<a-scene>.flushToDOM()
<a-entity>.flushToDOM()
If you wish to use an Inspector to debug, try the A-Frame Inspector. https://aframe.io/docs/0.3.0/guides/using-the-aframe-inspector.html . Just open a scene and press <ctrl> + <alt> + i.
While trying to load a Bitmap onto a SWFLoader the Event.COMPLETE event is not being triggered
mySWFLoader.source = new Bitmap(Bitmap(someEvent.content).bitmapData);
but if I use a URL as source the complete event is triggered:
mySWFLoader.source = "http://example.com/123.jpg";
Is there some kind of restriction while using Bitmap as source?
I believe if you use data that already exists in memory (which your Bitmap would) then no load operation would happen. It should be usable immediately after construction. I know attaching movies in AS2 worked like that. If it was part of the library you could use it right away and no loading events would happen.
Use
mySWFLoader.addEventListener(Event.ADDED,handleSwfLoadComplete);
It fires when the content is actually created and added to the display list.
I encountered the same issue. The problem is that when you use Bitmap or Class as source, the content is populated only after the Bitmap or class was instantiated.
This happens in swfLoader.loadContent which eventually adds the newly created content to the displayList as the loader's child, and eventually dispatches the ADDED event.
I've got the following MXML tag:
<mx:Image id="image" width="100%" height="100%"
source="#Embed('../assets/Test.swf')"
complete="completeHandler(event)"
progress="progressHandler(event)"/>
But for some reason my completeHandler / progressHandler functions aren't being called. The reason I need the complete event is because I want to manipulate the bitmap data once the image has loaded. In creationComplete the bitmap data is still null. Why aren't these events firing?
Edit: The asset is correctly showing in my application - so I know the asset is in the right location (the embed guarantees that at compile time anyway).
Check your asset path. Most probably, the swf is not at the right path or is not getting copied to an assets folder in the debug-build/release-build directory.
So, you just have to add the Event.COMPLETE listener to the loader.contentLoaderInfo directly instead of to the loader. I can't believe this isn't int he docs.
If you're using an embedded asset, the width / height properties are available immediately on the source object:
var mySource:Object = new embeddedClass();
m_myWidth = mySource.width;
m_myHeight = mySource.height;
m_image = new Image();
m_image.source = mySource;
So, you have to create an instance of the source first, then set the source on your image object.
That seems to be the expected behavior here!
From the documentation:
The progress event is not guaranteed to be dispatched. The complete event may be received, without any progress events being dispatched. This can happen when the loaded content is a local file.
So I think this part can explain why no progress events are being caught in your example.
Dispatched when content loading is complete. Unlike the complete event, this event is dispatched for all source types.
Note that for content loaded via Loader, both ready and complete events are dispatched.
For other source types such as embeds, only ready is dispatched.
It clearly says that you should listen for READY events instead of COMPLETE when dealing with embedded sources ;)