Kineticjs: Event listener missing after draw - javascript

I have created a Kineticjs scene with a scrollable background. On top of this background is a rect with an event listener attached. My question is, what could cause this event listener to not fire after I move the background and draw the scene. I don't know what it could be and I am even calling .moveToTop() on everything to see if I could move the shape back to the top even though I am pretty sure it still is. So what could cause an event listener to stop firing after a draw?
Does anybody know a fix for this? I figure I could might be able to attach another event listener to the shape, but this seems unnecessary if I am doing something fundamentally wrong.
Thanks in advance!
Edit: Here is some code.
// Here is the event listener attached to scroll bar
hscroll4.on('dragmove', updateBackgroundPos4);
// Here is code to move background
var updateBackgroundPos4 = function() {
var hscrollPos = hscroll4.getX();
console.log("mb4: ", mainBody4Dynamic.getX());
mainDynamicWrapper.setX(-hscrollPos+120); //the BG I am moving on scroll
// my attempt at getting it to work
dynamicLayer4.moveToTop();
mainBody4.moveToTop();
mainDynamicWrapper.moveToTop();
newFolder.moveToTop();
dynamicLayer4.draw();
//stage4.drawHit();
};
// Here is the group which contains the rectangle
folderGroup.on('mouseover', function() { //---- this isn't firing after draw
document.body.style.cursor = 'pointer';
console.log("change text");
updateTestText();
});
folderGroup.on('mouseout', function() {
document.body.style.cursor = 'default';
});
Edit 2: even my suggestion does not work. Adding the event listener back does not make it clickable again :(

Alright I got it! I found a thread which said to create an dragend event on the scrollbar then call layer.moveToTop() and layer.draw(). So putting it in dragmove was not enough for the program to register click events. The reasoning behind this was:
"When you use a drag event, KineticJS create a temporary layer on top as a result of which your events where not getting registered after the dragmove."
Here is the thread if anybody is interested:
LINK TO THREAD

Related

How to let scroll events through an overlay but not click events

I would like to create a map annotation tool with custom controls (not using map providers built-in annotation features).
Something like this:
My idea was to overlay a canvas above the map.
The problem is: I can't zoom on the map by scrolling anymore because of that overlay.
And if I set pointer-events: none to the canvas, then I can't draw on the canvas anymore.
Demo: https://codepen.io/vandrieu/pen/qBqdpzX?editors=1010
I would like to be able to draw on the canvas while still being able to zoom the map by scrolling the mouse.
How would you do this?
Using Rojo's comment I started looking into event dispatching and wrote this method that dispatches an event to another
function redirectEvent(eventType, fromElementSelector, toElementSelector) {
const fromElement=document.querySelector(fromElementSelector)
const toElement=document.querySelector(toElementSelector)
fromElement.addEventListener(eventType, function (event) {
toElement.dispatchEvent(new event.constructor(event.type, event));
event.preventDefault();
event.stopPropagation();
//event.stopImmediatePropagation();
});
}
Then I struggled,
First because scroll event didn't work. Until I figured out the right event for this is not scroll, it's wheel.
Then because dispatching the event this way:
redirectEvent("wheel", '#canvas2', '#map2')
Didn't work.
I figured maybe I needed to send the event to the canvas inside the map (the map is rendered using a canvas).
So I changed to:
redirectEvent("wheel", '#canvas2', '#map2 canvas')
But it didn't work either.
The reason is when page loads, the canvas inside the map is not rendered yet.
But if I wait a little:
setTimeout(() => {
redirectEvent("wheel", '#canvas2', '#map2 canvas')
},2000)
It works!
See the updated demo (map number 2): https://codepen.io/vandrieu/pen/qBqdpzX?editors=1010

Html Canvas lag when Left Mouse is down and moving on Chrome

I have created a canvas and I have added mouse events to it:
canvas = document.getElementById('canvas');
context = canvas.getContext('2d');
canvas.width = screenWidth;
canvas.height = screenHeight;
...
// CALLED AT START:
function setup() {
// Mouse movement:
document.onmousemove = function(e) {
e.preventDefault();
target.x = e.pageX;
target.y = e.pageY;
angle = Math.atan2((target.y - localPlayer.getY()),
(target.x - localPlayer.getX()));
// Distance to mouse Check:
var dist = Math.sqrt((localPlayer.getX() - target.x)
* (localPlayer.getX() - target.x) + (localPlayer.getY() - target.y)
* (localPlayer.getY() - target.y));
var speedMult = dist / (canvas.height / 4);
socket.emit("update", {
...
});
}
document.onmousedown = function(e) {
e.preventDefault();
}
}
Now the issue is when I hold down the only left mouse button and move the mouse at the same time, my game lags a lot. Simply moving the mouse causes no lag. I have tested this on chrome and on firefox. It seems that I can only recreate the issue on chrome. Using the middle mouse button or right button has the same behaviour in the game and cause no lag. Only when using the left mouse button causes lag.
I have looked around for answers and found that I should prevent default behaviour like so:
e.preventDefault();
But that did not resolve the issue. I have also tried to update a number on the screen that represents the mouse position. And it updated normally. Only the game itself was lagging. Could it be that the onMouseMoved is never called whilst the left button is held down? But then why is it called with the middle and right button?
The issue should be with the code I a calling inside of the move method, because it works fine when I am not holding down the left key, and it works well on firefox. There must be something else going on.
EDIT: I decided to a recording on chrome to see what is going on. Here is the result:
What's really odd, when I press the middle mouse button or the right button, the game does the same thing, but it does not lag at all. What are you doing chrome?
EDIT: Test it out here: www.vertix.io note that not everyone seems to be able to reproduce this issue.
Thank you for your time.
When you hold down the left mouse button and move it in the same time, you are dragging.
Edit: In some versions of Chrome, there is a bug (when I posted this answer I had it, now I don't), which causing the drag events to be fired even without the element having the draggable attribute. Normally, drag events should only be fierd from elements which have the draggable attribute set to true (except images and anchors who are drragable by default).
According to the MDN, when drag events are being fired, mouse events, such as mousemove, are not, which means that your function isn't being called.
A possible solution are to use the same function for both drag and mousemove events:
function mouseMove(e) {
//do your things here
...
}
document.addEventListener('mousemove', mouseMove);
document.addEventListener('drag', mouseMove);
Note: If you'll use the same function for both events, you should be aware of which properties of the event you're using in the function, because of the difference between the drag and mousemove events. The two events doesn't contains the exact same properties and the behavior of some properties may not be the same in both of them.
Have you considered throttling?
Check out https://blog.toggl.com/2013/02/increasing-perceived-performance-with-_throttle/
You have the mouse event on the document. As we can not see what you have on the document it is hard to know if that is a cause of your problems.
Try moving the mouse event to the canvas only, as that is the only place you need it I presume. No point handling events for the document if its not part of the game, plus document is last on the list if child elements have events attached. They go first and then it bubbles up to yours.
As it looks like you are using a framework of some type there is in all possibility another mouse event listener that is part of the frame work that may be slowing you down by not preventing default. You will have to search the framework to see if it has a listener for any of the mouse events.
And use addEventListener rather than directly attaching the event via .onmousedown = eventHandler
eg canvas.addEventListener("mousedown",eventHandler);
And add the event listener to the element you need it for, not the document.
function mouseMove(e) {
//do your things here
...
}
document.onmousemove = mouseMove;
document.ondrag = function(e) {
mouseMove(e);
//do another things
...
}

flot.navigate drag start/end events missing

im looking for some javascript events that trigger at the start and at the end navigating via dragging on flot plots so that i can do some ajax updates, however, I've been looking around online for some code to help me. I've found a few things, most didn't work worked or had bugs.
The best thing I've found so far is an answer from DNS, however it has unintentional behavior, when you hold the mouse click button down and stop panning the event triggers.
var delay = null;
element.on("plotpan", function() {
if (delay) clearTimeout(delay);
delay = setTimeout(function() {
// do your stuff here
delay = null;
}, 500);
});
The navigate plugin should really pass the event on to you; then you could easily check the state of the mouse buttons in your handler.
Since it doesn't, you'll need to attach your own mousedown/mouseup listeners to the overlay canvas; the child of your plot placeholder with class 'flot-overlay'. You can use these to update a shared variable with the state of the left button, then check that value in your handler above.

Mousedown triggers event, then when mouse is moved off element and mouseup fires it doesn't work

http://jsfiddle.net/63Y54/2/
In the example above when the user clicks and drags left or right off the canvas while holding the mouse button down and then takes their finger off the mouse the oscillator note hangs. I want to fix this. I am curious if their is a simple way to do something like..
if (mouseup == !htmlElement){
then....
}
In this case the html element would be the canvas element as that is what the user is clicking on.
As an attempt to fix this I made the body element encompass the page by setting its CSS width and height to 100%.
I then created a function that selected the body element with a mouseup click handler that launches the oscillator.stop() method. This only works when the user moved their mouse to the side of the page but when they moved down it still creates a hanging note.
This pseudo solution is here:
http://jsfiddle.net/63Y54/5/
I think this similar question answers yours.
jQuery detect mousedown inside an element and then mouseup outside the element
Here is the code from it from a guy named Mike:
var isDown = false;
$("#element").mousedown(function(){
isDown = true;
});
$(document).mouseup(function(){
if(isDown){
//do something
isDown = false;
}
There is additional code handling fringe cases in thelink as well.

How to catch mouseover event when dynamically added where mouse is already over the element?

I dynamically add this
$(ele).on("mouseover")
when user has mouse over the element, but it seems that mouseover event triggers only when I reenter element.
Here is example in jsFiddle (Click on <div> to add event listener)
How can I achieve this without manually triggering .mouseover() ?
Best solution I came up with was (Thanks to Brandon's suggestion):
Store x,y pos in document (drops performance on webpage a bit):
$(document).mousemove(function (e) {
// Set global values
window.mouseXPos = e.pageX;
window.mouseYPos = e.pageY;
});
And then when animation is finished:
$(document.elementFromPoint(window.mouseXPos, window.mouseYPos)).trigger("mouseenter");
You can't. mouseover only triggers when the mouse crosses the boundary of the element. Once the mouse is within the element, it won't trigger. Your question suggests you might need to take a step back and re-examine your problem. If you are taking action when the mouse is already within the element then why do you need a mouseover event?
You can manually trigger a mouseover with the trigger jQuery function after attaching you eventhandler this way
$(".test").on("click",function(){
$(this).on("mouseover",function(){
alert("");
});
$(this).trigger('mouseover');
})

Categories