supermedium / aframe-react Goto Github PK
View Code? Open in Web Editor NEW:atom: Build virtual reality experiences with A-Frame and React.
Home Page: https://ngokevin.github.io/aframe-react-boilerplate/
License: MIT License
:atom: Build virtual reality experiences with A-Frame and React.
Home Page: https://ngokevin.github.io/aframe-react-boilerplate/
License: MIT License
When my React app re-renders some of my components, some of the <Entities>
seem to lose their geometry, turning into 1x1x1 boxes. They also turn blue, for some reason.
I'm unclear on the exact circumstances, but these entities always reside deep in the component hierarchy and possibly have events bound to them.
I've managed to jury rig together an example of this happening by stripping down my app as much as possible, but you'll sadly need to jump through some hoops:
This is an early build of a hex-based game. What's happening is that the green box is moving onto the hex you clicked, meaning React is:
If you open the A-Frame inspector, you can see all mounted hexes with IDs like clickable-thing-x-y
. And here's the source of the React component containing the hex <Entity>
: https://github.com/jonikorpi/world/blob/blue-box-debugging/components/Action.js#L162
I've had this issue for months but haven't filed an issue since I can't pinpoint what makes it occur. Let me know if I can do anything else to help figure this out.
P.S. This issue could be related? #57
Would like to be able to create something like:
<Light type="directional"/>
while still being able to mix in arbitrary components:
<Light type="directional" geometry="primitive: sphere" material={sphereColor}/>
Can do this by having a React component that detects a main schema and expanding the properties of the schema onto the main component, and then applying the rest of the components as attributes.
<a-entity light="{lightSchemaProperties}" {...otherComponents}>
Hello, Im trying to put some text on my aframe-react project but the following:
<Entity bmfont-text={{text: 'HELLO WORLD'}} position="{[0, 1, -5]}"/>
Does nothing... I have the components imported as necessary and I dont receive any errors.. it just does not render. I have also tried this with the standard text-component as part of kframe. Same result.
<Scene id="sceneobj" stats physics="debug: true" >
<Scene id="sceneobj" stats physics={{debug: 'true'}} >
Currently, there's no support for this in aframe-react and going back to 'a-animation' tag doesn't work well either because there's no setAttribute/removeAttribute for dynamic props.
Doing some testing with this and was not able to stop an animation by removing it from the DOM.
onEnter(){
this.setState({animate:true});
},
onExit(){
this.setState({animate:false});
},
render() {
let animate = this.state && this.state.animate ? (<Animation attribute="rotation" dur="5000" to="0 360 360"/>) : false;
...
<Entity onMouseEnter={this.onEnter} onMouseLeave={this.onExit} geometry={{primitive: 'box'}} material="color: red" position="0 0 -5">
{animate}
</Entity>.... ```
The check for which entity prop names to skip calling setAttribute
on is currently broken in v4.0.2, resulting in entities with children having children="[object Object]"
attributes set on them, amongst other things.
The indexOf
check in
function doSetAttributes (el, props) {
// Set attributes.
const nonEntityPropNames = ['children', 'events', 'primitive'];
Object.keys(props).filter(
propName => propName.indexOf(nonEntityPropNames) === -1
).forEach(propName => { doSetAttribute(el, props, propName); });
}
needs to be reversed.
I'll submit a pull request to fix this soon.
I just updated my A-Frame app's aframe-react
version from 3.5.0 to 4.2.4. I believe I have made all the changes required from the upgrade (events, vector properties, _ref), although the lack of a changelog makes it hard to say exactly.
I have everything working as it did before I updated aframe-react
, except for one thing: I have a menu that can be toggled on and off. The menu is initially visible, and initially raycaster events such as click
and mouseover
work fine. However, when I toggle the menu off and on again the raycaster events are no longer triggered in 4.2.4. If I roll back to 3.5.0 - all other code and dependencies being equal - it works again.
I don't toggle the visibility of the menu being setting the visible
property. Instead I pass a prop to the React component rendering the menu telling it whether it should render or not. If the prop is true
, the component returns an <Entity>
, if it is false
, it returns null
. This setup is due to a number factors, related to how I use Redux to manage state and use of animations.
For performance reasons I have the configured the raycaster to only intersect with specific elements:
<Entity
primitive="a-cursor"
raycaster='objects: .interactable'
/>
If I remove raycaster='objects: .interactable'
, the menu works every time, but I get worse performance.
I have reproduced the issue here:
https://www.webpackbin.com/bins/-KkkMiVwnvG9MVsuq0us
The box toggles a sphere (a stand-in for the menu in my actual code). The first time the sphere is shown, it changes color when clicked. Once it has been hidden and is shown again, it no longer changes color.
From debugging, it seems like the Three.js raycaster simply doesn't match the sphere on subsequent renders. I just can't figure out how any of changes made in aframe-react
affects this. It doesn't seem to be related to the changes event system, since the problem is the same if I manually attach event handlers to the element. Rather, it seems like the intersected elements are somehow cached, or like the className
is not properly included on subsequent renders.
But I have nothing solid, just this example reproducing the issue above. Any help would be appreciated.
I'm getting UNMET PEER DEPENDENCY when trying to use with the latest react.
are there any breaking changes that would make it not work with newest react?
I'll try to bump versions and see for myself, can PR if I get it to work
As from the docs, following this pattern:
<Entity ref="box" geometry="primitive: box" material="opacity: 1">
<Animation attribute="material.opacity" begin="fade" to="2 2 2" />
</Entity>
this.refs.box.emit("fade");
Uncaught TypeError: _this.refs.box.emit is not a function
How does one properly implement this?
To recreate this bug, pull my repo here: https://github.com/cakenggt/bonsai/tree/block-missing-bug then do npm install
and npm start
and you can view the display on localhost:4000
To start out with, you will probably want to move back from the scene by holding down s
. Every time you click in the scene, a new block is supposed to be attached to the existing tree (don't click on the existing blocks for this test, as multiple blocks get added when you do that due to some other bug). Pretty reliably, a few clicks in, you will see some of the already-added blocks disappear, which should not happen as Entities are only being added.
If you then go into aframe inspector with ctrl
+alt
+i
, you can see the entity tree looks like this
Notice that some of the Entities, particularly the highlighted one in the picture, have no geometry or material. However, in the react plugin for chrome, they appear to have been added normally with the correct material and geometry components.
I am unsure what the problem is, and have tried to condense the code down in that bug branch so that all of the necessary code is in app/components/treeView.jsx
It's unclear to me how we use the asset management system- when combining these two abstractions. Like in here, for example, we're using a reference id- if we were using React, seems like we'd want the a-assets to be its own component. https://github.com/aframevr/aframe/blob/master/examples/boilerplate/360-video/index.html
I like the concept of the type of coding patterns that aframe-react allows us to use in defining 3D scenes,
but it seems like there is a performance concern: props (f.e. position
) can be passed to the React components as arrays of numbers, which get converted into strings to be passed into the custom elements, which get converted back into numbers for use internally by A-Frame/Three.js.
That 3-step conversion will happen on every tick while animating a component's prop
like position
repeatedly.
Is it something to be concerned about? How do you recommend handling animations?
Cannot find module 'react/lib/ReactDefaultInjection' from 'index.test.js'
I seem to not be able to get a simple PLY model loaded up. This is one of the stock models that comes with MagicaVoxel. My network traffic shows the file getting loaded. It does indeed appear to be downloaded correctly by the browser, but no rendering occurs. Aframe inspector shows that an entity does indeed exist.
First I import extras like this: import 'aframe-extras';
Then I added my model as an asset
<a-assets>
<a-asset-item id="castle" src="/assets/castle.bake.ply"></a-asset-item>
</a-assets>
Finally I add it to the scene, using Entity
<Entity plyModel="src: #castle" rotation="-90 0 0" position="0 0 0" />
Any obvious issues here?
I think we need to create elements for: a-asserts
, a-assert-item
, audio
, img
, video
https://aframe.io/docs/0.4.0/core/asset-management-system.html
Those can't be created with Entity
.
For example:
const material = {color: 'red', side: 'double'}
<Entity material={{metalness: 1, roughness: 0}} {...material}/>
That should combine all the material component properties together. Currently, the second instance of material will overwrite the first one.
Hi,
I'm working on a small aframe-react app where I need to update different geometry attributes via react state (like this: geometry={{ width: this.state.width }}
).
When I'm using the geometry.primitive property everything works as expected, but when I'm using Primitives or the aframe-react-components module, all aframe-primitives are getting updated to geometry={{ primitive: 'box' }}
when I update the react state.
This works as expected:
<Entity
geometry={{ primitive: 'plane', width: this.state.width, height: '2' }}
material={{color: 'blue' }}
position='-4 -1.5 -8'
onClick={this.changeWidth.bind(this)} />
This works onload, but when I update this.state.width
the geometry.primitive of the <a-plane />
-Element changes to 'box'
<Entity
primitive='a-plane'
geometry={{ width: this.state.width, height: '2' }}
material={{color: 'blue' }}
position='-4 2.5 -8'
onClick={this.changeWidth.bind(this)} />
I used the aframe-react-boilerplate to build a basic demo of the bug. The upper row uses aframe Primitives, the lower row uses the geometry.primitive property. Live Demo with v0.4.0 (Code)
onload | after this.setState({}) |
---|---|
![]() |
![]() |
Main purpose is to bring aframe to native apps and download assets into local storage.
Combining three.js/webgl with react native is not a new idea at all.
https://discuss.reactjs.org/t/webgl-in-react-native/2123
https://github.com/ProjectSeptemberInc/gl-react-native
http://jlongster.com/First-Impressions-using-React-Native
http://stackoverflow.com/questions/37167090/react-native-and-three-js-webgl-library-integration
I think aframe-reactnative would a great approach to connect to native device api and resolve the large assets long loading time issue.
@ngokevin Any suggestion?
Hi, any plan to fix the warning with React 15.5.0:
Warning: Accessing PropTypes via the main React package is deprecated. Use the prop-types package from npm instead
https://facebook.github.io/react/blog/2017/04/07/react-v15.5.0.html
In 15.5, instead of accessing PropTypes from the main React object, install the prop-types package and import them from there:
// Before (15.4 and below)
import React from 'react';
class Component extends React.Component {
render() {
return <div>{this.props.text}</div>;
}
}
Component.propTypes = {
text: React.PropTypes.string.isRequired,
}
// After (15.5)
import React from 'react';
import PropTypes from 'prop-types';
class Component extends React.Component {
render() {
return <div>{this.props.text}</div>;
}
}
Component.propTypes = {
text: PropTypes.string.isRequired,
};
Hello! I'm try to work some mouse look component but have a problem.
(component: https://github.com/alexrkass/no-click-look-controls)
When i try get canvas element i have undefined. but a-scene i get it perfectly.
var sceneEl = this.el.sceneEl;
var canvasEl = sceneEl.canvas;
console.log(canvasEl,sceneEl);
in react component i have:
<Scene className="aframebox" embedded={true} >
<a-entity camera no-click-look-controls="maxyaw:0.5π; maxpitch:0.2π;" ></a-entity>
<a-sky src="images/city.jpg" rotation="0 -130 0"></a-sky>
</Scene>
Thank u for any help!
I might be missing something fundamental here, but can you explain to me how event handlers are cleaned up in this lib?
I am getting an error when using conditional rendering where event listeners are trying to be added to a null element.
my fix is a change to the file lib/Index.js line 94. Wrap the event listeners for 'click' and 'loaded' in an if(el)
Currently tied to AFRAME.components
. Can't include A-Frame because of window
.
Hacking on a short hand library for using aframe react's primitives in aframe-react-components. Essentially mapping:
<Sphere radius={5} />
to
<Entity primitive='a-sphere' radius={5} />
which should map to
<a-sphere radius='5' />
But currently, the short hand properties provided by primitives are discarded, requiring a user to define with the full component mapping, like <Entity primitive='a-sphere' geometry={{ radius: 5 }} />
.
Is it possible to know these mappings for stock primitives? Dug around a bit, and couldn't seem to find a way to expose these via the AFRAME global. Still new to aframe-react, so I might be missing something, but if this sounds good (and it's possible to get these mappings), I'll work on a PR
Hey @ngokevin
I open this because I saw a user complaining about master being not syncronized with npm.
The potentiall issue could be that master is bug-free meanwhile the registry could have some bug (related with a-asset-items
or others...) If it's true.
For now I only can see that there's no diff between
diff
https://raw.githubusercontent.com/ngokevin/aframe-react/master/dist/index.js
vs
https://unpkg.com/[email protected]
unpkg
is a cdn of the npm registry
Well... going back to the issue, I would like to have the dist out of the repo basically for have the distribute version in a CDN and atomic (be able to re-create the dist version), as well we would have cleaner PRs.
I can see the benefit of having the dist in the repo as a shareable URL, but since there's options like unpkg
, we can provide this URLs as a direct asset.
Thanks!
PS: I didn't express very well on this issue :(
CODE: https://github.com/itsakt/aframe-react-test
Memory Usage
This sample code contains five 360 degree images. ( ~600KB - ~1.8MB, 8192x4096 )
Initial memory usage:
Google Chrome
After switching through five images
Google Chrome
My actual project has 24 images
After switching through 24 images
Google Chrome after 20 images (chrome tab crashed after that)
Firefox Developer Edition after 24 images.
EDIT: Memory usage also increases if I reload the page.
I'm wondering if you have any strong opinions on how this should work. It's inconvenient to have to convert a Vector3 into a string that a-frame can work with. Should this be handled by aframe-react? Or should this be some external utility function? Likewise for rotation and scale, maybe even color: convert RGB to Hex?
I currently do this:
let {x,y,z} = someVectorObject
position={`${x} ${y} ${z}`}
would be nice to be able to do this:
position={someVectorObject}
and/or
position={[x, y, z]}
How to use <Entity />
to show a 360 image? Is there any example? I have no idea by just looking into the document : https://aframe.io/docs/0.2.0/guide/
I'm making a few stupid, yet time consuming, mistakes with aframe-react. One of them is this code:
import { Component } from 'react'
import Avatar from '../components/Avatar'
class Avatars extends Component {
render () {
let members = this.props.members
return (
<div>
{members.map(member => {
return <Avatar key={member.id} id={member.id} name={member.name} photoUrl={member.photo_url}/>
})}
</div>
)
}
}
It works when I replace my stupid <div></div>
wrapper with <Entity></Entity>
, but with the code above, I got nothing rendered at all, and no error. It would be really nice with an exception explaining the problem and how to fix it.
It would be nice, if the Entity
component filters received props to exclude null
values and instead uses to the default A-Frame value. IMHO this would more conform with the way React handles null
values.
This would also make it simpler to add default props passed to entities. For example:
class Camera extends Component {
static defaultProps = {
position: null,
};
render() {
const { position } = this.props;
const camera = {
userHeight: 1.6,
};
return (
<Entity
position={position}
camera={camera}
look-controls
/>
);
}
}
At the moment this produces the following error at https://github.com/ngokevin/aframe-react/blob/master/src/index.js#L104:
Uncaught TypeError: Cannot read property 'constructor' of null
With a okay from you @ngokevin I could build a small PR for this.
We need a way to remove the events that get attached to the element.
<Entity
onMouseEnter={this.onMouseEnter}
onMouseLeave={this.onMouseLeave}
onClick={this.onClick}
>
I know Sky entity can be rendered like below:
<Entity geometry={{primitive: 'sphere', radius: 5000}} material={{color: props.color || '#73CFF0', shader: 'flat', src: '#sky'}} scale="1 1 -1"/>
But when I tried to render image instead of color, the image is not rendered.
<Entity geometry={{primitive: 'sphere', radius: 5000}} material={{ src: "./skyimage.png" }} scale="1 1 -1"/>
I wonder if it is possible to render Sky Entity with image using aframe-react.
For example, if I remove "geometry" prop from an Entity element, aframe-react doesn't call removeAttribute and the geometry stays. This seems to be an easy fix, or am I missing something?
I see there is a-model tag in the original a-frame.
a-model uses '.dae' data format.
Is it possible to render a-model using aframe-react?
I'm trying to run the "Anime UI" example from aframe on aframe-react, but I'm unable to load engine.dae. It just does not appear.
My Scene contains the following code:
<a-assets>
<a-asset-item id="engine" src="models/engine.dae" />
</a-assets>
<Entity primitive="a-entity" position="1.75 0 1.2" rotation="0 28 0">
<Entity primitive="a-camera" near="0.1" user-height="0" />
</Entity>
<Entity primitive="a-entity" position="0 0 -3">
<Entity primitive="a-collada-model" src="#engine" rotation="90 0 0" scale="18 18 18" />
</Entity>
Can anyone please tell me what I'm doing wrong and why the model is not appearing.
Thanks!
You wrote a cool text component, but I cant seem to get it to be wrapped since its not a primitive. Any suggestions on to how this would work?
Hey @ngokevin, what do you think of some API like:
render () {
return <Scene>
<Entity>
<div>
Hello World
</div>
</Entity>
</Scene>;
}
I'd be rather excited to do this if you can point me in the right direction. I'm not totally sure of the perf impact (the current method of blending WebGL and HTML seems to be a CSS trick), but might be fun
it looks like React is already adding the correct DOM to the tree, just need to make the aframe entity aware of the children.
I have some intuition on how to do this:
THREE.CSS3DObject
in update()
, bound to the plane's position and rotation, using the first child DOM element (which is what React creates for us)that sound right? any gotchas I'm missing?
Main source of inspiration is this comment and [the linked post](http://learningthreejs.com/blog/2013/04/30/closing-the-gap-between-html-and-webgl/
This code:
import {Entity} from 'aframe-react'
import {Component} from 'react'
class Avatars extends Component {
render () {
return (
<Entity>
</Entity>
);
}
}
results in this error: Uncaught ReferenceError: React is not defined
in the line where it tries to render <Entity>
. Seems like this component implicitly expects React to be imported be the parent component, as changing line 2 to import React, {Component} from 'react'
fixes the problem.
But that shouldn't really be necessary, should it?
When adding a raycaster and cursor component (to represent an <a-cursor>
) to an entity, the element gets created before mounted to the DOM, causing the raycaster component's this.el.sceneEl
to be undefined (as it has yet to be mounted), throwing an error and causing the scene to fail to render. A work around is to wait until the component is mounted to DOM and then adding more components, but this took some time to figure out. Similar to assumptions in #50 of when things are mounted and initialized, I wonder if there's a general way of handling this for all components.
import React, { Component, PropTypes } from 'react';
import { Entity } from 'aframe-react';
class CameraComponent extends Component {
constructor() {
super();
this.state = {
mounted: false,
};
}
componentDidMount() {
this.setState({ mounted: true });
}
render() {
const mountedProps = {};
if (this.state.mounted) {
mountedProps.cursor = 'maxDistance: 100; fuse: true; fuseTimeout: 1000'
};
return (
<Entity id='camera-container' {...this.props}>
<Entity camera>
<Entity
{...mountedProps}
raycaster='objects: .action'
geometry='primitive: plane'>
</Entity>
</Entity>
</Entity>
);
}
};
export default CameraComponent;
Would be more performant since we can pass objects directly to setAttribute rather than serializing!
Apologies for submitting a very custom issue that likely is not the fault of aframe-react, but I could really use a second pair of eyes on this. I've built a small example of switching between a normal html/css rendering and an aframe rendering of the same data using aframe-react starting from the boilerplate.
The example is running here: http://immersionftw.com/meetup-vr/
The code is here: https://github.com/RSpace/aframe-meetup-example
If you:
... you will see that the canvas is not shown the second time "VR mode" is entered. By profiling the canvas in Firefox it is clear that the canvas is indeed rendered the second time, so it might be something as simple as a styling issue. But I just can't figure out why it's different the second, and if the problem is on my code, aframe-react or aframe-core.
Any ideas?
We have to do <Entity camera=""/>
. Need to tell aframe-react to not treat those as props or something.
I get that the gist of aframe-react
is that we're not supposed to be using stuff like <a-sphere>
in lieu of always using the <Entity>
component. But being able to call <a-sphere>
A) saves a lot of typing, and B) seems to work.
I figured the problem would be that React has patchy support for custom attributes, but as it turns out:
<Scene embedded>
<a-sphere position="0 0 -15" color="red" radius="1"/>
</Scene>
renders perfectly fine. The only problem I get are these warning in the console:
core:schema:warn Unknown property `color` for component/system `undefined`. +2ms
core:schema:warn Unknown property `radius` for component/system `undefined`. +3ms
I don't think I've run into any other issues besides that, so far. But what are these warnings about? They don't show up when I build my spheres with <Entity>
As I understand primitives: https://aframe.io/docs/0.4.0/primitives/
They are just a-entity
tags with a nice combination of components and default values, as well a easy access attributes.
We could probably implement them all very quickly, any reason not to provide them?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.