Improving performance of mouseover event in EaselJS - createjs

From the manual:
The latter four events have some overhead associated with them, so you
need to enable them with stage.enableMouseOver(frequency). The
frequency parameter indicates how many times per second EaselJS should
calculate what is currently under the pointer. A higher number is more
responsive, but also more computationally expensive.
I need to enable a mouseover functionality only on a certain class of objects on my otherwise crowded stage. Is there a way to enable the mouseover checking only for certain objects as opposed for the whole stage? Or is EaselJS only checking objects with a "mouseover / mouseout, and rollover / rollout" listener? What about the pointer property - it works only if enableMouseOver is enabled - is that checked for all objects or only for those with pointer property other than default?
Is EaselJS internally doing some space partitioning like k d trees to boost the performance?

You can prevent any object from receiving a mouse event by setting mouseEnabled=false.
myBitmap.mouseEnabled = false;
If you have a large amount of items (such as particles), make sure they are in a container, and set mouseEnabled AND mouseChildren=false on the container, and the Stage will not check any of the container's children.
myContainer.mouseEnabled = myContainer.mouseChildren = false;
If you still want to know when a container's general area is clicked, you can swap out the default mouse behaviour with a hitArea, which is used in place of its actual contents.
var hitArea = new createjs.Shape();
hitArea.graphics.drawRect(0, 0, 500, 500);
myContainer.hitArea = hitArea;
Hope that helps!

For improving the performance i used cache if any object is static
I used mouseEnabled =false;
I did not render any text or images inside the canvas i used mix of
angular or plain javascript to render the dom element

Related

Show or hide featues by zoom level and importance

Using arcgis for JS 4.24 MapView.
I have a feature layer with features of different importance to the user. The importance is defined in an attribute of the feature. What I want to achieve is, that less important features only show on a certain zoom level.
What I tried so far:
Clustering: is not what I want since it is grouping on occurrences not importance.
Unique Value Renderer: Does not seem to support visibility by zoom level but is otherwise exactly what I would use.
Setting the min-max visibility: This applies to all features and cannot be configured by attribute value.
What did I miss? Any other ways to apply custom styles to feature layers?
I guess a simple solution would be to create as many FeatureLayer instances as importances you have. In each of this instances you set,
definitionExpression to the importance level,
maxScale and minScale to constraint the visibility
This solution would work if the number of importance levels are "reasonable" (let say, less than 10 or so, you will have to test it).
Another solution would be to listen for scale changes in the map view (could be the updating event), and then apply a filter (could be definitionExpression again) with the correspondent importance. With this you do not need to have many instances of the same service.
EDIT
The reason for using updating, is to avoid doing stuff while the view is changing, something like this,
view.watch("updating", function (value) {
if (!value) {
// now is the moment to check view properties
// for example
if (view.scale < MIN_SCALE) {
doSomething();
};
}
});

layout doesn't work when adding nodes to graph dynamically

When I add nodes to the graph statically via the elements property of
$('#cy').cytoscape(..)
the layout option works but when I add them via
cy.add({..})
the layout is ignored. I can apply new layout only on these events(click, mouseover, mouseout) like this:
cy.on('mouseover', function(event) {
cy.layout({name: "grid"});
});
and the layout changes. Tried with other events: ready, done and load but it doesn't work.
Is there a normal way way to change the layout when elements are added dynamically?
You can't call a second layout while the initialisation layout is running. Configure your initialisation properly (http://cytoscape.github.io/cytoscape.js/#core/initialisation) to have all the data and options you require.
As for cy.add(): Don't try using cy.add() on load unless you specify everything you need (incl. position) for those elements. Or, you'll have to at least wait for layoutstop before running a new layout. In general, you're better off using the initialisation options to do things for you rather than having to worry about edge cases and event synchronising yourself.

optimize drag and drop with svg library & javascript

Currently most of the SVG framework provides drag and dropping. I have used RaphaelJs , Extjs Drawing , and SVG.js(http://www.svgjs.com/). All of the framework provides the event handling method by binding it with the element itself. For example:
dragStart: function(event){
//'this' refers to the element itself
this.doSomething();
this.moveTo(event.x,event.y);
};
However the consequences of this is that browser performance is greatly degraded, when there are more than hundred of elements and some logic processing aside. My elements will be composite elements, meaning maybe some text or path in a rect but the rect should be the target (or this) of the event when dragged. The elements will have other event to listen to , for example onclick, onDblClick, onHover & etc.
My question is, is there any way to optimize this ? The user experience is bad after the application is showing a lot of the composite elements I mentioned above.
UPDATE:
I have built an application using the mean that i spoke of above. Binding the event handler to each of the objects. The result is not very user friendly when the element is listening to onhover and onmousedown events. I am thinking to optimize the application but not sure how. The effect is more obvious in FF, chrome is better.
Are you sure you need SVG? Fabric.js is an awesome API for scaling, rotating, drag-drop, and grouping, based on the Canvas element.

How to use VirtualizingStackPanel CleanUpVirtualizedItemEvent?

I've customised the style of a ListBox in order to register for the VirtualizingStackPanel.CleanUpVirtualizedItemEvent. I need to free up some memory when the item is re-virtualized, and then re-load the memory when it is un-virtualized. Whenever I check to see if the item is virtualized, it always returns false:
const bool isVirtualizing = VirtualizingStackPanel::GetIsVirtualizing(e->UIElement); // Always returns false
How do I work with this event? I can change the ListBox to use VirtualizingStackPanel.VirtualizationMode="Standard" but that causes the UI to be created and deleted constantly, which can lead to performance issues. I'd rather recycle the UI controls if possible.

Checking if an element is really visible to the user

I'd like to check whether the user can see an element in the current web browser view without scrolling.
What I've found can check whether the element is somewhere on the page.
Another hint suggested to check the elements position but then I would need to get the dimensions of the visible window of the browser plus its x/y offset to 0/0.
I would be grateful if someone could point me to a solution that does not need JavaScript code.
How do you define 'visible to the user'? How do you propose to check it?
If it has a height? If it isn't hidden by CSS? What if it's parent element is hidden by CSS?
The most reliable way will be to use Selenium's built in .Displayed property (if you are using C#, Java has something similiar), and combine it with jQuery's 'visible' selector: http://api.jquery.com/visible-selector/. Example below, in C#.
var element = Driver.FindElement(By.Id("test"));
bool isVisible = element.Displayed;
var javascriptCapableDriver = (IJavascriptExecutor)Driver;
bool jQueryBelivesElementIsVisible = javascriptCapableDriver.ExecuteScript("return $('#myElement').is(:visible);");
bool elementIsVisible = isVisible && jQueryBelievesElementIsVisible;
This will get the majority of cases.
It isn't possible without client side code, or in the preparation that someone else finds a way that it can be done in a server side language, I highly doubt it will be pretty, readable or reliable.
jQuery has the offset() method:
http://api.jquery.com/offset/
This, however, won't work when taking into account borders, margins, that kind of stuff.