Handle events through multiple layers in Kinetic.js? - javascript

I have a circle on layer1 and then a square on layer2. The circle diameter is the square's width, their centers are the same, and the circle is on top of the square. How do I set things up such that if I trigger any event on layer1 the same even will be executed at the same location in layer2. So in this case if I click on the circle, the square's click event will also be triggered. Of course, this doesn't mean I simply want to hook up the circle's events to the square's, but rather I basically want the events to be triggered on both layers.
So for example if
circle.on( "click", function() {
alert("foo");
});
square.on( "click", function() {
alert("bar");
});
then clicking on the center of circle should trigger the square click event.
And NOT by
circle.on( "click", function() {
alert("foo");
square.simulate("click"); // don't want this
});

How about adding the circle and square to a group, and then attatch the click-event to the group instead?

Kinetic has two things that can help you.
getIntersections() -- returns all shapes under the mouse click point
fire() -- fires an event
The Kinetic docs mention the getIntersections() performs slowly, so they prefer getIntersection(), but I have never used either, so I can't say how much.
http://kineticjs.com/docs/Kinetic.Stage.html#getIntersection
Hope this helps.

Related

JavaScript: Trigger area measurement and line measurement from click event,

i have a canvas and inside this canvas, i have images and other stuff, in addition to that, there is a measurement tool, to measure the length of smth inside the canvas. now i need the measurement tool to behave in two different modes:
Line measurement:
this is triggered by two clicks, first click determine the first point of the line, and the second click determine the end point of the line.
Area measurement: this is triggered by one click as follows:
a. mouseDown: determine the first point of the area.
b. mouseMove: selecting the area while mouse is down.
c. mouseUp: determine the end point of the area.
I tried to trigger both by different ways, but the best way still have some issues.
My approach: using YUI lib to define Events
Event.on(canvas,"mousedown", mousedown);
Event.on(canvas,"mousemove", mousemove);
Event.on(canvas,"mouseup", mouseup);
define these three event listeners.
Mouse Down: in this function i store the Date.now() and set initially the area measurement. in addition to settimeout call back after 300ms, i check if the mouse still down, if so, set the mode to area measurement.
Mouse Move: draw the selected mode.
Mouse Up: here i check the Date.now(), if the click is less than 300ms, convert the mode to line and call MouseMove().
But this approach have some issues in the first 300ms, its ambiguous which mode the user wants. using my approach the code knows the mode after 300ms, but before 300ms, it can't be known.
So any helps to improve this approach or setting a new one?
Take a look at this answer that shows how to distinguish clicks from drags. How to distinguish mouse "click" and "drag"
Seems like 2 different things altogether that shouldn't rely on how fast the user moves.
Click, Click = Measure Distance
MouseDown, Drag, MouseUp = Measure Area

Google Maps API mousedown disabled when in drawing mode?

I have a google map with drawing overlays for rectangle, circle, polygon. Everything is cool but I want to clear the overlays before I start drawing a new one (automatically).
There doesn't seem to be any way to clear it via an existing Google Maps control and I don't want to create some custom button for it.
google.maps.event.addListener(this.map, 'mousedown', function(event) {
console.log('map mousedown');
console.log(_this.drawingManager.getDrawingMode());
});
I'm trying to clear the maps when a mousedown event occurs on the map. But it seems when the map is in "drawing mode" this event doesn't fire. I also can't find any documentation on any kind of mouse events for the drawing control.
Is there a way to fire a mousedown even when in drawing mode (drawing a circle, rectangle, polygon, etc) ?
There isn't a way to fire a mousedown event on map when in drawing mode I know of, but still I think there are two possible ways for you to go:
A. Only if you are using custom buttons for drawing manager (meaning you set drawingControl: false when initializing DrawingManager and create your own buttons). Then, when any drawing button was pressed, e.g. button for drawing a polyline, you can listen for the event which is fired when drawing was complete, and setDrawingMode to null which ensures that user will have to click one of the icons again to start drawing, where you can in the same click listener delete all existing drawings. For example (illustrational, depends on your setup):
$('#polylineButton').on('click', function(){
//delete any previous existing drawings on map
drawing_manager.setDrawingMode(google.maps.drawing.OverlayType.POLYGON);
google.maps.event.addListenerOnce(drawing_manager, 'overlaycomplete',function(polyline) {
drawing_manager.setDrawingMode(null); //set to hand cursor after overlay was drawn
..
}
...
});
So this solution wouldn't require any additional buttons on the map, only those required to select respective drawing tools (hand, polyline, circle, etc.)
B. You cannot listen for the map click event, but you can still listen for a click event on the div containing the map. In that case you can, also with leveraging overlaycomplete event, set up some variables indicating when drawing started. Something similar to what was done in this answer .

Making an Object "transparent" for Mouse Events?

I'm working on a project with HTML5 Canvas and KineticJS. A half-transparent overlay (a KineticJS group or layer) is placed all over the scene. The problem is: Mouse events bound to KineticJS objects under this overlay are not processed.
How can I make this overlay (or any other object) "transparent" to mouse events?
NOTE: The question is only about the Canvas, there are no other HTML elements interfering to it. (To make clear what was asked below.)
Assuming you mean HTML elements are placed over your canvas, try looking at pointer events: pointer events at MDN
e.g.
#foo {
pointer-events:none;
}
Setting opacity in layer level also sets opacity into object level.
layer.setOpacity(0.1);
"Mouse events bound to KineticJS objects under this overlay are not processed."
Hmm, mouse events bound to object are processed although your overlay(layer) has opacity of 0. this seems working fine, I don't know what you are into.
"How can I make this overlay (or any other object) "transparent" to mouse events?"
For me, mouseover/mouseout both work fine on layer level to make it half transparent.
layer.on('mouseover', function() {
this.setOpacity(0.5);
this.draw();
});
layer.on('mouseout', function() {
this.setOpacity(1);
this.draw();
});
Are you missing layer.draw()?
Yes you can click-through top nodes to the bottom nodes similar to pointer-events:none
You just tell your top object not to listen to events…like this:
myTopObject.setListening(false);
Now all mouse events will bubble down to the bottom object.
See this SO answer for code and Fiddle: pointer-events in Kineticjs

Change color and width of Polyline - ESRI Javascript API

I have a ESRI map that has 11 polylines on it. I would like it so that when a user mouses over a line, the line changes a different color and changes to a bigger width. When a user mouses off the line, the line will go back to it's original color and width. All these lines are on the same layer (var reaches).
I have the code that detects when a user mousesover or mouseout of a line:
dojo.connect(reaches, "onMouseOver", function(evt)
{ });
dojo.connect(reaches, "onMouseOut", function()
{ });
They correctly detect when the mouse in over a line and when the mouse is off a line. The way I have these 2 function, they detect when the mouse is over any line in the reaches layer. I would like the onMouseOver function to know which line was moused over and change the color and the width of the line. How do I do this?
I would like the onMouseOver function to know which line was moused
over
The evt parameter given to your event handler function should have a .graphic property, which contains the geometry of the feature you're hovering over.
and change the color and the width of the line
You can't do this directly on the feature without playing with its field values, but you can add a new feature to the map.graphics layer to serve as the highlighted feature. There's a good example on ESRI's forums:
dojo.connect(pdaGraphicsLayer, "onMouseOver", function(evt) {
map.graphics.clear();
var highlightGraphic = new esri.Graphic(evt.graphic.geometry,highlightSymbol);
map.graphics.add(highlightGraphic);
});

Manually triggering mouse event doesn't give me latLng

I am triggering a mouse event on the map from an absolutely positioned dom element that is over the map (this element follows my mouse). I want the mouseup element to trigger on the map as if the mouseup had been performed on the map directly. Most importantly, I want the latLng coordinates for the position over which the mouse button was released. Here is the relevant portion of my code (regarding the element that follows the mouse).
var mouseup = google.maps.event.addListenerOnce(_map, 'mouseup', function(event) {
placeMarker(event.latLng);
addPinClone.remove();
return bean.remove(window, "mousemove.window__temp__");
});
var addPinClone = $("<div class='map-add-pin'>").css({
opacity: .4,
position: "absolute"
}).mouseup(function(evt) {
return google.maps.event.trigger(_map, "mouseup", evt);
}).appendTo("#map");
If I click the map directly, I get event.latLng in my mouseup event. When I trigger the event from the floating element, I do not.
I tried to omit the mouseup function on addPinClone altogether, hoping the event would bubble up to the map properly, but that didn't work either.
How do I get the latLng from here?
mouseup is not a documented event on the Map class (it is on Marker, Polygon, Rectangle and Circle, i.e. things you might drag around on the map). So I'd guess it's impossible for you to trigger that event. Although interesting that anything happens at all for a normal click on the map.

Categories

Resources