I'm using openlayers on an image and looking to have it so that if I zoom all the way out and it's off to the side a bit, that it will be automatically centered. I have the following code, but it is not working. It doesn't look like 'zoomEnd' is called on pinch, but what event is fired?
Is there a list of all the possible events to listen for in Openayers? I can't find something like that anywhere in the documentation..
map = new OpenLayers.Map('detailsdiv', {
projection : 'EPSG:3785',
units : 'm',
fractionalZoom : true,
eventListeners: {
"zoomend": recenterMap
},
maxResolution: Math.pow(2, graphic.numberOfTiers - 1),
numZoomLevels : graphic.numberOfTiers,
controls: [
new OpenLayers.Control.TouchNavigation({
dragPanOptions: {
enableKinetic: true
}
})
]
});
==============================
function recenterMap(){
if (!map.centered){
if (map.getZoom() == 0){
map.centered = true;
map.zoomToMaxExtent();
map.zoomTo(0);
} else {
}
}
}
I believe you are better off using the moveend event. It gets fired when a drag, pan, or zoom ends...which is better. Also, here is a list of events:
http://dev.openlayers.org/releases/OpenLayers-2.12/doc/apidocs/files/OpenLayers/Map-js.html#OpenLayers.Map.events
You also might want to use map.setCenter() in your recenterMap() function
Related
I'm trying to detect when a marker if found/lost in ar.js, while using a-frame.
From what I see in the source code, when the marker is found, a 'getMarker' event should be fired, moreover artoolkit seems to dispatch a markerFound event.
I tried to listen to those events on the <a-scene>, or on the <a-marker>, but it seems I'm either mistaken, or i need to get deeper to the arController, or arToolkit objects.
When i log the scene, or the marker, i only get references to the attributes, which don't seem to have the above objects attached.(like marker.arController, or marker.getAttribute('artoolkitmarker').arController)
Did anybody tried this and have any tips how to do this ?
PR303 introduces events when a marker is found and lost
markerFound
markerLost
You can use them by simply adding an event listener:
anchorRef.addEventListener("markerFound", (e)=>{ // your code here}
with a simple setup like this:
<a-marker id="anchor">
<a-entity>
</a-marker>
example here.
Please note, that as of sep 18', you need to use the dev branch to use the above.
ORIGINAL ANWSER - in case you want to do it manually
Detecting if the marker is found is possible by checking if the marker is visible when needed (other event, or on tick): if(document.querySelector("a-marker").object3D.visible == true)
For example:
init: function() {
this.marker = document.querySelector("a-marker")
this.markerVisible = false
},
tick: function() {
if (!this.marker) return
if (this.marker.object3D.visible) {
if (!this.markerVisible) {
// marker detected
this.markerVisible = true
}
} else {
if (this.markerVisbile) {
// lost sight of the marker
this.markerVisible = false
}
}
}
As adrian li noted, it doesn't work with a-marker-camera, only with a-markers
I went with a dirty hack diving into the internals, bear in mind that what I've provided might not suffice because the event get's called every time the marker is found, sadly I couldn't find an event to hook into for markers being lost.
const arController = document.querySelector("a-scene").systems.arjs._arSession.arContext.arController;
arController.addEventListener("getMarker", (evt) => {
const markerType = evt.data.type;
const patternType = 0;
//console.log("onMarkerFound!!");
if (markerType == patternType) {
//console.log("onMarkerFound out pattern!!");
//Do stuff...
}
});
I have a strange problem with the use of vector layers events.
Here is snipped of my code:
var options = {
projection : "EPSG:3857",
displayProjection : "EPSG:4326",
numZoomLevels : 18,
//after delete this part below of option everything works good
eventListeners: {
featureover: function(e) {
document.getElementById("output").innerHTML="ok';
}}};
map = new OpenLayers.Map('map', options);
w_parcels = new OpenLayers.Layer.Vector("PARCELS", {
styleMap : style_parcels,
projection : "EPSG:3857",
strategies : [ new OpenLayers.Strategy.Fixed() ],
protocol : new OpenLayers.Protocol.HTTP({
url : "parcels.php",
format : new OpenLayers.Format.GeoJSON()})
});
map.addLayers([osm,w_parcels]);
selectControl = new OpenLayers.Control.SelectFeature(w_parcels, {
clickout: false,
multiple: true,
onSelect : onFeatureSelect,
onUnselect : onFeatureUnselect,
toggleKey: "ctrlKey" // ctrl key removes from selection
});
selectControl.handlers.feature.stopDown = false;
map.addControl(selectControl);
selectControl.activate();
map.addControl(new OpenLayers.Control.ScaleLine());
function onFeatureSelect(feature) {
console.log('it works');
}
In this code event onselect dosen't work always when I click on feature on the layer(sometimes I have to do double click).
If I delete eventListeners from options , the onselect works perfect, I mean always when I click feature on the layer.
What is wrong in my code? Is the possibility to resolve this conflict betwween eventListeners an onselect?
Seems like, Event featureover masks the select control as that function will executes first while you select, as you must mouse over the Vector Layer for clicking it. But if the functionality is limited to select and mouse-over vector layer. Then you can use something like-
eventListeners: {
featureover: function(e) {
//behavior for hover events
},
featureout: function(e) {
//behavior for mouse out events
},
featureclick: function(e) {
//behavior for click events
}
}
Hope this helps.
I'm using Hammer.js to look for horizontal pan gestures, I've devised a simple function to clicks a button when panned left or right. It works okay, except the vertical scroll doesn't do anything on a touch device, or it's really glitchy and weird.
Here's the function:
var panelSliderPan = function() {
// Pan options
myOptions = {
// possible option
};
var myElement = document.querySelector('.scroll__inner'),
mc = new Hammer.Manager(myElement);
mc.add(new Hammer.Pan(myOptions));
// Pan control
var panIt = function(e) {
// I'm checking the direction here, my common sense says it shouldn't
// affect the vertical gestures, but it blocks them somehow
// 2 means it's left pan
if (e.direction === 2) {
$('.controls__btn--next').click();
// 4 == right
} else if (e.direction === 4) {
$('.controls__btn--prev').click();
}
};
// Call it
mc.on("panstart", function(e) {
panIt(e);
});
};
I've tried to add a horizontal direction to the recognizer but it didn't really help (not sure if I did it even right):
mc = new Hammer.Manager(myElement, {
recognizers: [
[Hammer.Pan,{ direction: Hammer.DIRECTION_HORIZONTAL }],
]
});
Thanks!
Try setting the touch-action property to auto.
mc = new Hammer.Manager(myElement, {
touchAction: 'auto',
recognizers: [
[Hammer.Pan,{ direction: Hammer.DIRECTION_HORIZONTAL }],
]
});
From the hammer.js docs:
When you set the touchAction to auto it doesnt prevent any defaults, and Hammer would probably break. You have to call preventDefault manually to fix this. You should only use this if you know what you're doing.
User patforna is correct. You need to adjust the touch-action property. This will fix scrolling not working when you have hammer bound on a big element in mobile.
You create a Hammer instance like so
var h = new Hammer(options.contentEl, {
touchAction : 'auto'
});
I was working on a pull to refresh feature, so I need the pan event.
Add the recognizers.
h.get( 'pan' ).set({
direction : Hammer.DIRECTION_VERTICAL,
});
h.on('panstart pandown panup panend', eventHandler);
Inside the eventhandler, you'd look at the event that was triggered and manually call on event.preventDefault() when you require it. This is applicable for hammer 2.0.6.
For anyone who's looking the pull to refresh code was taken from - https://github.com/apeatling/web-pull-to-refresh
My problem was that vertical scroll was toggling a sidebar that was supposed to show/hide on horizontal pan/swipe. After looking at the event details, I realized that Hammer probably triggers panleft and panright event based on X delta and doesn't consider Y delta, so my quick solution was to check the pan direction in my handler:
this.$data.$hammer.on('panleft', (e) => {
if (Math.abs(e.deltaY) > Math.abs(e.deltaX)) {
return;
}
this.isVisible = true;
});
I was stuck on this for several days. Hope this will fix your problem.
mc = new Hammer(myElement, {
inputClass: Hammer.SUPPORT_POINTER_EVENTS ? Hammer.PointerEventInput : Hammer.TouchInput,
touchAction: 'auto',
});
When the relevant gesture is triggered, we applied a css class to the element, that would set the touch-action to none.
mc.on('panmove panstart', event => {
mc.addClass('is-dragging');
}
);
.is-dragging {
touch-action: none !important;
}
Hammer 2.x does not support vertical swipe/pan. Documentation says:
Notes:
When calling Hammer() to create a simple instance, the pan and swipe recognizers are configured to only detect horizontal gestures
You can however use older 1.1.x version, which supports vertical gestures
——
Clarification: this refers to a ‘simple instance’ which is when you don’t pass in any recognizer configuration as the second parameter. In other words these are the defaults but can (and usually should) be overridden.
I work with Openlayers 2.x and I have zoomstart event
map.events.register('zoomstart', map, function(e) {
// 1. OpenLayers.Event.stop(event);
// 2. return ;
// 3. e.preventDefault();
}
});
My way (1,2,3) not working and event does not stop and change zoom level. Can anybody help me?
The zoom event is triggered by the zoomBarUp function in PanZoomBar control, see: http://trac.osgeo.org/openlayers/browser/trunk/openlayers/lib/OpenLayers/Control/PanZoomBar.js and the line
this.map.zoomTo(zoomLevel);
One way to prevent zoom for zoom levels above 13 would be to override this function, which you can do by adding your own version, either in a standalone js file or by using prototype within you OpenLayers init function, ie, after OpenLayers has loaded.
OpenLayers.Control.PanZoomBar.prototype.zoomBarUp = function(evt){
//copy here the code from the actual function
if (!OpenLayers.Event.isLeftClick(evt) && evt.type !== "touchend") {
return;
}
//rest of code .....
//put in your check for zoom level here before calling this.map.zoomTo(zoomLevel);
if(this.map.zoom<13){
this.map.zoomTo(zoomLevel);
this.mouseDragStart = null;
this.zoomStart = null;
this.deltaY = 0;
OpenLayers.Event.stop(evt);
}};
There may be a more elegant way, but this should work.
Highcharts offers the opportunity to detect clicks on chart points, but is it possible
to detect other events, such as the double click or mousedown event?
Thanks in advance
Each component only supports certain events, for example the Chart component will detect addSeries, click, load, redraw, and selection. I don't believe this set is extensible, so you can't capture a different event like mousedown.
You could try to inspect the source of your page and attach listeners to the elements that HighCharts generates, but this would be an undocumented work-around and would be liable to break in future releases. In addition, if you have to support < IE9 you would need handlers for both SVG and VML generated markup.
You can get creative with some events. Here's an example of detecting a double click using a click handler:
Working Demo
var clickDetected = false;
// create the chart
$('#container').highcharts({
chart: {
events: {
click: function(event) {
if(clickDetected) {
alert ('x: '+ event.xAxis[0].value +', y: '+ event.yAxis[0].value);
clickDetected = false;
} else {
clickDetected = true;
setTimeout(function() {
clickDetected = false;
}, 500);
}
}
}
},
...
It's possible, but in a different way. In Highcharts you can add event to each element using element.on. For example:
chart.series[0].data[0].graphic.on('dblclick', function() {
//callback here
});
And simple jsFiddle for you. Good thing is that you can add to all elements, and make sure work in all browsers.