OpenLayers get coordinates of touch points? - javascript

I am registering the "click" event on the map to get the Lon and Lat of the mouse click like this:
map.events.register("click", map, function(e) {
var lonlat = map.getLonLatFromPixel(e.xy);
});
This works fine on my PC(click), but doesn't get triggered on my Android tablet(touch). So it gets triggered on click, but not on touch. I have to register the event to my layer to get it to trigger on touch(https://gis.stackexchange.com/q/20859) like this:
layer.events.register("touchstart", layer, function(e) {
//e.xy is undefined
});
This gets triggered, but for some reason event.xy is undefined?
How do I get the touch coordinates when using touch on a tablet?

It's not so easy to get the coordinates from the touchstart event.
Touchstart event comes with a touches array, each one containing some coordinates, but using different properties.
OpenLayers normalizes the touchstart event in the OpenLayers.Event class method getTouchClientXY.
Also, I can't find any click/touchstart event in the layer class. Maybe you are using some other subclass or a custom one...
However, depending on your needs, you could
create a drawfeature control, with a point handler and listen to the featureadded event
define a custom control that use the OpenLayers.Handler.Click (that handles click/touchstart correctly)
if you need to select a vector feature, use the SelectFeature control
Handle the "touchstart" event using a for loop to find xy coordinates in the touches property

I found a solution that works for me. This also triggers click event with touch:
OpenLayers.Control.Click = OpenLayers.Class(OpenLayers.Control, {
defaultHandlerOptions: {
'single': true,
'double': false,
'pixelTolerance': 0,
'stopSingle': false,
'stopDouble': false
},
initialize: function(options) {
this.handlerOptions = OpenLayers.Util.extend(
{}, this.defaultHandlerOptions
);
OpenLayers.Control.prototype.initialize.apply(
this, arguments
);
this.handler = new OpenLayers.Handler.Click(
this, {
'click': this.trigger
}, this.handlerOptions
);
},
trigger: function(e) {
var coordinates = map.getLonLatFromViewPortPx(e.xy);
}
});
var click = new OpenLayers.Control.Click();
map.addControl(click);
click.activate();

i use
e.clientX
instead of
e.x
or the touch.
Have a look in my code if you want In taphold.js
[http://ozonforages.free.fr/mobile.html]

Related

Restore mouse wheel event javascript library

I am using wheel-indicator JS library. I like to restore the mouse wheel event which was originally set to preventDefault().
I tried indicator.setOptions({preventMouse:"false"}) as the instance method says "The only argument must be Object", but it does not work.
var indicator = new WheelIndicator({
elem: document.querySelector('.element'),
callback: function(e){
console.log(e.direction);
//DO SOMETHING HERE
}
});
indicator.setOptions({preventMouse:"false"});
var indicator = new WheelIndicator({
elem: document.querySelector('.element'),
callback: function(e){
console.log(e.direction);
//DO SOMETHING HERE
}
});
indicator.getOption('preventMouse'); // true
I suppose the problem isn't connected directly with plugin. Maybe preventDefault() to wheel event on element just doesn't work in your case?

Paper.js Mouseup Event Inhibited by Tool

I'm using Paper.js and I need to do something on mouseup on a raster. However the event does not seem to fire when I use the global tool space.
Note this sketch, where clicking and dragging yields a log something like this:
raster mousedown
raster mousedrag
... [more "raster mousedrag"] ...
raster mousedrag
raster mouseup
indicating the raster.on('mouseup' function() {...}); was hit properly, as expected.
However, in this sketch, which contains functionality for displaying the dragged area, the raster.on('mouseup' function() {...}); is not hit properly. Note that the log does not contain "raster mouseup", only "raster mousedown" and "raster mousedrag".
Why in the second instance does mouseup not fire on the raster? How can I adjust the code in the second sketch so that it does fire?
Well, the simple answer is that the problem is that the on('mouseup', ...) handler is never called. The paper code gets the most recent hit, i.e., the red rectangle you're drawing, and checks to see if that responds to the 'mouseup' event. It doesn't. Then it checks the parent chain and the parent of the red rectangle is the layer, so it doesn't pass the .responds test either. Because the raster is at the same level as the red rectangle handlers associated with the raster are never called.
The simplest answer is to install the handlers on the view, not the raster, by using the global tool, e.g.,
function onMouseUp(event) {
console.log('vup');
}
See the paperjs code (in CanvasView.js):
function callEvent(view, type, event, point, target, lastPoint) {
var item = target,
mouseEvent;
function call(obj) {
if (obj.responds(type)) {
if (!mouseEvent) {
mouseEvent = new MouseEvent(type, event, point, target,
lastPoint ? point.subtract(lastPoint) : null);
}
if (obj.emit(type, mouseEvent) && mouseEvent.isStopped) {
event.preventDefault();
return true;
}
}
}
while (item) {
if (call(item))
return true;
item = item.getParent();
}
if (call(view))
return true;
return false;
}

Google Maps: Want to drag the map directly after setting draggable to true

To avoid unwanted scrolling in small browser-windows, I set draggable option of my Google Map to false:
if (document.getElementById('map').offsetWidth < 350 )
map.setOptions({
draggable: false,
scrollwheel: false
});
Then, I add a timer/function which enables dragging after one second of mousedown if a user wants it (sort of longpress):
var timer = null;
function draggable_true() {
map.setOptions({
draggable: true,
scrollwheel: true
});
}
var mdown = google.maps.event.addDomListener(map, 'mousedown', function() {
timer = setTimeout( draggable_true, 1000 );
});
var mup = google.maps.event.addDomListener(map, 'mouseup', function() {
clearTimeout( timer );
});
This works fine, after one second the cursor changes to the hand-symbol. But to drag the map, I have to release the mousebutton once and press it again. So now I'm wondering how to drag the map directly (the mousebutton is already and still down).
I tried MouseEvent inside the draggable_true() function to simulate another mousedown, but it doesn't work:
var event = new MouseEvent('mousedown', {
'view': window,
'bubbles': true,
'cancelable': true
});
document.getElementById('map').dispatchEvent(event);
I also tried mouseup first and then mousedown, but also no result (not even mistakes or warnings).
So any ideas anybody? Thank You.
I solved a similar problem using jQuery-Mobile's taphold event, as this event allows you to detect a longpress and then bind the mousemove event to your drag function. When the user releases the mouse, you unbind the mousemove event and everything returns back to normal. Please, be aware that I didn't use this technique with GoogleMaps but it should work nonetheless.

How to decide the triggering order of different mouseDown function

I have two kinds of functions which will detect the mousedown event and trigger some functions.
window.onmousedown = function(...)
Raphael object:
var rec = paper.rect(10,10,10,10)
rec.mousedown(...)
the second one is a rectangle create by Raphael.js and the function will be triggered when you click the rectangle.
I need the second one to be triggered before the first one, but it seems that the order of triggering of the two functions is randomly decided by the browser?
Do I have any way to control it !?
thanks!!
I need the second one to be triggered before the first one
Look at the DEMO, mousedown even triggers on circle before window's.
window.onmousedown = function()
{
alert('Yes');
}
var paper = new Raphael(document.getElementById('paper'),500,400);
var circle = paper.circle(100,100,50).attr({fill:'orange', stroke:'green', 'stroke-width':3});
circle.mousedown(function() {
alert('No');
this.attr({fill:'green', stroke:'red', 'stroke-width':3});
});
circle.mouseout(function() {
this.attr({fill:'orange', stroke:'green', 'stroke-width':3});
});
Click on the circle and see that the alerts. Good luck

How to grab and drag an element around a circle?

So far I have a circle with a marker.
http://jsfiddle.net/x5APH/1/
I would like to grab and drag the marker around the circle, however the current functionality only nudges the marker when you click it.
What changes can I make to the code so that the marker can be dragged around the circle while the mouse is held down?
Note
If you could update the fiddle with your solution I would greatly appreciate it.
changed some code
$(document).ready(function(){
$('#marker').on('mousedown', function(){
$('body').on('mousemove', function(event){
rotateAnnotationCropper($('#innerCircle').parent(), event.pageX,event.pageY, $('#marker'));
});
});
}); ​
also add this code
$('body').on('mouseup', function(event){ $('body').unbind('mousemove')});
in the function
this is the jsfiddle http://jsfiddle.net/sandeeprajoria/x5APH/11/
To do anything of this sort:
On mousedown on the desired element, set:
mousemove event on the document to update the position of the target
mouseup event on the document to remove the mousemove and mouseup events you just set.
Example in plain JS:
elem.onmousedown = function() {
document.body.onmousemove = function(e) {
e = e || window.event;
// do stuff with e
};
document.body.onmouseup = function() {
document.body.onmousemove = document.body.onmouseup = null;
};
};
Personally I like to improve this further by creating a "mask" element over the whole page to capture events, so that (for example) dragging a selection or image does not trigger default browser actions (which are strangely immune to all event cancelling methods in this case...)

Categories