Any idea why this Paperjs script has a certain amount of lag - javascript

I wrote this script, and when I move the slider, the squares should instantly resize. They dont. It takes a few seconds. Any ideas?
Here's a link to my code: code on github gist. . Why does it delay?

You should add paper.view.draw() after you resize the squares so paper will update the canvas. It's redrawing internally but not updating the canvas.
There might be an issue with using on("change") as well - see this issue: onchange event on input range not triggering

Related

lag while dragging element

I am implementing a functionality where I can add, drag, and delete "sticky notes" on a webpage. The app is built in Vue js but it also renders content in an iframe. All the notes that are added to the page have to be on top of the iframe (which is almost 80% of the main .vue page), therefore positioning here is important and I also have to preserve the positions because I must render the notes on the same position on next page reload. The problem is that there's a lot of lag in dragging the "note" element.
The "sticky note" itself is a very lite weight separate component.
I have noticed that this because of the iframe that's present on the vue page because when I inspect the DOM in the browser and delete the iframe and then try dragging the "note" component then it works smoothly.
Things I have tried:
Use throttling: I tried to use loadsh.throttle but that does not make any difference.
Inject "sticky note" code inside the iframe: I tried to inject a sticky note element into the iframe and append it to iframe's body. It actually makes the dragging very smooth. But I don't want to go ahead with this solution because then I will have to write a lot of extra code to maintain the state of multiple notes (which can be done easily with Vue js).
In this solution, instead of using the document of the main page to attach events for dragging, I attached all the events to iframe.contentDocument.
So the question here is how do I make the drag smooth while using vue.js
Sandbox Link: https://codesandbox.io/s/affectionate-jang-3c1hw?file=/src/components/HelloWorld.vue
In this gif, the background is actually the iframe, I have reduced its opacity to hide it.
I could not actually include the iframe in sandbox code because of cross-origin problems but I have included a lot of extra content in that sandbox to make it heavy.
UPDATE:
Using the chrome task manager, I found that the page is only taking max 200MB memory and the GPU process is taking another 200MB. I am running this on a system with 16GB RAM. So I don't think it's a memory issue. But there is a sudden spike in the CPU consumption when I start dragging the element (up to 40%).
UPDATE:
I have found the fix for this problem. The actual problem wasn't lag but it was mouse trailing i.e. the draggable element wasn't able to catch up with the fast moving mouse cursor. And the slowness was due to e.preventDefault in the dragMouseDown method inside Note.vue. Just removing the e.preventDefault fixed all the problems. Also just adding a return false at the end of dragMouseDown method seems to cause the same amount of lag.
function dragMouseDown(e) {
e = e || window.event;
// e.preventDefault(); --> this line causes the mouse trailing issue
document.onmouseup = closeDragElement;
document.onmousemove = elementDrag;
// return false; --> adding this line also causes mouse trailing problem.
}
So for now I have just removed the preventDefault from this function. But I tried searching and could not find any explanation of this behavior. Also I am not sure if not cancelling the event can cause any other issue.
The problem is that you're working with mousemove without using requestAnimationFrame to debounce. Here's a working example using debounce (CodeSandbox link)
Generally, anytime you're trying to animate with javascript, you want to use requestAnimationFrame. Another thing you could try is using transform to change the position of the element instead of absolute positions.
Here's the MDN reference on requestAnimationFrame.
Here's an article by Paul Irish about using transform instead of absolute positioning to speed up a drag/drop.
As your extra description in the comments,
It starts to lag when these a lot of other content on screen. There's
a v-for in the sandbox. make it do more iterations and it will start
to laggy
The problem you met is the Dom elements were too many on your page then caused high memory usage. (Actually I tried <div v-for="i in 10000" :key="i">", then it took around 3GBs of memory), finally, everything works slowly and laggy
If your page has tons of Dom elements, you may have to consider dynamically add only visible items into the Dom tree when scrolling.
Even there are some packages that already implements this feature.
Below is one demo which uses RecycleScroller of vue-virtual-scroller:
100K items in the Codepen
You will see even the number of the items are 100,000, it still works smoothly.
PS: you may notice the below statement in the user guide of the above package=vue-virtual-scroller
The browsers have a size limitation on DOM elements, it means that
currently the virtual scroller can't display more than ~500k items
depending on the browser.

Adobe Animate CC Canvas mouse actions on the stage are laggy and intermittent

In Adobe Animate CC HTML5 Canvas (createJS), I'm trying to do something very simple, to trigger an animated rollover when the entire stage of an ad is moused over, and to trigger an animated rollout when the mouse leaves the stage. It should be very simple, but it's not. Using mouseenter and mouseleave on the stage is laggy and only works intermittently. It's the same with mouseover and mouseout.
Here's the code that's laggy and intermittent:
stage.addEventListener("mouseenter", fl_MouseOverHandler.bind(this));
stage.addEventListener("mouseleave", fl_MouseOutHandler.bind(this));
function fl_MouseOverHandler(){
this.btnOverAnim.gotoAndPlay("on");
}
function fl_MouseOutHandler(){
this.btnOverAnim.gotoAndPlay("off");
}
I also tried mouseover and mouseout on a button the entire size of the stage and I got the same issue. (Also doing it this way doesn't work at all from inside a frame, and the ad is served inside a frame). I put the var frequency way up to 90 to see if that would help with the lagging, it didn't.
This was the simple mouseover / mouseout code I tried:
var frequency = 90;
stage.enableMouseOver(frequency);
this.bgCta.addEventListener("mouseover", fl_MouseOverHandler.bind(this));
this.bgCta.addEventListener("mouseout", fl_MouseOutHandler.bind(this));
On the createJS website it says "You can monitor whether the pointer is over the canvas by using stage.mouseInBounds AND the mouseleave / mouseenter events." So I'm wondering if using stage.mouseInBounds will help (but I can't find an example anywhere of how to use it). But I actually don't think it'll help because I think this whole problem is about createJS not reading where the mouse is fast enough.
Does anyone know how to fix this lagginess and intermittent firing? A work around? Why does createJS not just monitor the mouse events constantly like pure js?
Also mouseenter and mouseleave on the stage in createJS do not work on tablets or mobile and that's a problem, so it would be better to do this with mouseover and mouseout on a button the entire size of the stage. I did try using mouseover and mouseout and having 3 pixels space around the button between the edge of the button and the edge of the ad banner, this helped, but it was still firing intermittently.
Your thoughts and ideas please.
Mouseover checks are expensive. A canvas is essentially just a bitmap, so EaselJS can't use mouse events from the browser (you just get one for the entire canvas). Instead, mouseover in EaselJS requires every element to be drawn to a 1x1 pixel canvas, and then checked for fill. This gives pixel-perfect detection, but is costly if you are either checking a lot of content, or checking too often.
Reduce your frequency:
It looks like you have set the frequency to 90. This is really high (11 ms between checks, which is basically trying to achieve 90 fps). The default is 10, which is slower than a good framerate, but fast enough to feel responsive. You can probably bring it down to 20 or so to give you a peppy check without it being unnecessarily high.
Modify interactivity: Another thing you can do is filter out exactly what gets checked. By default, all display objects get checked -- but you can reduce this by turning off mouseEnabled on anything you don't care about (omitting them from the check), and turning off mouseChildren on containers that you want to treat as a single object (so something like a complex button is drawn once, instead of all its contents being drawn individually).
// Example
myBackground.mouseEnabled = false;
myButton.mouseChildren = false;
Hope that helps!
Friends, I know this was asked 4 years ago, but the lagginess in Adobe Animate CC V.21 is no different (horrible) regarding mouseenter, mouseleave, mouseover and mouseout. After 10 times of rolling over/out the page becomes unresponsive. I was able to alleviate this using stage.mouseInBounds on a setInterval. The original poster could not find an example, so here is what I did:
// Place this in a keyframe on the timeline where the named cta exists.
setInterval(function(scope){
if(stage.mouseInBounds){
createjs.Tween.get(scope.cta).to({scaleX:1.1, scaleY:1.1}, 150);
}
else{
createjs.Tween.get(scope.cta).to({scaleX:1, scaleY:1}, 150);
}
}, 150, this );
Make sure to pass this into the end of the setInterval function as an argument for the callback function as to not lose scope. I am guessing this can be reworked to use gotoAndPlay() on the timeline, in this instance the built-in tweener for CreateJS sufficed for what I needed.

A-Frame cursor clicking disabled after implementing Pointer Lock

I'm using A-Frame on my project. There's this cursor component that enables you to interact with the elements by clicking, which is quite similar to DOM clicking.
However, the cursor clicking no longer works after I implemented my Pointer Lock.
Pointer Lock works well for me, I can walk around and look around in my scene, and the cursor always appears in front of me.
Why is the clicking not working? I can confirm that the clicking works fine when I haven't entered the Pointer Lock mode. Thanks!
Link to my demo:
http://zichao.co/exp/_simu/
I have added a listener on the '#floor'. If you successfully clicked the floor, the console should say 'hello'.
When you try to implement your PointerLock using the apis, first you need to define an element, and call element.requestPointerLock, is that right? The issue here is that element.
I took the a-scene as the element. What you should do is to take the canvas as the element - the canvas that is rendered later by a-frame, or three.js.
A $(document).ready() function is not able to return you the canvas because it is inserted into the dom by three.js, i.e. the dom is ready before canvas is created. What I do now is to set an interval to loop and check if canvas is created, and then activate the PointerLock.
Solved.

D3 js unexpected behavior on rapid mouse clicks

I have a multiline chart using D3, and the lines have nodes to mark the points. I also have legends below x-axis to display or hide each line when a user clicks on them. Similar to this example
The chart and legend selection works totally fine when I click normally on legends. But when I click rapidly on legends, one of the lines' nodes disappear. When I inspected the page, I found they got relocated to the top of the browser window(and not visible because there's no svg element there)
I don't even know what the problem is and where should I start debugging as it works fine with normal speed mouse clicks on legends.
I know it is very difficult for anyone to help without looking at the source code or a working fiddle, but I just wanted to know (before I try to reproduce the problem on fiddle) has anyone experienced something like this before? does mouse clicking speed affect how elements get rendered in D3? or this is not a D3 problem at all and some javascript/dom thing I am overlooking?
Some "strange" behaviour can occur depending on how your transitions are set up. For example, if there are many transitions attached to the same element, one might be interrupted when another one starts, and that may result on some element not being redrawn on screen.
For more about this see D3 documentation: Working with transitions, specifically this section which explains that "for a given element, transitions are exclusive: only one transition can be running on the element at the same time. Starting a new transition on the element stops any transition that is already running."

Stopping my tooltips from flickering

Having a problem getting my javascript working properly . For a single tooltip, it works great. But when I rollover multiple tips, I get a flickering effect. It seems the mouseover, out events are being 'queued' or something.
I've created a fiddle where you can see what I'm talking about
http://jsfiddle.net/eco_bach/dpFBQ/2/
Any other optimization suggestions appreciated!
You just need to add .stop(true, true) before the fadeIn() or fadeOut() methods to end any current animation. This will stop it flickering as seen here
Your code is creating and animating the tool tip every time you mouse over an element, so the flickering is expecting. I suspect you want to open it once and then just update its location and content when hovering others.
In that case you will need to track wether the tooltip is already open or not, if it is update its content and location but skip animating it. If not, do do the animation.

Categories

Resources