I'm drawing an entity using position data being fed from a database.
I'm currently using
viewer.entities.removeAll();
to remove all the entities every time I get a result from the database.
This causes a long and heavy process in the browser as the entities are currently 3D models.
Is there a better way for the data to update, for example an array of the entities.
Or a way to cache the entities that I could then alter the data.
The end result is so that I could alter the positions on the fly and then see the entity update on the display
I am using
viewer.entities.add({
name : name,
position : position,
orientation : orientation,
model : {
uri : url,
minimumPixelSize : 50
}
});
to add the entities
Take a look at the Picking Demo, you can see it assigning new Cartesian3 values to entity.position around line 26 in the live-editor window. Updating an entity is going to be much faster than destroying it and creating a new one.
Also, if your database knows that an entity has a position that changes over time, you can supply that via a SampledPositionProperty, and allow Cesium to animate the entity moving along a path over time.
Related
I wish to get handles of all the charts in a stage in order to modify background settings.
I noticed there is a stage.forEachChild(function(element) { … }) method that allows you to fire up a function for each stage element.
For example:
stage.forEachChild(function(element) {
alert(element.id());
});
The problem is that "element" type is anychart.graphics.vector.Element; instead I need a anychart.core.Chart object in order to call the background() method. Is there a way to do that?
Unfortunately, is a GraphicsJS entity and it returns its graphic vector elements as children. It doesn't control charts. You can store all chart in an object or array and iterate them, or apply a unique ID to every chart and get access to them at any moment by anychart.getChartById('CHART_ID');. For details, check the sample by the link in a comment below.
Using Meteor and React, I am building an application that has a fabric canvas in the middle, a 'components panel' on the left (a library of objects to add to the canvas), and a 'layers panel' on the right (similar to Photoshop, where each object on the canvas is represented as a layer with specific controls like color, opacity etc.).
So far I have managed to display the Layers Panel by using a Meteor session variable that contains an array for the objects on the canvas.
So each time I add, remove, adjust or make any functional change to any object on the canvas, I manually make the adjustment for the object within the session variable array as well.
This has worked well so far but I now want to implement grouping functionality. While it is easy to do this with fabric.js alone, I am having trouble representing the exact state of the groups on the layers panel. It needs to be displayed in a tree format where nested groups and items are within/under other objects.
I also still need to have the layers panel sortable as well.
Using fabric, we can group a set of objects, group another set of objects, and then group the two sets of objects together. This gets quite complicated and is quickly becoming a nightmare to maintain using the method I described above.
So now I am thinking, it would be much easier to just have the layers panel look at the object data directly from the canvas (reactively). This way, I don't need to maintain a second array and manually match every change that occurs. I could then use something like React Sortable Tree.
So in an attempt to make this happen, I am trying to store a copy of canvas.getObjects() into a Meteor session variable after any change occurs on the canvas.
canvas.on({
'after:render': function() {
var canvasObjects = [];
var objects = canvas.getObjects();
objects.forEach(object=>{
canvasObjects.push(object);
});
Session.set('canvasObjects', canvasObjects);
}
});
I am getting the following error though...
TypeError: callback is not a function
at modules.js?hash=d9804d9fae07a146610fc3c3c610d3e79bf33006:261816
at onLoaded (modules.js?hash=d9804d9fae07a146610fc3c3c610d3e79bf33006:244313)
at modules.js?hash=d9804d9fae07a146610fc3c3c610d3e79bf33006:244337
at modules.js?hash=d9804d9fae07a146610fc3c3c610d3e79bf33006:257179
at onLoaded (modules.js?hash=d9804d9fae07a146610fc3c3c610d3e79bf33006:244357)
at modules.js?hash=d9804d9fae07a146610fc3c3c610d3e79bf33006:244379
at Array.forEach (<anonymous>)
at Object.enlivenPatterns (modules.js?hash=d9804d9fae07a146610fc3c3c610d3e79bf33006:244370)
at Function.fabric.Object._fromObject (modules.js?hash=d9804d9fae07a146610fc3c3c610d3e79bf33006:257171)
at Function.fabric.Path.fromObject (modules.js?hash=d9804d9fae07a146610fc3c3c610d3e79bf33006:261457)
If I replace this line...
Session.set('canvasObjects', canvasObjects);
with this line...
console.log(canvasObjects);
I see the array printed in the console.
Why is it able to log the array but unable to store it into the session variable?
Is this even a good idea? I feel like it will be bad for performance. Would there be any other way to keep the canvas state and the layers panel in sync with all the properties that I want (visibility, opacity, fill, lock, index, group hierarchy etc.).
Thanks in advance.
I am using gridster.js. When i am adding a new widget,current widget moves down as per the requirement.But how and where can i get the changed position of the moved widget to save that in db?
You can use serialize method to get widget positions. It returns a Array of objects that can be used as a JSON object.
gridster.serialize();
Sample output:
[{"col":1,"row":4,"size_x":2,"size_y":2},{"col":3,"row":1,"size_x":1,"size_y":2},{"col":4,"row":1,"size_x":1,"size_y":1},{"col":2,"row":6,"size_x":3,"size_y":1},{"col":1,"row":7,"size_x":1,"size_y":1},{"col":1,"row":6,"size_x":1,"size_y":1},{"col":2,"row":7,"size_x":1,"size_y":1},{"col":2,"row":8,"size_x":1,"size_y":1},{"col":4,"row":7,"size_x":1,"size_y":1},{"col":2,"row":1,"size_x":1,"size_y":3},{"col":1,"row":8,"size_x":1,"size_y":2},{"col":3,"row":7,"size_x":1,"size_y":2},{"col":4,"row":8,"size_x":1,"size_y":1},{"col":2,"row":9,"size_x":3,"size_y":1},{"col":5,"row":1,"size_x":1,"size_y":2},{"col":5,"row":3,"size_x":1,"size_y":1},{"col":3,"row":10,"size_x":1,"size_y":1}]
Demo here
Edit:
gridster.serialize_changed() //Call this after adding the new widgets
To get the position of widgets with updated positions, you can use .serialize_changed() method. It returns an array of objects representing the current position of the widgets who have changed position.
I am trying to record user selections and replay them in a new session at a later point in time. I cannot figure out how to re-create the range(s) the user has selected in the new session.
Specifically, I display (inside a div with a known ID) a blob of HTML. The user makes a selection and clicks a button. This allows me to capture whatever information I want about the range. I am using Rangy to get the range information and capture the start and end nodes and offsets, the raw HTML, and the text property. I also style the selection at this point, which obviously changes the DOM. The user may make/store multiple selections. When they click 'save' I upload all the selection data to the server and store it.
At a later point in time, a different user looks at the same blob of HTML (also inside a div with a known ID). The are presented with the document with all user-applied highlighting shown.
Obviously in a new session the DOM objects are different, so storing the actual node data is meaningless. I also tried converting the path to the node as an XPath but I can't find a good way to then re-apply the XPath to find the target node in the new session. I thought of counting elements to find the start or end element, but the count obviously changes if later selections come before previous selections and this will throw off the retrieval without some hairy logic.
Is there a good way to remember and re-find a node in a DOM that could change slightly (and in predictable ways)?
If you are using Rangy 1.3 (still in beta at the time of this writing), you can preserve highlightings between sessions easily.
First initialize Rangy when your page loads:
var highlighter;
var highlightClass = "someCssClassName";
$(document).ready(function() {
highlighter = rangy.createHighlighter();
highlighter.addClassApplier(rangy.createCssClassApplier(highlightClass, {
ignoreWhiteSpace: true,
tagNames: ["span", "a"]
}));
});
To highlight the text that is selected with a :
highlighter.highlightSelection(highlightClass);
To serialize all the highlighted text in the current document:
var data = highlighter.serialize();
storeDataToExternalSourceAndReloadPage(data);
To later (or in another session) deserialize the data object and highlight the current document:
var data = loadDataFromExternalSource();
highlighter.deserialize(data);
Easy! Thanks Tim for an amazingly helpful library!
I extended an Ext.data.Store (i.e users with model user) but when I iterate over custom JSON response and add each record, it replaces the first record and so the store consist of just one record instead of many
Here is my code (in image format) notice in line 215 i added a model on store on each iteration:
And here is the console output w/c only shows 1 on getCount():
I tried many solutions, and that includes changing the 'id' attribute to something else and also differ my user model to users model
But I have another store that is adding fine without problems.
EDIT: I tried adding it through javascript console and still it replaces the record 1:
The store's add function will automatically handle creation of the model(s). Your callback should be as simple as this:
callback: function(optionsusers, successusers, responseusers) {
loadingLoginModal.hide();
var responseusersJSON = Ext.JSON.decode(responseusers.responseText);
userStore.add(responseusersJSON);
loadingLoginModal.destroy();
that.showHomeView();
}