From 1f7588f1ceb72851fe3680df5f86966fd8600689 Mon Sep 17 00:00:00 2001 From: Connor Turland Date: Sun, 17 Mar 2013 02:29:17 -0400 Subject: [PATCH] added ability to use touch to drag nodes, pan, and zoom. fixed label glitch for the most part --- Gemfile | 4 +- Gemfile.lock | 8 --- Gemfile~ | 46 +++++++++++++ .../Jit/graphsettings-event-handlers.js | 64 ++++++++++++++++++- app/assets/javascripts/Jit/graphsettings.js | 46 +++++++++++-- app/assets/javascripts/Jit/jit2.0.0.js | 3 + app/assets/javascripts/Jit/loadgraphs.js | 19 ++++++ .../javascripts/Jit/onCreateLabelHandler.js | 6 +- app/assets/javascripts/application.js | 18 +++++- 9 files changed, 192 insertions(+), 22 deletions(-) create mode 100644 Gemfile~ diff --git a/Gemfile b/Gemfile index cb1ac1c2..1f7c3bd8 100644 --- a/Gemfile +++ b/Gemfile @@ -13,8 +13,8 @@ gem 'formtastic' gem 'json' gem 'rails3-jquery-autocomplete' gem 'best_in_place' -gem 'therubyracer' #optional -gem 'rb-readline' +#gem 'therubyracer' #optional +#gem 'rb-readline' # Gems used only for assets and not required # in production environments by default. diff --git a/Gemfile.lock b/Gemfile.lock index ed4f0c01..cc33f0b6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -60,7 +60,6 @@ GEM railties (>= 3.1.0, < 5.0) thor (~> 0.14) json (1.7.6) - libv8 (3.11.8.13) mail (2.4.4) i18n (>= 0.4.0) mime-types (~> 1.16) @@ -95,10 +94,8 @@ GEM rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) rake (10.0.3) - rb-readline (0.4.2) rdoc (3.12) json (~> 1.4) - ref (1.0.2) sass (3.2.1) sass-rails (3.2.5) railties (~> 3.2.0) @@ -109,9 +106,6 @@ GEM multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - therubyracer (0.11.4) - libv8 (~> 3.11.8.12) - ref thor (0.16.0) tilt (1.3.3) treetop (1.4.12) @@ -139,7 +133,5 @@ DEPENDENCIES pg rails (= 3.2.11) rails3-jquery-autocomplete - rb-readline sass-rails (~> 3.2.3) - therubyracer uglifier (>= 1.0.3) diff --git a/Gemfile~ b/Gemfile~ new file mode 100644 index 00000000..6b2f6e48 --- /dev/null +++ b/Gemfile~ @@ -0,0 +1,46 @@ +source 'https://rubygems.org' + +gem 'rails', '3.2.11' + +# Bundle edge Rails instead: +# gem 'rails', :git => 'git://github.com/rails/rails.git' + +gem 'pg' +gem 'authlogic' +gem 'cancan' +gem 'formula' +gem 'formtastic' +gem 'json' +gem 'rails3-jquery-autocomplete' +gem 'best_in_place' +#gem 'therubyracer' #optional +gem 'rb-readline' + +# Gems used only for assets and not required +# in production environments by default. +group :assets do + gem 'sass-rails', '~> 3.2.3' + gem 'coffee-rails', '~> 3.2.1' + + # See https://github.com/sstephenson/execjs#readme for more supported runtimes + # gem 'therubyracer' + + gem 'uglifier', '>= 1.0.3' +end + +gem 'jquery-rails', '2.1.2' + +# To use ActiveModel has_secure_password +# gem 'bcrypt-ruby', '~> 3.0.0' + +# To use Jbuilder templates for JSON + gem 'jbuilder' + +# Use unicorn as the web server +# gem 'unicorn' + +# Deploy with Capistrano +# gem 'capistrano' + +# To use debugger +# gem 'ruby-debug19', :require => 'ruby-debug' diff --git a/app/assets/javascripts/Jit/graphsettings-event-handlers.js b/app/assets/javascripts/Jit/graphsettings-event-handlers.js index 80136c18..2e40b82c 100644 --- a/app/assets/javascripts/Jit/graphsettings-event-handlers.js +++ b/app/assets/javascripts/Jit/graphsettings-event-handlers.js @@ -160,8 +160,8 @@ function onDragMoveTopicHandler(node, eventInfo, e) { $('#new_synapse').fadeOut('fast'); $('#new_topic').fadeOut('fast'); var pos = eventInfo.getPos(); - // if it's a left click, move the node - if (e.button == 0 && !e.altKey && (e.buttons == 0 || e.buttons == 1 || e.buttons == undefined)) { + // if it's a left click, or a touch, move the node + if ( e.touches || (e.button == 0 && !e.altKey && (e.buttons == 0 || e.buttons == 1 || e.buttons == undefined))) { //if the node dragged isn't already selected, select it var whatToDo = handleSelectionBeforeDragging(node, e); if (whatToDo == 'only-drag-this-one') { @@ -235,3 +235,63 @@ function onDragMoveTopicHandler(node, eventInfo, e) { } } } + +var lastDist = 0; + +function getDistance(p1, p2) { + return Math.sqrt(Math.pow((p2.x - p1.x), 2) + Math.pow((p2.y - p1.y), 2)); +} + +function touchPanZoomHandler(eventInfo, e) { + if (e.touches.length == 1) { + var thispos = touchPos, + currentPos = eventInfo.getPos(), + canvas = Mconsole.canvas, + ox = canvas.translateOffsetX, + oy = canvas.translateOffsetY, + sx = canvas.scaleOffsetX, + sy = canvas.scaleOffsetY; + currentPos.x *= sx; + currentPos.y *= sy; + currentPos.x += ox; + currentPos.y += oy; + //var x = currentPos.x - thispos.x, + // y = currentPos.y - thispos.y; + var x = currentPos.x - thispos.x, + y = currentPos.y - thispos.y; + touchPos = currentPos; + Mconsole.canvas.translate(x * 1/sx, y * 1/sy); + } + else if (e.touches.length == 2) { + var touch1 = e.touches[0]; + var touch2 = e.touches[1]; + + var dist = getDistance({ + x: touch1.clientX, + y: touch1.clientY + }, { + x: touch2.clientX, + y: touch2.clientY + }); + + if(!lastDist) { + lastDist = dist; + } + + var scale = dist / lastDist; + + console.log(scale); + + if (8 >= Mconsole.canvas.scaleOffsetX*scale && Mconsole.canvas.scaleOffsetX*scale >= 1) { + Mconsole.canvas.scale(scale, scale); + } + if (Mconsole.canvas.scaleOffsetX < 0.5) { + Mconsole.canvas.viz.labels.hideLabels(true); + } + else if (Mconsole.canvas.scaleOffsetX > 0.5) { + Mconsole.canvas.viz.labels.hideLabels(false); + } + lastDist = dist; + } + +} \ No newline at end of file diff --git a/app/assets/javascripts/Jit/graphsettings.js b/app/assets/javascripts/Jit/graphsettings.js index 5b5646d8..3ca32af5 100644 --- a/app/assets/javascripts/Jit/graphsettings.js +++ b/app/assets/javascripts/Jit/graphsettings.js @@ -58,7 +58,7 @@ function graphSettings(type, embed) { }, //Update node positions when dragged onDragMove: function (node, eventInfo, e) { - onDragMoveTopicHandler(node, eventInfo, e); + onDragMoveTopicHandler(node, eventInfo, e); }, onDragEnd: function(node, eventInfo, e) { onDragEndTopicHandler(node, eventInfo, e, false); @@ -67,16 +67,52 @@ function graphSettings(type, embed) { onDragCancelHandler(node, eventInfo, e, false); }, //Implement the same handler for touchscreens + onTouchStart: function (node, eventInfo, e) { + //$jit.util.event.stop(e); //stop default touchmove event + //Mconsole.events.onMouseDown(e, null, eventInfo); + Mconsole.events.touched = true; + touchPos = eventInfo.getPos(); + var canvas = Mconsole.canvas, + ox = canvas.translateOffsetX; + oy = canvas.translateOffsetY, + sx = canvas.scaleOffsetX, + sy = canvas.scaleOffsetY; + touchPos.x *= sx; + touchPos.y *= sy; + touchPos.x += ox; + touchPos.y += oy; + + touchDragNode = node; + }, + //Implement the same handler for touchscreens onTouchMove: function (node, eventInfo, e) { - $jit.util.event.stop(e); //stop default touchmove event - this.onDragMove(node, eventInfo, e); + if (touchDragNode) onDragMoveTopicHandler(touchDragNode, eventInfo, e); + else { + touchPanZoomHandler(eventInfo, e); + $('#topic_' + MetamapsModel.showcardInUse + '_label').hide(); + } + }, + //Implement the same handler for touchscreens + onTouchEnd: function (node, eventInfo, e) { + //clicking on a node, or clicking on blank part of canvas? + if (node.nodeFrom) { + selectEdgeOnClickHandler(node, e); + } else if (node && !node.nodeFrom) { + selectNodeOnClickHandler(node, e); + } else { + canvasDoubleClickHandler(eventInfo.getPos(), e); + }//if + }, + //Implement the same handler for touchscreens + onTouchCancel: function (node, eventInfo, e) { + }, //Add also a click handler to nodes onClick: function (node, eventInfo, e) { if (e.target.id != "infovis-canvas") return false; //topic and synapse editing cards - hideCards(); + if (!Mconsole.events.moved) hideCards(); //clicking on a node, or clicking on blank part of canvas? if (node.nodeFrom) { @@ -84,6 +120,8 @@ function graphSettings(type, embed) { } else if (node && !node.nodeFrom) { selectNodeOnClickHandler(node, e); } else { + //topic and synapse editing cards + if (!Mconsole.events.moved) hideCards(); canvasDoubleClickHandler(eventInfo.getPos(), e); }//if } diff --git a/app/assets/javascripts/Jit/jit2.0.0.js b/app/assets/javascripts/Jit/jit2.0.0.js index 7e15717b..0a5fdc9e 100644 --- a/app/assets/javascripts/Jit/jit2.0.0.js +++ b/app/assets/javascripts/Jit/jit2.0.0.js @@ -2591,6 +2591,7 @@ Extras.Classes.Navigation = new Class({ $.event.stop($.event.get(e, win)); var val = this.config.zooming / 1000, ans = 1 + scroll * val; + // START METAMAPS CODE if (ans > 1) { if (5 >= this.canvas.scaleOffsetX) { this.canvas.scale(ans, ans); @@ -2607,6 +2608,8 @@ Extras.Classes.Navigation = new Class({ else if (this.canvas.scaleOffsetX > 0.5) { this.canvas.viz.labels.hideLabels(false); } + // END METAMAPS CODE + // ORIGINAL CODE this.canvas.scale(ans, ans); }, onMouseDown: function(e, win, eventInfo) { diff --git a/app/assets/javascripts/Jit/loadgraphs.js b/app/assets/javascripts/Jit/loadgraphs.js index 2335a4ba..8a1c585b 100644 --- a/app/assets/javascripts/Jit/loadgraphs.js +++ b/app/assets/javascripts/Jit/loadgraphs.js @@ -118,6 +118,25 @@ function initialize(type, loadLater, embed){ else if ( type == "arranged" || type == "chaotic") { Mconsole.animate(chooseAnimate); } + + // prevent touch events on the canvas from default behaviour + $("#infovis-canvas").bind('touchstart', function(event) { + event.preventDefault(); + Mconsole.events.touched = true; + }); + + // prevent touch events on the canvas from default behaviour + $("#infovis-canvas").bind('touchmove', function(event) { + //touchPanZoomHandler(event); + }); + + // prevent touch events on the canvas from default behaviour + $("#infovis-canvas").bind('touchend touchcancel', function(event) { + lastDist = 0; + if (!Mconsole.events.touchMoved && !touchDragNode) hideCurrentCard(); + Mconsole.events.touched = Mconsole.events.touchMoved = false; + touchDragNode = false; + }); }); // end }// if not loadLater diff --git a/app/assets/javascripts/Jit/onCreateLabelHandler.js b/app/assets/javascripts/Jit/onCreateLabelHandler.js index 51a41f93..1b629588 100644 --- a/app/assets/javascripts/Jit/onCreateLabelHandler.js +++ b/app/assets/javascripts/Jit/onCreateLabelHandler.js @@ -290,15 +290,13 @@ function bindCallbacks(showCard, nameContainer, node) { // add some events to the label $(nameContainer).find('.label').click(function(e){ - $('.name').css('display','block'); - $('.name.topic_' + node.id).css('display','none'); + hideCurrentCard(); $('.showcard.topic_' + node.id).fadeIn('fast'); $('.showcard.topic_' + node.id).find('.scroll').mCustomScrollbar("update"); node.setData('dim', 1, 'current'); - - hideCurrentCard(); MetamapsModel.showcardInUse = node.id; Mconsole.plot(); + $('#topic_' + node.id + '_label').hide(); }); nameContainer.onmouseover = function(){ diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 012cbcc2..86984539 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -21,7 +21,7 @@ // other options are 'graph' var viewMode = "list"; -var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, gType, tempNode = null, tempInit = false, tempNode2 = null, metacodeIMGinit = false, findOpen = false, analyzeOpen = false, organizeOpen = false, goRealtime = false, mapid = null, mapperm = false; +var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, gType, tempNode = null, tempInit = false, tempNode2 = null, metacodeIMGinit = false, findOpen = false, analyzeOpen = false, organizeOpen = false, goRealtime = false, mapid = null, mapperm = false, touchPos, touchDragNode; $(document).ready(function() { @@ -69,11 +69,25 @@ var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, height: '0px' }, 300, function() { sliding1 = false; + menuIsOpen = false; }); } },800); } ); + + var menuIsOpen = false; + $("#mainTitle a").bind('touchend', function(evt) { + if (!menuIsOpen) { + menuIsOpen = true; + var listLength = $('.logo .menu li').length * 28; + $('.footer .menu').animate({ + height: listLength + 'px' + }, 300); + evt.preventDefault(); + evt.stopPropogation(); + } + }); addHoverForSettings(); @@ -99,7 +113,7 @@ var labelType, useGradients, nativeTextSupport, animate, json, Mconsole = null, saveLayoutAll(); }); -}); +}); // end document.ready function addHoverForSettings() { // controls the sliding hover of the settings for cards