I'm using Openlayers 2 and I'm creating a map app. I'm using apache cordova so it's just javascript/html/css.
It works fine for most cases but when I zoom in and out a bunch of times (with my fingers on a touchscreen) sometimes the scaleline stops updating. Moving the map around and zooming in/out some more usually get's it starting again.
My question is: Is there a way to force the ScaleLine control to redraw (other than moving around the screen and zoom in/out randomly). Like, is there a function I can run on, say, the click of a button to force redrawing?
I've tried
map.Control.Scaleline.update();
map.Control.Scaleline.draw();
But it doesn't work
Thanks!
PS:
I've tried opening the app from chrome on a desktop and since I don't have the touch screen capability there I can't reproduce the error
By looking at OpenLayers.debug.js I could see that scaleline is updated at "moveend" event which is only triggered when touch is completed (which it isn't if the user doesn't let the touch drag finish for example by zooming)
"move" always triggers, so I solved it by triggering "moveend" on "move" event.
map.events.on ({
"move": function () {
map.events.triggerEvent("moveend");
}
}
});
It removes the detail of adding certain events only on "moveend" but it solves the problem. Please comment if you have a better solution!
#atwinther was almost right. The solution is to watch for "touchend" and then send a moveend event. Only the latest browsers support this, however, so it might still be buggy for some people. At the least, according to Mozilla, this should work for the latest Firefox and Chrome: https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent
This is what I did that worked, with non-essential code ellided:
var SYP = {
init: function() {
this.map = new OpenLayers.Map("map");
// workaround for ol2 bug where touch events do not redraw the
// graticule or scaleline
this.map.events.on ({
"touchend": function () {
SYP.map.events.triggerEvent("moveend");
}
});
},
Related
Hi, particulary I am having a problem with HighCharts / HighStock not scrolling on the x-axis to display hidden data such as the times contained here:
It works just fine in Chrome browser on my Desktop. Whenever I scroll the overthrow-polyfill.js error shows itself. This is not a library I included myself as I can't find any mention of overthrow in all my code.
Sidenote: I do have angular touch and fastclick in the mix as well, but removing them did not help either
I've got the same problem on mobile device. After couple of hour i have found that scrolling is available just on mousemove event, but not on touch event. To fix this I have added the same listeners on touch events.
Highcharts.Pointer.prototype.onContainerTouchStart = Highcharts.Pointer.prototype.onContainerMouseDown;
var onContainerMouseMove = Highcharts.Pointer.prototype.onContainerMouseMove;
Highcharts.Pointer.prototype.onContainerTouchMove = function(e) {
onContainerMouseMove.call(this, e);
if ("touchstart" === this.chart.mouseIsDown) {
this.drag(e);
}
};
I'm having issues with the combination of CSS transforms and touch event hit testing. This only reproduces for me in Chrome on Android 4 (stable and beta). iOS Safari, as well as Chrome desktop with touch emulation both appear to be working fine.
I'm almost positive this has to be a bug, so I think I'm mostly looking for workarounds here.
The issue is that hit testing for touch only seems to work for where the element was before the transform, not the final position. You can see an example on my jsfiddle (only on Android 4 Chrome):
jsfiddle: http://jsfiddle.net/LfaQq/
full screen: http://jsfiddle.net/LfaQq/embedded/result/
If you drag the blue box half way down the screen and release it will snap back to the top. Now, if you try dragging from the top half of the page again, no touch will register. The touch events aren't even fired on the element. However, if you attempt to touch the bottom of the element, it works fine. You can then try moving it up from the bottom, and observing that hit testing no longer works on the bottom, but works on the top.
This is how I'm handling the events:
function handleTouch(e) {
console.log("handle touch")
e.preventDefault();
switch(e.type){
case 'touchstart':
console.log("touchstart");
touchOriginY = e.targetTouches[0].screenY;
break;
case 'touchmove':
console.log("touchmove");
el.innerHTML = e.targetTouches[0].screenY;
var p = e.targetTouches[0].screenY - touchOriginY;
el.style[TRANSFORM] = 'translate3d(0,' + p + 'px' + ',0)';
break;
case 'touchcancel':
console.log("touchcancel");
// Fall through to touchend
case 'touchend':
//console.log("touchend");
//el.style[TRANSITION] = '.4s ease-out';
el.style[TRANSFORM] = 'translate3d(0,0,0)';
break;
}
}
el.addEventListener('touchstart', handleTouch);
el.addEventListener('touchend', handleTouch);
el.addEventListener('touchmove', handleTouch);
el.addEventListener(TRANSITION_END, function(e) {
console.log("transition end")
el.style[TRANSITION] = '';
});
I don't have any problems with the transforms in touchmove, as those aren't new touches to be detected anyways.
Any suggestions?
This is an unusual bug in Chrome.
Essentially the hit targets for an element is recorded during a layout pass by the browser. Each time you set innerHTML, the browser will relayout and the last time this is done, is before the touchend event is fired. There are a couple of ways around it:
OPTION 1: You can set a touch handler on the body element and check the target of touch event to see if it is touching the red block. Tip of the cap to Paul Lewis for this approach.
http://jsfiddle.net/FtfR8/5/
var el = document.body;
var redblock = $('.splash-section');
function handleTouch(e) {
console.log("handle touch")
if(e.target != redblock) {
return;
}
....
OPTION 2: Set an empty touch callback on the document seems to fix the problem as well - according to some of the linked bug reports, this causes the hit testing to be done on the main thread which is a hit on performance but it properly calculates the hit targets.
http://jsfiddle.net/LfaQq/2/
document.body.addEventListener('touchstart', function(){});
OPTION 3: Set innerHTML after the transition has ended to force a relayout:
el.addEventListener(TRANSITION_END, function(e) {
console.log("trans end - offsettop:" + el.offsetTop);
el.style[TRANSITION] = '';
el.innerHTML = 'Relayout like a boss!';
});
I've created a bug report here and Rick Byers has linked to a related bug with additional info: https://code.google.com/p/chromium/issues/detail?id=253456&thanks=253456&ts=1372075599
So I am having an issue with my event handling in a script I am writing. The entire thing is working fine in chrome, and in safari even though it runs VERY slowly, it still works. In Firefox one of the events is not working at all.
Basically, on page load I am creating a bunch of event listeners:
canvasElem.addEventListener("mousedown",down,false);
canvasElem.addEventListener("mouseup",up,false);
canvasElem.addEventListener("mousemove",move,false);
These event listeners work, of that much I am sure, but one of the event listeners (that calls the down function) stops running part way through because of these two lines of code:
dXImgSpin=(centerXImgSpin-expansionOffsetXImgSpin)-(window.event.clientX);
dYImgSpin=(centerYImgSpin-expansionOffsetYImgSpin)-(window.event.clientY);
Now I understand (kind of understand, I am new to programming so it is still a bit over my head) That this won't work in firefox because I am using the IE DOM model rather then the W3C model, but in another part of the program that I was having issues with, /* event.pageX not working in firefox, but does in Chrome */ I fixed it by adding changing the way the event was handled(aka adding a canvasEleem.addEventListener), and then adding a line of code
event = event || window.event;
and changing the window.event.clientX to just event.clientX. However, when I try to do this in this different function, the above line of code won't even run.
Anything helps, and I am sorry if this question is not well phrased, But I have pretty much hit a wall in my current understanding of javascript, and can't understand how to get past it. If there is any more information that is required, don't hesitate to let me know!
Isaac
The full flow of code for when down is pressed:
canvasElem.addEventListener("mousedown",down,false);
function down(){
mouseDown=1;
getNewAngle();
angleMomentumImgSpin=.005;
}
The getNewAngle() function is the problem:
function getNewAngle(){
dX2ImgSpin=dX1ImgSpin;
dY2ImgSpin=dY1ImgSpin;
dX1ImgSpin=dXImgSpin;
dY1ImgSpin=dYImgSpin;
//THESE ARE THE PART THAT ARE CAUSING THE PROBLEM
dXImgSpin=(centerXImgSpin-expansionOffsetXImgSpin)-(window.event.clientX);
dYImgSpin=(centerYImgSpin-expansionOffsetYImgSpin)-(window.event.clientY);
//This if statement is to avoid the drawing from flipping when the mouse crosses the halfwaypoint
if (dXImgSpin>0){
angleImgSpin=(Math.atan((dYImgSpin/dXImgSpin))-angleStartImgSpin);
}else{angleImgSpin=(Math.atan((dYImgSpin/dXImgSpin))-angleStartImgSpin+(Math.PI))}
//alert(angle);
}
First of all, I can't upgrade to a newer version of the player, because I need the displayclick=fullscreen option to work, and it doesn't with version 5.
So, what I need to do is this: have the player auto-start with no volume and no controls on the page (this works just fine), and when the user clicks the screen the player must go full-screen and the volume must turn on.
The problem is all Javascript interaction seems to be completely ignored by the player, and I really can't see where the problem is.
When the page is loaded, I embed the player:
var so = new SWFObject('path_to_player.swf','div_id','200','120','10');
so.addParam('allowfullscreen','true');
so.addParam('allowscriptaccess','sameDomain');
so.addParam('bgcolor','#000000');
so.addParam('flashvars','file=path_to_playlist.xml&autostart=true&displayclick=fullscreen&controlbar=none&volume=0&icons=false&image=path_to_thumb.jpg');
so.write('div_id');
This seems to work just fine, the player is loading.
Then I add the event listeners:
var player = null;
function playerReady(p) {
player = document.getElementById(p.id);
addListeners();
}
function addListeners() {
if (player) {
console.log('add the listener');
console.log(player.getConfig().volume);
player.addControllerListener("RESIZE", "checkResize");
} else {
setTimeout("addListeners()", 100);
}
}
function checkResize(obj) {
console.log('resized');
if (obj.fullscreen) {
player.sendEvent("VOLUME", "60");
} else {
player.sendEvent("VOLUME", 0);
}
}
The "add the listener" message gets displayed in the console, but the second one, with the player's volume doesn't, and neither does the "resized" one when the player enters or exits fullscreen (and, obviously, the volume doesn't turn on).
I've tried other listeners, for both model and controller, and they don't seem to work. Sending events doesn't work either.
I've tried running just the code for the player separately, to make sure there are no other things interfering with the code, but I still have the same problem.
Well, it seems I've found the answer myself. Upgrading to a newer version of swfobject and using swfobject.embedSWF() seems to work just fine.
I'm working on a project that integrates OpenLayers and Qooxdoo...so far I'm having lots of success. But now I want to be able to place qooxdoo widgets in an OpenLayers popup (FramedCloud in this case) and something weird is happening--the button won't click!
The hover events seem to be working, and I've determined that qx.event.handler.Focus.__onNativeMouseDown is being executed, so the click event seems to be getting to the qooxdoo event system (?), but qx.event.handler.Mouse._onButtonEvent never gets called!
Either something in OL is getting in the way, or I'm doing something wrong. See one or both of these links for a test case:
http://s89238293.onlinehome.us/olisletest/build/index.html
http://s89238293.onlinehome.us/olisletest/source/index.html
(be advised that the "source" link loads the uncompressed/debug versions of both qooxdoo and OpenLayers, so it takes a while to load!)
The links above build on the skeleton qx Inline app, here's the main custom part of the code:
var map = new OpenLayers.Map("map_canvas", {
projection: new OpenLayers.Projection("EPSG:900913"),
displayProjection: new OpenLayers.Projection("EPSG:4326"),
units: "m",
numZoomLevels: 18,
maxResolution: 156543.0339,
maxExtent: new OpenLayers.Bounds(-20037508, -20037508,
20037508, 20037508.34)
});
map.addLayer(new OpenLayers.Layer.OSM());
map.setCenter(new OpenLayers.LonLat(-97.0, 38.0).transform(map.displayProjection, map.projection), 3);
var popup = new OpenLayers.Popup.FramedCloud(
"searchSelection",
new OpenLayers.LonLat(-97.0, 38.0).transform(map.displayProjection, map.projection),
new OpenLayers.Size(200, 200),
null,
null,
true,
null
);
popup.autoSize = false;
map.addPopup(popup);
var button2 = new qx.ui.form.Button("A Button");
button2.addListener("execute", function(){alert("Hello???");}, this);
var isle = document.createElement("DIV");
popup.contentDiv.appendChild(isle);
var popupIsle = new qx.ui.root.Inline(isle, false, false);
popupIsle.setLayout(new qx.ui.layout.VBox);
popupIsle.setBackgroundColor("#fff");
popupIsle.add(button2);
Can anyone help me figure out what's happening to the click event?
== EDIT ==
Thanks Alex, I've done some more plugging at it to try and figure out.
I tried a test of essentially the same code outside the OL map and it works, so that's eliminated.
I did this additionally to the OL popup object:
popup.events.un({
"mousedown": popup.onmousedown,
"mousemove": popup.onmousemove,
"mouseup": popup.onmouseup,
"click": popup.onclick,
"mouseout": popup.onmouseout,
"dblclick": popup.ondblclick,
scope: popup
});
Which I think disables all event handling on the popup itself (notice, for example, you can now pan the map by dragging within the popup--which is suboptimal, but proves the point). And, that didn't help...which seems to suggest that perhaps the event handling on the map itself is blocking the events. I can't disable mouse events on the map, for obvious reasons.
I'm going to pass this on to the OpenLayers mailing list in hopes of some more help...but in the meantime, anyone have any ideas for a workaround? So strange to me that some events (mouseover) work fine, but click doesn't. I'm open even to hacks at this point.
Also, I'm having a real hard time debugging this...I tried using the "Break on Next" feature in Firebug (and Safari debugger), but since qooxdoo is running several interval timers internally I can't catch the click because of the noise (the interval code always comes up before I can click). Any tips on how to catch the click event in the debugger would be appreciated!!
I had the same problem. Clicking on the Qooxdoo doesn't work. I use Qooxdoo v1.6 and OpenLayers v2.12. The Problem was the mousedown-event on the popup and the Map-Navigator. In my case the following has working fine:
// looking for the navigation control of the map
var controls = map.controls;
var navigator;
for(var i = 0; i < controls.length; i++) {
if(controls[i].CLASS_NAME == "OpenLayers.Control.Navigation")
navigator = controls[i];
}
popup.events.unregister("mousedown", popup, popup.onmousedown); // disable the mousedown-event
popup.events.register("mouseover", navigator, navigator.deactivate()); // on mouseover: deactivate the navigation-control of the map
popup.events.register("mouseout", navigator, navigator.activate()); // on mouseout: activate the navigation-control of the map
I hope, this would be helpful for anybody.
I've just tested your example and I think that the layer implementation is blocking the click event. So the click event is first processed by the OpenLayers and qooxdoo does not get it.
Do be sure that nothing is wrong with inline implementation of qooxdoo. Do you already tested your inline button without including the OpenLayers stuff? If everything is working fine without OpenLayers implementation you know at least that OpenLayers is somehow blocking the events.
This would be my first step in debugging. Hope that helps a bit.
Regards,
Alex