/** * Created by Alex on 2/27/2015. * */ import {SelectionHandler} from "./components/SelectionHandler" var util = require('../../util'); class TouchEventHandler { constructor(body) { this.body = body; this.body.eventListeners.onTap = this.onTap.bind(this); this.body.eventListeners.onTouch = this.onTouch.bind(this); this.body.eventListeners.onDoubleTap = this.onDoubleTap.bind(this); this.body.eventListeners.onHold = this.onHold.bind(this); this.body.eventListeners.onDragStart = this.onDragStart.bind(this); this.body.eventListeners.onDrag = this.onDrag.bind(this); this.body.eventListeners.onDragEnd = this.onDragEnd.bind(this); this.body.eventListeners.onMouseWheel = this.onMouseWheel.bind(this); this.body.eventListeners.onPinch = this.onPinch.bind(this); this.body.eventListeners.onMouseMove = this.onMouseMove.bind(this); this.body.eventListeners.onRelease = this.onRelease.bind(this); this.touchTime = 0; this.drag = {}; this.pinch = {}; this.pointerPosition = {x:0,y:0}; this.scale = 1.0; this.body.emitter.on("_setScale", (scale) => this.scale = scale); this.selectionHandler = new SelectionHandler(body); } setCanvas(canvas) { this.canvas = canvas; this.selectionHandler.setCanvas(canvas); } /** * Get the pointer location from a touch location * @param {{pageX: Number, pageY: Number}} touch * @return {{x: Number, y: Number}} pointer * @private */ getPointer(touch) { return { x: touch.pageX - util.getAbsoluteLeft(this.canvas.frame.canvas), y: touch.pageY - util.getAbsoluteTop(this.canvas.frame.canvas) }; } /** * On start of a touch gesture, store the pointer * @param event * @private */ onTouch(event) { if (new Date().valueOf() - this.touchTime > 100) { this.drag.pointer = this.getPointer(event.gesture.center); this.drag.pinched = false; this.pinch.scale = this.scale; // to avoid double fireing of this event because we have two hammer instances. (on canvas and on frame) this.touchTime = new Date().valueOf(); } } /** * handle tap/click event: select/unselect a node * @private */ onTap(event) { console.log("tap",event) var pointer = this.getPointer(event.gesture.center); this.pointerPosition = pointer; this.selectionHandler.selectOnPoint(pointer); } /** * handle drag start event * @private */ /** * This function is called by onDragStart. * It is separated out because we can then overload it for the datamanipulation system. * * @private */ onDragStart(event) { // in case the touch event was triggered on an external div, do the initial touch now. //if (this.drag.pointer === undefined) { // this.onTouch(event); //} // //var node = this._getNodeAt(this.drag.pointer); //// note: drag.pointer is set in onTouch to get the initial touch location // //this.drag.dragging = true; //this.drag.selection = []; //this.drag.translation = this._getTranslation(); //this.drag.nodeId = null; //this.draggingNodes = false; // //if (node != null && this.constants.dragNodes == true) { // this.draggingNodes = true; // this.drag.nodeId = node.id; // // select the clicked node if not yet selected // if (!node.isSelected()) { // this._selectObject(node, false); // } // // this.emit("dragStart", {nodeIds: this.getSelection().nodes}); // // // create an array with the selected nodes and their original location and status // for (var objectId in this.selectionObj.nodes) { // if (this.selectionObj.nodes.hasOwnProperty(objectId)) { // var object = this.selectionObj.nodes[objectId]; // var s = { // id: object.id, // node: object, // // // store original x, y, xFixed and yFixed, make the node temporarily Fixed // x: object.x, // y: object.y, // xFixed: object.xFixed, // yFixed: object.yFixed // }; // // object.xFixed = true; // object.yFixed = true; // // this.drag.selection.push(s); // } // } //} } /** * handle drag event * @private */ onDrag(event) { //if (this.drag.pinched) { // return; //} // //// remove the focus on node if it is focussed on by the focusOnNode //this.releaseNode(); // //var pointer = this.getPointer(event.gesture.center); //var me = this; //var drag = this.drag; //var selection = drag.selection; //if (selection && selection.length && this.constants.dragNodes == true) { // // calculate delta's and new location // var deltaX = pointer.x - drag.pointer.x; // var deltaY = pointer.y - drag.pointer.y; // // // update position of all selected nodes // selection.forEach(function (s) { // var node = s.node; // // if (!s.xFixed) { // node.x = me._XconvertDOMtoCanvas(me._XconvertCanvasToDOM(s.x) + deltaX); // } // // if (!s.yFixed) { // node.y = me._YconvertDOMtoCanvas(me._YconvertCanvasToDOM(s.y) + deltaY); // } // }); // // // // start _animationStep if not yet running // if (!this.moving) { // this.moving = true; // this.start(); // } //} //else { // // move the network // if (this.constants.dragNetwork == true) { // // if the drag was not started properly because the click started outside the network div, start it now. // if (this.drag.pointer === undefined) { // this._handleDragStart(event); // return; // } // var diffX = pointer.x - this.drag.pointer.x; // var diffY = pointer.y - this.drag.pointer.y; // // this._setTranslation( // this.drag.translation.x + diffX, // this.drag.translation.y + diffY // ); // this._redraw(); // } //} } /** * handle drag start event * @private */ onDragEnd(event) { //this.drag.dragging = false; //var selection = this.drag.selection; //if (selection && selection.length) { // selection.forEach(function (s) { // // restore original xFixed and yFixed // s.node.xFixed = s.xFixed; // s.node.yFixed = s.yFixed; // }); // this.moving = true; // this.start(); //} //else { // this._redraw(); //} //if (this.draggingNodes == false) { // this.emit("dragEnd", {nodeIds: []}); //} //else { // this.emit("dragEnd", {nodeIds: this.getSelection().nodes}); //} } /** * handle doubletap event * @private */ onDoubleTap(event) { //var pointer = this.getPointer(event.gesture.center); //this._handleDoubleTap(pointer); } /** * handle long tap event: multi select nodes * @private */ onHold(event) { //var pointer = this.getPointer(event.gesture.center); //this.pointerPosition = pointer; //this._handleOnHold(pointer); } /** * handle the release of the screen * * @private */ onRelease(event) { //var pointer = this.getPointer(event.gesture.center); //this._handleOnRelease(pointer); } /** * Handle pinch event * @param event * @private */ onPinch(event) { //var pointer = this.getPointer(event.gesture.center); // //this.drag.pinched = true; //if (!('scale' in this.pinch)) { // this.pinch.scale = 1; //} // //// TODO: enabled moving while pinching? //var scale = this.pinch.scale * event.gesture.scale; //this._zoom(scale, pointer) } /** * Zoom the network in or out * @param {Number} scale a number around 1, and between 0.01 and 10 * @param {{x: Number, y: Number}} pointer Position on screen * @return {Number} appliedScale scale is limited within the boundaries * @private */ _zoom(scale, pointer) { //if (this.constants.zoomable == true) { // var scaleOld = this._getScale(); // if (scale < 0.00001) { // scale = 0.00001; // } // if (scale > 10) { // scale = 10; // } // // var preScaleDragPointer = null; // if (this.drag !== undefined) { // if (this.drag.dragging == true) { // preScaleDragPointer = this.canvas.DOMtoCanvas(this.drag.pointer); // } // } // // + this.canvas.frame.canvas.clientHeight / 2 // var translation = this._getTranslation(); // // var scaleFrac = scale / scaleOld; // var tx = (1 - scaleFrac) * pointer.x + translation.x * scaleFrac; // var ty = (1 - scaleFrac) * pointer.y + translation.y * scaleFrac; // // this._setScale(scale); // this._setTranslation(tx, ty); // // if (preScaleDragPointer != null) { // var postScaleDragPointer = this.canvas.canvasToDOM(preScaleDragPointer); // this.drag.pointer.x = postScaleDragPointer.x; // this.drag.pointer.y = postScaleDragPointer.y; // } // // this._redraw(); // // if (scaleOld < scale) { // this.emit("zoom", {direction: "+"}); // } // else { // this.emit("zoom", {direction: "-"}); // } // // return scale; //} } /** * Event handler for mouse wheel event, used to zoom the timeline * See http://adomas.org/javascript-mouse-wheel/ * https://github.com/EightMedia/hammer.js/issues/256 * @param {MouseEvent} event * @private */ onMouseWheel(event) { //// retrieve delta //var delta = 0; //if (event.wheelDelta) { /* IE/Opera. */ // delta = event.wheelDelta / 120; //} else if (event.detail) { /* Mozilla case. */ // // In Mozilla, sign of delta is different than in IE. // // Also, delta is multiple of 3. // delta = -event.detail / 3; //} // //// If delta is nonzero, handle it. //// Basically, delta is now positive if wheel was scrolled up, //// and negative, if wheel was scrolled down. //if (delta) { // // // calculate the new scale // var scale = this._getScale(); // var zoom = delta / 10; // if (delta < 0) { // zoom = zoom / (1 - zoom); // } // scale *= (1 + zoom); // // // calculate the pointer location // var gesture = hammerUtil.fakeGesture(this, event); // var pointer = this.getPointer(gesture.center); // // // apply the new scale // this._zoom(scale, pointer); //} // //// Prevent default actions caused by mouse wheel. //event.preventDefault(); } /** * Mouse move handler for checking whether the title moves over a node with a title. * @param {Event} event * @private */ onMouseMove(event) { //var gesture = hammerUtil.fakeGesture(this, event); //var pointer = this.getPointer(gesture.center); //var popupVisible = false; // //// check if the previously selected node is still selected //if (this.popup !== undefined) { // if (this.popup.hidden === false) { // this._checkHidePopup(pointer); // } // // // if the popup was not hidden above // if (this.popup.hidden === false) { // popupVisible = true; // this.popup.setPosition(pointer.x + 3, pointer.y - 5) // this.popup.show(); // } //} // //// if we bind the keyboard to the div, we have to highlight it to use it. This highlights it on mouse over //if (this.constants.keyboard.bindToWindow == false && this.constants.keyboard.enabled == true) { // this.canvas.frame.focus(); //} // //// start a timeout that will check if the mouse is positioned above an element //if (popupVisible === false) { // var me = this; // var checkShow = function() { // me._checkShowPopup(pointer); // }; // // if (this.popupTimer) { // clearInterval(this.popupTimer); // stop any running calculationTimer // } // if (!this.drag.dragging) { // this.popupTimer = setTimeout(checkShow, this.constants.tooltip.delay); // } //} // ///** // * Adding hover highlights // */ //if (this.constants.hover == true) { // // removing all hover highlights // for (var edgeId in this.hoverObj.edges) { // if (this.hoverObj.edges.hasOwnProperty(edgeId)) { // this.hoverObj.edges[edgeId].hover = false; // delete this.hoverObj.edges[edgeId]; // } // } // // // adding hover highlights // var obj = this._getNodeAt(pointer); // if (obj == null) { // obj = this._getEdgeAt(pointer); // } // if (obj != null) { // this._hoverObject(obj); // } // // // removing all node hover highlights except for the selected one. // for (var nodeId in this.hoverObj.nodes) { // if (this.hoverObj.nodes.hasOwnProperty(nodeId)) { // if (obj instanceof Node && obj.id != nodeId || obj instanceof Edge || obj == null) { // this._blurObject(this.hoverObj.nodes[nodeId]); // delete this.hoverObj.nodes[nodeId]; // } // } // } // this.redraw(); //} } } export {TouchEventHandler};