diff --git a/virtualsky.js b/virtualsky.js index bcb74b9..7c71a03 100644 --- a/virtualsky.js +++ b/virtualsky.js @@ -283,7 +283,7 @@ function VirtualSky(input){ this.transparent = false; // Show the sky background or not this.fps = 10; // Number of frames per second when animating this.credit = (location.host == "lco.global" && location.href.indexOf("/embed") < 0) ? false : true; - this.callback = { geo:'', mouseenter:'', mouseout:'', contextmenu: '', cursor: '', click:'' }; + this.callback = { geo:'', mouseenter:'', mouseout:'', contextmenu: '', cursor: '', click:'', draw: '' }; this.lookup = {}; this.keys = []; this.base = ""; @@ -1073,6 +1073,7 @@ VirtualSky.prototype.init = function(d){ if(is(d.callback.mouseout,f)) this.callback.mouseout = d.callback.mouseout; if(is(d.callback.cursor,f)) this.callback.cursor = d.callback.cursor; if(is(d.callback.contextmenu,f)) this.callback.contextmenu = d.callback.contextmenu; + if(is(d.callback.draw,f)) this.callback.draw = d.callback.draw; } return this; }; @@ -1381,27 +1382,60 @@ VirtualSky.prototype.createSky = function(){ ctx.fillText(loading,(ctx.wide-ctx.measureText(loading).width)/2,(this.tall-fs)/2); ctx.fill(); - var contextMenuHandler = (!this.callback.contextmenu) ? undefined : { - longPressStart: function(x,y){ - contextMenuHandler.longPressStop(); - this.longPressTimer = window.setTimeout(function() { - this.longPressTimer = undefined; - this.dragging = false; - this.x = ""; - this.y = ""; - this.theta = ""; - contextMenuHandler.click(x,y); - }, 400 /** 400ms for long press */); + var touchClickHandler = (!this.callback.contextmenu && !this.callback.click) ? undefined : { + // Indicate an immobile press is occuring. It will lead to context menu or click depending on its duration + clickActive: false, + clickDone: false, + // Timer that differentiate between long/short press + longPressTimer: undefined, + + clickStart: function(e){ + e.originalEvent.preventDefault(); + touchClickHandler.clickCancel(); + touchClickHandler.clickActive = true; + touchClickHandler.clickDone = false; + touchClickHandler.initialTouchEvent = e; + if (this.callback.contextmenu) { + touchClickHandler.longPressTimer = window.setTimeout(function() { + touchClickHandler.clickActive = false; + touchClickHandler.longPressTimer = undefined; + this.dragging = false; + this.x = ""; + this.y = ""; + this.theta = ""; + + if (this.callback.contextmenu) { + touchClickHandler.clickDone = true; + this.callback.contextmenu.call(e.data.sky, e); + } + }.bind(this), 400 /** 400ms for long press */); + } + }.bind(this), + + clickEnd: function(e) { + if (touchClickHandler.clickActive) { + var initialTouchEvent = touchClickHandler.initialTouchEvent; + touchClickHandler.clickCancel(); + + if(e.data.sky.callback.click){ + touchClickHandler.clickDone = true; + e.data.sky.callback.click.call(initialTouchEvent.data.sky, initialTouchEvent); + } + } }.bind(this), - longPressStop: function(){ - if (this.longPressTimer !== undefined) { - window.clearTimeout(this.longPressTimer); - this.longPressTimer = undefined; + + clickCancel: function(){ + touchClickHandler.clickActive = false; + touchClickHandler.initialTouchEvent = undefined; + if (touchClickHandler.longPressTimer !== undefined) { + window.clearTimeout(touchClickHandler.longPressTimer); + touchClickHandler.longPressTimer = undefined; } - }.bind(this) + return !touchClickHandler.clickDone; + }.bind(this), }; - function getXYProperties(e,sky){ + getXYProperties =function (e,sky){ e.matched = sky.whichPointer(e.x,e.y); var skyPos = sky.xy2radec(e.x,e.y); if(skyPos){ @@ -1415,6 +1449,11 @@ VirtualSky.prototype.createSky = function(){ e.y = o.pageY - el.offset().top - window.scrollY; return getXYProperties(e,sky); } + function getTouchXY(sky,o,el,e) { + e.x = o.touches[0].pageX - el.offset().left - window.scrollX; + e.y = o.touches[0].pageY - el.offset().top - window.scrollY; + return getXYProperties(e,sky); + } S("#"+this.idinner).on('click',{sky:this},function(e){ e.data.sky.debug('click'); @@ -1496,7 +1535,11 @@ VirtualSky.prototype.createSky = function(){ if(typeof s.callback.mouseenter=="function") s.callback.mouseenter.call(s); }).on('touchmove',{sky:this},function(e){ e.preventDefault(); - if(contextMenuHandler) contextMenuHandler.longPressStop(); + if(touchClickHandler) { + if (!touchClickHandler.clickCancel()) { + return; + } + } var s = e.data.sky; var x = e.originalEvent.touches[0].pageX; var y = e.originalEvent.touches[0].pageY; @@ -1529,17 +1572,8 @@ VirtualSky.prototype.createSky = function(){ }).on('touchstart',{sky:this},function(e){ e.data.sky.debug('touchstart'); e.data.sky.dragging = true; - if(contextMenuHandler){ - var x = e.originalEvent.touches[0].pageX; - var y = e.originalEvent.touches[0].pageY; - x = x - this.offset().left - window.scrollX; - y = y - this.offset().top - window.scrollY; - contextMenuHandler.longPressStart(x, y); - if(e.data.sky.callback.click){ - e.x = x; - e.y = y; - e.data.sky.callback.click.call(e.data.sky,getXYProperties(e,e.data.sky)); - } + if(touchClickHandler){ + touchClickHandler.clickStart(getTouchXY(e.data.sky,e.originalEvent,this,e)); } }).on('touchend',{sky:this},function(e){ e.data.sky.debug('touchend'); @@ -1547,7 +1581,9 @@ VirtualSky.prototype.createSky = function(){ e.data.sky.x = ""; e.data.sky.y = ""; e.data.sky.theta = ""; - if(contextMenuHandler) contextMenuHandler.longPressStop(); + if(touchClickHandler) { + touchClickHandler.clickEnd(e); + } }).on((isEventSupported('mousewheel') ? 'mousewheel' : 'wheel'),{sky:this},function(e) { e.preventDefault(); e.data.sky.debug('mousewheel'); @@ -2264,6 +2300,16 @@ VirtualSky.prototype.draw = function() { this.pendingRefresh = window.setTimeout(this.drawImmediate.bind(this), 20); }; +VirtualSky.prototype.invokeDrawCb = function(visible){ + if (typeof this.callback.draw) { + var self = this; + function callCb() { + self.callback.draw(visible); + } + window.setTimeout(callCb, 0); + } +} + VirtualSky.prototype.drawImmediate = function(proj){ // Don't bother drawing anything if there is no physical area to draw on if (this.pendingRefresh !== undefined) { @@ -2271,8 +2317,14 @@ VirtualSky.prototype.drawImmediate = function(proj){ this.pendingRefresh = undefined; } - if(this.wide <= 0 || this.tall <= 0) return this; - if(!(this.c && this.c.getContext)) return this; + if(this.wide <= 0 || this.tall <= 0) { + this.invokeDrawCb(false); + return this; + } + if(!(this.c && this.c.getContext)) { + this.invokeDrawCb(false); + return this; + } if(proj !== undefined) this.selectProjection(proj); var white = this.col.white; @@ -2485,7 +2537,7 @@ VirtualSky.prototype.drawImmediate = function(proj){ if(typeof s.callback.geo=="function") s.callback.geo.call(s); }); } - + this.invokeDrawCb(true); off = S('#'+this.idinner).position(); S('.'+this.id+'_position').css({ position:'absolute',