UNPKG

mapbox-gl

Version:
214 lines (187 loc) 7.14 kB
'use strict'; var Interaction = require('./interaction'); var Point = require('point-geometry'); var util = require('../util/util'); var DOM = require('../util/dom'); var LatLngBounds = require('../geo/lat_lng_bounds'); module.exports = Handlers; function Handlers(map) { var rotateEnd, startScale, startBearing, box, inertiaLinearity = 0.2, inertiaEasing = util.bezier(0, 0, inertiaLinearity, 1); function boxzoomFinish() { if (box) { box.parentNode.removeChild(box); map.getContainer().classList.remove('mapboxgl-crosshair'); box = false; DOM.enableDrag(); } } this.interaction = new Interaction(map.getCanvas()) .on('click', function(e) { e.latLng = map.unproject(e.point); map.fire('click', e); }) .on('dblclick', function(e) { e.latLng = map.unproject(e.point); map.fire('dblclick', e); }) .on('mousemove', function(e) { e.latLng = map.unproject(e.point); map.fire('mousemove', e); }) .on('down', function() { map.fire('movestart'); }) .on('resize', function() { map.stop(); map.resize(); map.update(); }) .on('keydown', function(e) { if (e.altKey || e.ctrlKey || e.metaKey) return; var pan = 80; var rotate = 2; function zoomBy(z) { map.zoomTo(Math.round(map.getZoom()) + (e.shiftKey ? 2 : 1) * z); } function panBy(v) { map.panBy(v); } function rotateBy(v) { map.setBearing(map.getBearing() + v); } switch (e.keyCode) { case 61: case 107: case 171: case 187: zoomBy(1); break; case 189: case 109: case 173: zoomBy(-1); break; case 37: if (e.shiftKey) { rotateBy(-rotate); } else { panBy([-pan, 0]); } break; case 39: if (e.shiftKey) { rotateBy(rotate); } else { panBy([pan, 0]); } break; case 38: panBy([0, -pan]); break; case 40: panBy([0, pan]); break; default: return; } }) .on('pan', function(e) { map.stop(); var mouseLocation = map.transform.pointLocation(e.point.add(e.offset)); map.transform.setLocationAtPoint(mouseLocation, e.point); map.fire('move'); }) .on('panend', function(e) { if (!e.inertia) { map.fire('moveend'); } else { // convert velocity to px/s & adjust for increased initial animation speed when easing out var velocity = e.inertia.mult(1000 * inertiaLinearity), speed = velocity.mag(); var maxSpeed = 4000; // px/s if (speed >= maxSpeed) { speed = maxSpeed; velocity._unit()._mult(maxSpeed); } var deceleration = 8000, // px/s^2 duration = speed / (deceleration * inertiaLinearity), offset = velocity.mult(-duration / 2).round(); map.panBy(offset, { duration: duration * 1000, easing: inertiaEasing, noMoveStart: true }); } }) .on('zoom', function(e) { // Scale by sigmoid of scroll wheel delta. var scale = 2 / (1 + Math.exp(-Math.abs(e.delta / 100))); if (e.delta < 0 && scale !== 0) scale = 1 / scale; var fromScale = map.ease && isFinite(e.delta) ? map.ease.to : map.transform.scale, duration = !isFinite(e.delta) ? 800 : 0, targetZoom = map.transform.scaleZoom(fromScale * scale); map.zoomTo(targetZoom, { duration: duration, around: map.unproject(e.point) }); }) .on('pinchstart', function() { startScale = map.transform.scale; startBearing = map.transform.bearing; }) .on('pinch', function(e) { map.easeTo({ zoom: map.transform.scaleZoom(startScale * e.scale), bearing: startBearing + e.bearing, duration: 0, around: map.unproject(e.point) }); }) .on('rotate', function(e) { var center = map.transform.centerPoint, // Center of rotation startToCenter = e.start.sub(center), startToCenterDist = startToCenter.mag(); map.rotating = true; // If the first click was too close to the center, move the center of rotation by 200 pixels // in the direction of the click. if (startToCenterDist < 200) { center = e.start.add(new Point(-200, 0)._rotate(startToCenter.angle())); } var bearingDiff = e.prev.sub(center).angleWith(e.current.sub(center)) / Math.PI * 180; map.transform.bearing = map.getBearing() - bearingDiff; map.fire('move').fire('rotate'); window.clearTimeout(rotateEnd); rotateEnd = window.setTimeout(function() { map.rotating = false; map._rerender(); }, 200); }) .on('boxzoomstart', function(e) { if (!box) { box = DOM.create('div', 'mapboxgl-boxzoom', map.getContainer()); map.getContainer().classList.add('mapboxgl-crosshair'); map.fire('boxzoomstart'); DOM.disableDrag(); } var minX = Math.min(e.start.x, e.current.x); var maxX = Math.max(e.start.x, e.current.x); var minY = Math.min(e.start.y, e.current.y); var maxY = Math.max(e.start.y, e.current.y); DOM.setTransform(box, 'translate(' + minX + 'px,' + minY + 'px)'); box.style.width = (maxX - minX) + 'px'; box.style.height = (maxY - minY) + 'px'; }) .on('boxzoomend', function(e) { boxzoomFinish(); var bounds = new LatLngBounds( map.unproject(e.start), map.unproject(e.current) ); map.fitBounds(bounds, { linear: true }).fire('boxzoomend', { boxZoomBounds: bounds }); }) .on('boxzoomcancel', boxzoomFinish); }