<title>Modest Maps JS - Throwable Test</title>
<script type="text/javascript" src="modestmaps.min.js"></script>
<script type="text/javascript">
MM.ThrowableHandler = function() { }
MM.ThrowableHandler.prototype = {
MM.addEvent(map.parent, 'click', function(e) { map.parent.focus() });
MM.addEvent(map.parent, 'keydown', MM.bind(this.keyDown, this));
MM.addEvent(map.parent, 'keyup', MM.bind(this.keyUp, this));
MM.addEvent(map.parent, 'mousedown', MM.bind(this.mouseDown, this));
MM.addEvent(map.parent, 'mousemove', MM.bind(this.mouseMove, this));
MM.addEvent(map.parent, 'mouseup', MM.bind(this.mouseUp, this));
MM.addEvent(map.parent, 'mousewheel', MM.bind(this.mouseWheel, this));
// tick every frame for time-based anim
this.prevT = new Date().getTime();
this.boundAnimate = MM.bind(this.animate, this);
this.speed = { x: 0, y: 0 };
MM.getFrame(this.boundAnimate);
trappedKeys: { 37: true, 38: true, 39: true, 40: true },
var dir = { x: 0, y: 0 };
if (this.keysPressed[37]) {
if (this.keysPressed[38]) {
if (this.keysPressed[39]) {
if (this.keysPressed[40]) {
var dt = Math.max(0.001,(t - this.prevT) / 1000.0);
var len = Math.sqrt(dir.x*dir.x + dir.y*dir.y);
this.speed.x += dir.x * this.acceleration * dt;
this.speed.y += dir.y * this.acceleration * dt;
else if (this.mousePoint && this.prevMousePoint) {
dir.x = this.mousePoint.x - this.prevMousePoint.x;
dir.y = this.mousePoint.y - this.prevMousePoint.y;
this.speed.x -= this.speed.x * this.drag;
this.speed.y -= this.speed.y * this.drag;
if (Math.abs(this.speed.x) < 0.001) {
if (Math.abs(this.speed.y) < 0.001) {
if (this.speed.x || this.speed.y) {
this.map.panBy(this.speed.x,this.speed.y);
if (this.zoomSpeed && this.zoomPoint) {
this.map.zoomByAbout(this.zoomSpeed * dt, this.zoomPoint);
this.zoomSpeed -= this.zoomSpeed * 0.125;
if (Math.abs(this.zoomSpeed) < 0.001) {
// tick every frame for time-based anim accuracy
MM.getFrame(this.boundAnimate);
if (!(e.keyCode in this.keysPressed)) {
this.keysPressed[e.keyCode] = true;
if (e.keyCode in this.trappedKeys) {
return MM.cancelEvent(e);
delete this.keysPressed[e.keyCode];
if (e.keyCode in this.trappedKeys) {
return MM.cancelEvent(e);
this.mousePoint = this.prevMousePoint = MM.getMousePoint(e,this.map);
return MM.cancelEvent(e);
this.prevMousePoint = this.mousePoint;
this.mousePoint = MM.getMousePoint(e,this.map);
return MM.cancelEvent(e);
this.mousePoint = this.prevMousePoint = null;
return MM.cancelEvent(e);
mouseWheel: function(e) {
// normalize, just want direction
if (Math.abs(delta) > 0) {
this.zoomPoint = MM.getMousePoint(e, this.map);
//console.log(delta/100.0);
this.zoomSpeed += Math.max(-1, Math.min(delta/100.0, 1));
// Cancel the event so that the page doesn't scroll
return MM.cancelEvent(e);
var provider = new MM.TemplatedMapProvider('https://tile.stamen.com/watercolor/{Z}/{X}/{Y}.jpg');
var handler = new MM.ThrowableHandler();
var dragSlider = document.getElementById('drag');
var dragValue = document.getElementById('dragvalue');
dragSlider.onchange = function() {
handler.drag = parseFloat((dragSlider.value - dragSlider.min) / (dragSlider.max - dragSlider.min)) / 10.0;
dragValue.innerHTML = handler.drag.toFixed(3);
dragValue.innerHTML = handler.drag.toFixed(3);
map.enablePyramidLoading = true;
map.setCenterZoom(new MM.Location(37.811530, -122.2666097), 10);
var zoomSlider = document.getElementById('zoom');
var zoomValue = document.getElementById('zoomvalue');
var targetZoom = map.getZoom();
zoomSlider.onchange = function() {
var sliderProp = (zoomSlider.value - zoomSlider.min) / (zoomSlider.max - zoomSlider.min);
targetZoom = sliderProp * 18.0;
MM.getFrame(animateToZoom);
function animateToZoom() {
var currentZoom = map.getZoom();
var nextZoom = currentZoom + (targetZoom-currentZoom) * 0.2;
if (Math.abs(nextZoom - currentZoom) < 0.001) {
MM.getFrame(animateToZoom);
zoomValue.innerHTML = nextZoom.toFixed(2);
zoomValue.innerHTML = targetZoom;
-webkit-user-select: none;
text-shadow: 1px 2px 2px rgba(0,0,0,0.5);
<body onload="initMap()">
<div id="map" tabindex="0"></div>
<p id="instructions">Click/drag to throw the map, or press and hold the arrow keys to fly around.</p>
drag <span id="dragvalue"></span>: <input id="drag" type="range" value="1000" min="0" max="2000"></input><br>
zoom <span id="zoomvalue"></span>: <input id="zoom" type="range" value="10000" min="0" max="18000"></input>
<p id="credit">Built with <a href="https://github.com/stamen/modestmaps-js/">Modest Maps JS</a>. Tiles Courtesy of <a href="https://www.mapquest.com/" target="_blank">MapQuest</a> <img src="https://developer.mapquest.com/content/osm/mq_logo.png"></p>