I have been trying to get my head around a way to intergrate Ember.js with Three.js. In particular, I want to render a number of elements, controlling the data with Ember.js bindings and general pub/sub handling, but also wont to be able to manipulate the views/elements with three.js using THREE.CSS3DObject.
I'm fairly confident with Ember but new to Three. I guess what I'm thinking is, can I have an element that exists in both the THREE.Scene and the Ember application namespace?
In the THREE.js periodic table example:
http://mrdoob.github.com/three.js/examples/css3d_periodictable.html
an DOM.element is create and then later decorated with attributes (style, position etc).
var element = document.createElement( 'div' );
element.className = 'element';
element.style.backgroundColor = 'rgba(0,127,127,'+(Math.random()* 0.5 + 0.25 ) + ')';
Later, it is added as an element to the THREE.CSS3Object constructor:
var object = new THREE.CSS3DObject( element );
I'm wondering if I can create the elements in perhaps an Ember containerView and then use jQuery to iterate over the childViews, caching the currently iterated element as 'element' and then render this to the THREE.CSS3DObject constructor?
I know it's a bit hacky and I only mention the above as some indication that I have tried to think up a way before asking for help! haha!
Any guidance or even pie in the sky suggestions like mine would be greatly appreciated. Thanks in advance.
Three's CSS3D renderer is just a thin abstraction of the browsers' own renderer and therefore should not conflict with the manipulation of DOM elements with Ember or jQ.
Once passed to the CSS3DObject constructor, an element's 3D transforms are updated but beyond that, it's business as usual. You can manipulate its content and style it as needed.
Related
I'm trying to better understand the fundamentals of A-Frame.
I understand how to use the getAttribute() and setAttribute() methods for
accessing component data. However I don't understand why we use them instead of just accessing the components attributes using dot notation.
A lot of people use something like:
document.querySelector("#myText").getAttribute('text').value
Why not use:
document.querySelector("#myText").components['text'].data.value
Is there something wrong with using that second way? What are the pitfalls? In my experiments I have experienced both ways returning "undefined" due to the code running before the scene is finished loading, but I have learned how to avoid that using the "loaded" event.
As you can see at this glitch example (https://glitch.com/~text-hierarchy) I've successfully printed data to the console using both ways.
Part of the standard
Both getAttribute(prop) and setAttribute(prop, value) are used to get/set attributes of any other DOM elements. MDN links here (get, set)
Compatible with aframe components
If you have a update() function in your a-frame component, setAttribute() calls it, notyfing, that a property of a component has changed.
It's not mandatory, it's even faster to modify some properties directly, but it has risks, like undefined behavior if a developer uses update() to monitor changes.
I have multiple entities which I would like to share the same material. Therefore, if I make a change to the material properties, the properties would be updated on all the entities within the scene using that material.
Is this possible? If so, how can it be done?
Create a material manually and attach to mesh:
var material = new THREE.SomeMaterial();
AFRAME.registerComponent('my-material', {
this.el.getObject3D('mesh').material = material;
});
<a-entity geometry my-material></a-entity>
And then you can manually manipulate the material whenever you want and it will auto-apply to all entities / meshes using it (e.g., material.color.set(0.5, 0.5, 0.5)).
The mixin method also works although slightly less efficient and more abstracted
Use a-mixin with a material component and manipulate its attributes. All entities that have it applied will update:
https://aframe.io/docs/0.8.0/core/mixins.html#sidebar
What's the fastest way to render dijit widgets?
I know that the programmatic way is faster than the declarative. (Some reference)
I have a custom widget that loads too slowly (it's a datagrid with combobox, buttons and other small dijit widgets used for adding filters, etc).
Looking at the source, I see that all the dijit widgets are created programmatically, but the DOM nodes where they are inserted into are created programmatically as well.
Is it the "right" way?
I'm trying to speed up the rendering of this widget, and currently my choice would be to combine a velocity template (my company uses struts2 + velocity) to create the DOM nodes, with programmatically created widgets (using placeAt and similar methods to insert the widgets into the already built DOM nodes).
It would work fine, but sadly all the css classes are overwritten by dijit, so I have to overwrite them again, which causes a sensible overhead.
In the template I write something like this:
<input id="idOfAnExistingDomNode" class="myCssClass" />
And to insert a FilteringSelect in that DOM node I have to write this:
var fieldSelect = new dijit.form.FilteringSelect({
store : jsonStore,
searchAttr : "caption",
labelAttr : "caption",
selectOnClick : true,
value : "Content"
}, "idOfAnExistingDomNode");
fieldSelect.domNode.className += " myCssClass";
The last line is necessary because myCssClass is overwritten during the creation of the FilteringSelect.
Is there any way to avoid this issue?
Or, perhaps, I'm trying to do this thing the wrong way? I'm not completely sure about that "velocity template" thing.
Note: Dojo version is 1.5 and no, sadly we can't upgrade it to newer versions.
Please forgive me for my TERRIBLE English.
Often one of the faster ways to instantiate widgets is to create them in a temporary div and then move that div onto the DOM. Have you tried profiling what exactly is slow in this instantiation? Part of me wonders if too much time is being spent waiting for data, as a few widgets + a grid with reasonable pagesize params shouldn't take long to load.
As for your class issue, it is strange that dojo is not mixing in the existing class. That said, you could do a lookup on the node first, get the class attribute, and then specify it as
the class attribute in your mixin object when creating the FilteringSelect. If you do so, be sure you wrap class in quotes or older IE's will reject it.
I'm removing an UIComponent but parts of it last being visible.
It redraws only when I move mouse around or something. I tried to do validateNow() on its parent, tried to do setTimeout(validateNow, 100) but it doesn't help. When I call it by setTimeout it seems these artifacts shown more rarely but it doesn't solve a problem in all cases. Please guide me someone to read about validateNow(), how it works and how to make these things correctly.
The code is below:
protected var bubble: SpeechBubble;
// creation
bubble = new SpeechBubble();
map.addChild(bubble);
//...
// removing
bubble.visible = false;
map.removeChild(bubble);
map.validateNow();
setTimeout(map.validateNow, 100);
map is Google Map for Flex.
The reason this is happening is because you're messing with the Google Maps drawing logic. You should look at the developer guide provided by google. It mentions in the controls section that to create a custom control, you need to extend ControlBase.
You may need to trigger invalidation before calling validateNow(). The call to validate now causes the code to check if any of the invalidation flags are set (properties, display list, or size) then for each calls the appropriate method to correct the invalidation (commitProperties, updateDisplayList, measure) in your case it sounds like it's just not doing the clear call to the graphics or redrawing appropriately so you may need to call
bubble.invalidateDisplayList();
bubble.validateNow();
Also hope one of these solutions works out for you, generally speaking forcing validation at a given time is not usually a good idea as the framework components should trigger the appropriate invalidation and subsequent validation in it's life cycle, but I can't say I haven't done this myself :).
Shaun
You may use includeInLayout property
bubble.visible = false;
bubble.includeInLayout = false;
Example demonstrates this property
The Beauty of includeInLayout
hopes that helps
I have 2 components for example (editor.mxml using mx:windows), when I click an edit button, I want to get the current value from the other component's datafield? (datagrid.mxml using mx:window)
I do know how to access the main MXML's datagrid by parentDocument or Application.application method, but stumped block if I want to access other way as mentioned above. Keep the code as simple as possible.
You could either do dependency injection, that is, give component A a reference to component B so that they can communicate directly (example of tighter coupling,) or have both components communicate through a common mediator using events (example of more loose coupling.)
Both of those options would be implemented wherever it is that you're creating those components (A and B in this example) and adding them to the display list.
This might be more complicated than it deserves, and it smacks of Pattern-Fever, but you could use a mediator class that listens for the CLICK event from the button and knows enough about the other component to query its property. It could even transmit that data using a custom event, which the button listens for.
While this involves three classes instead of two, it often turns out to be easier to have two components that focus on looking good and one that worries about coordination.
Cheers
Try this:
FlexGlobals.topLevelApplication
This points Your root. From the root You can grab every element You want.
You can also add an id to the custom component like this,
<custom:Editor id="myCustomComponent">
</Editor:AddressForm>
and
access your datagrid's value like this,
var data:ArrayCollection = myCustomComponent.DatagridID.dataProvider;