D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
RandomEtc
Full window
Github gist
Modest Maps Throwable
<!DOCTYPE html> <html> <head> <title>Modest Maps JS - Throwable Test</title> <script type="text/javascript" src="modestmaps.min.js"></script> <script type="text/javascript"> (function(MM){ MM.ThrowableHandler = function() { } MM.ThrowableHandler.prototype = { init: function(map) { this.map = map; 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); }, keyCount: 0, keysPressed: {}, trappedKeys: { 37: true, 38: true, 39: true, 40: true }, animate: null, prevT: 0, acceleration: 25.0, speed: null, boundAnimate: null, drag: 0.05, mouseDownPoint: null, mousePoint: null, mouseDownTime: 0, zoomSpeed: 0, zoomPoint: null, animate: function(t) { var dir = { x: 0, y: 0 }; if (this.keysPressed[37]) { dir.x += 1; } if (this.keysPressed[38]) { dir.y += 1; } if (this.keysPressed[39]) { dir.x -= 1; } if (this.keysPressed[40]) { dir.y -= 1; } var dt = Math.max(0.001,(t - this.prevT) / 1000.0); if (dir.x || dir.y) { var len = Math.sqrt(dir.x*dir.x + dir.y*dir.y); dir.x /= len; dir.y /= len; 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 = dir.x; this.speed.y = dir.y; } else { this.speed.x -= this.speed.x * this.drag; this.speed.y -= this.speed.y * this.drag; if (Math.abs(this.speed.x) < 0.001) { this.speed.x = 0; } if (Math.abs(this.speed.y) < 0.001) { this.speed.y = 0; } } 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) { this.zoomSpeed = 0; } } this.prevT = t; // tick every frame for time-based anim accuracy MM.getFrame(this.boundAnimate); }, keyDown: function(e) { if (!(e.keyCode in this.keysPressed)) { this.keysPressed[e.keyCode] = true; this.keyCount++; } if (e.keyCode in this.trappedKeys) { return MM.cancelEvent(e); } }, keyUp: function(e) { this.keyCount--; delete this.keysPressed[e.keyCode]; if (e.keyCode in this.trappedKeys) { return MM.cancelEvent(e); } }, mouseDown: function(e) { this.mousePoint = this.prevMousePoint = MM.getMousePoint(e,this.map); return MM.cancelEvent(e); }, mouseMove: function(e) { if (this.mousePoint) { this.prevMousePoint = this.mousePoint; this.mousePoint = MM.getMousePoint(e,this.map); return MM.cancelEvent(e); } }, mouseUp: function(e) { this.mousePoint = this.prevMousePoint = null; return MM.cancelEvent(e); }, mouseWheel: function(e) { var delta = 0; // normalize, just want direction if (e.wheelDelta) { delta = e.wheelDelta; } else if (e.detail) { delta = -e.detail; } 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); } }; })(com.modestmaps); var MM = com.modestmaps; var map; function initMap() { 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 = new MM.Map('map', provider, null, [ handler ]); map.enablePyramidLoading = true; map.setCenterZoom(new MM.Location(37.811530, -122.2666097), 10); map.parent.focus(); 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) { nextZoom = currentZoom; } else { MM.getFrame(animateToZoom); } map.setZoom(nextZoom); zoomValue.innerHTML = nextZoom.toFixed(2); } zoomValue.innerHTML = targetZoom; } </script> <style type="text/css"> html, body, #map { width: 100%; height: 100%; margin: 0; padding: 0; border: 0; } #map:focus { outline: 0; } #map img { -webkit-user-select: none; -webkit-user-drag: none; -moz-user-drag: none; } p { font-family: sans-serif; position: absolute; margin: 0; padding: 5px; background: transparent; color: white; text-shadow: 1px 2px 2px rgba(0,0,0,0.5); } a { color: #ccf; } #instructions { top: 15px; left: 15px; } #credit { bottom: 15px; right: 15px; } #controls { text-align: right; top: 15px; right: 15px; } </style> </head> <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> <p id="controls"> 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> <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> </body> </html>