UNPKG

gars_v2

Version:

Geo Assistant Research System

185 lines (167 loc) 5.95 kB
import Data from './data'; import fileUrl from 'file-url'; class Map { constructor($parent) { // wrap the absolute positioned $view to enable areaselector on $img var $view = $('<div>').addClass('view').appendTo($parent); var $img = $('<img>').addClass('img').appendTo($view); var mc = new window.Hammer.Manager($view.get(0)); var pinch = new window.Hammer.Pinch(); var pan = new window.Hammer.Pan(); mc.add([pinch, pan]); this.mc = mc; this.$view = $view; this.$img = $img; this.loaded = false; this.$parent = $parent; $(window).resize(() => this.updateViewport()); this.start(); } start() { var panX, panY; this.mc.on('panstart', () => { panX = panY = 0; }); this.mc.on("panmove", ev => { console.log('panmove', ev); var x = ev.deltaX - panX; var y = ev.deltaY - panY; this.translate(x, y); panX = ev.deltaX; panY = ev.deltaY; }); var initScale; this.mc.on("pinchstart", ev => { console.log('pinchstart', ev); initScale = this.scale; }); this.mc.on("pinch", ev => { console.log('pinch', ev); this.zoom(initScale * ev.scale, ev.center.x, ev.center.y); }); this.$view.on('wheel', e => { console.log('wheel', e); e = e.originalEvent; if (e.wheelDelta === 0) return; var scale = e.wheelDelta > 0 ? 0.05 : -0.05; this.zoom(this.scale * (1 + scale), e.pageX, e.pageY); }); } stop() { this.mc.off('panstart panmove pinchstart pinch'); this.$view.off('wheel'); } updateViewport() { var $parent = this.$parent; this.parentWidth = $parent.width(); this.parentHeight = $parent.height(); if (this.width !== undefined) { this.maxScale = 10; this.minScale = Math.min( this.parentWidth / this.width, this.parentHeight / this.height ); this.applyTransform(); } } zoom(scale, x2parent, y2parent) { // do normalization scale = limit(scale, this.minScale, this.maxScale); x2parent = (x2parent === undefined) ? this.parentWidth / 2 : x2parent; y2parent = (y2parent === undefined) ? this.parentHeight / 2 : y2parent; console.log('zooming', scale, 'from x:', x2parent, 'y:', y2parent); var x2img = x2parent - this.x; var y2img = y2parent - this.y; this.x -= x2img * (scale - this.scale) / this.scale; this.y -= y2img * (scale - this.scale) / this.scale; this.scale = scale; this.applyTransform(); } translate(x, y) { this.x += x; this.y += y; this.applyTransform(); } applyTransform() { var x = this.x, y = this.y, s = this.scale; s = limit(s, this.minScale, this.maxScale); x = limit(x, this.parentWidth - this.width * s, 0); y = limit(y, this.parentHeight - this.height * s, 0); this.setSize(s * this.width, s * this.height); this.setPosition(x, y); this.scale = s; this.x = x; this.y = y; } setPosition(x, y) { this.$view.css('left', `${x}px`); this.$view.css('top', `${y}px`); } setSize(width, height) { this.$img.css('width', `${width}px`); this.$img.css('height', `${height}px`); } open(filepath) { var url = fileUrl(filepath); var $spin = $('<i>').addClass('fa fa-spin fa-cog').insertBefore(this.$view); console.log('loading image:', url); this.$img.attr('src', url); this.loaded = false; loadImage(filepath).then(({ width, height }) => { console.log('image loaded, width:', width, 'height', height); $spin.remove(); this.setSize(width, height); this.loaded = true; this.width = width; this.height = height; this.x = 0; this.y = 0; this.scale = 1; this.updateViewport(); // sets minscale this.zoom(this.minScale); }); var data = new Data(); var datapath = filepath.replace(/\..+/, '.gars'); console.log('loading map data from', datapath); return data.read(datapath).then(() => data); } reopen(filepath) { var url = fileUrl(filepath); console.log('loading image:', url); var widthSav = this.width; var heightSav = this.height; this.$img.attr('src', url); this.loaded = false; loadImage(filepath).then(({ width, height }) => { console.log('image loaded, width:', width, 'height', height); this.setSize(widthSav, heightSav); this.loaded = true; this.width = widthSav; this.height = heightSav; this.updateViewport(); // sets minscale }); var data = new Data(); var datapath = filepath.replace(/\..+/, '.gars'); console.log('loading map data from', datapath); return data.read(datapath).then(() => data); } onclose() {} } function loadImage(src) { var image = new Image(); image.src = src; return new Promise(function(resolve) { image.onload = function() { resolve({ width: image.width, height: image.height }); }; }); } function limit(x, lower, upper) { return Math.min(upper, Math.max(lower, x)); } export default Map;