client/js/renderer/scene.js
changeset 293 fba23fde14ba
parent 286 3ab8c63d26db
child 297 7de2652f7ee8
equal deleted inserted replaced
292:f67047a16084 293:fba23fde14ba
     1 "use strict";
       
     2 
     1 
     3 define(['jquery', 'underscore', 'requtils', 'renderer/miniframe'], function ($, _, requtils, MiniFrame) {
     2 define(['jquery', 'underscore', 'requtils', 'renderer/miniframe'], function ($, _, requtils, MiniFrame) {
     4     
     3     'use strict';
       
     4 
     5     var Utils = requtils.getUtils();
     5     var Utils = requtils.getUtils();
     6     
     6 
     7     /* Scene Begin */
     7     /* Scene Begin */
     8 
     8 
     9     var Scene = function(_renkan) {
     9     var Scene = function(_renkan) {
    10         this.renkan = _renkan;
    10         this.renkan = _renkan;
    11         this.$ = $(".Rk-Render");
    11         this.$ = $(".Rk-Render");
    26         this.selected_target = null;
    26         this.selected_target = null;
    27         this.edge_layer = new paper.Layer();
    27         this.edge_layer = new paper.Layer();
    28         this.node_layer = new paper.Layer();
    28         this.node_layer = new paper.Layer();
    29         this.buttons_layer = new paper.Layer();
    29         this.buttons_layer = new paper.Layer();
    30         this.delete_list = [];
    30         this.delete_list = [];
    31         
    31 
    32         if (_renkan.options.show_minimap) {
    32         if (_renkan.options.show_minimap) {
    33             this.minimap = {
    33             this.minimap = {
    34                     background_layer: new paper.Layer(),
    34                     background_layer: new paper.Layer(),
    35                     edge_layer: new paper.Layer(),
    35                     edge_layer: new paper.Layer(),
    36                     node_layer: new paper.Layer(),
    36                     node_layer: new paper.Layer(),
    43             this.minimap.rectangle = new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]), this.minimap.size.add([4,4]));
    43             this.minimap.rectangle = new paper.Path.Rectangle(this.minimap.topleft.subtract([2,2]), this.minimap.size.add([4,4]));
    44             this.minimap.rectangle.fillColor = _renkan.options.minimap_background_color;
    44             this.minimap.rectangle.fillColor = _renkan.options.minimap_background_color;
    45             this.minimap.rectangle.strokeColor = _renkan.options.minimap_border_color;
    45             this.minimap.rectangle.strokeColor = _renkan.options.minimap_border_color;
    46             this.minimap.rectangle.strokeWidth = 4;
    46             this.minimap.rectangle.strokeWidth = 4;
    47             this.minimap.offset = new paper.Point(this.minimap.size.divide(2));
    47             this.minimap.offset = new paper.Point(this.minimap.size.divide(2));
    48             this.minimap.scale = .1;
    48             this.minimap.scale = 0.1;
    49 
    49 
    50             this.minimap.node_layer.activate();
    50             this.minimap.node_layer.activate();
    51             this.minimap.cliprectangle = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);
    51             this.minimap.cliprectangle = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);
    52             this.minimap.node_group.addChild(this.minimap.cliprectangle);
    52             this.minimap.node_group.addChild(this.minimap.cliprectangle);
    53             this.minimap.node_group.clipped = true;
    53             this.minimap.node_group.clipped = true;
    54             this.minimap.miniframe = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);
    54             this.minimap.miniframe = new paper.Path.Rectangle(this.minimap.topleft, this.minimap.size);
    55             this.minimap.node_group.addChild(this.minimap.miniframe);
    55             this.minimap.node_group.addChild(this.minimap.miniframe);
    56             this.minimap.miniframe.fillColor = '#c0c0ff';
    56             this.minimap.miniframe.fillColor = '#c0c0ff';
    57             this.minimap.miniframe.opacity = .3;
    57             this.minimap.miniframe.opacity = 0.3;
    58             this.minimap.miniframe.strokeColor = '#000080';
    58             this.minimap.miniframe.strokeColor = '#000080';
    59             this.minimap.miniframe.strokeWidth = 3;
    59             this.minimap.miniframe.strokeWidth = 3;
    60             this.minimap.miniframe.__representation = new MiniFrame(this, null);
    60             this.minimap.miniframe.__representation = new MiniFrame(this, null);
    61         }
    61         }
    62 
    62 
    80         ['edit', 'remove', 'link', 'enlarge', 'shrink', 'revert' ].forEach(function(imgname) {
    80         ['edit', 'remove', 'link', 'enlarge', 'shrink', 'revert' ].forEach(function(imgname) {
    81             var img = new Image();
    81             var img = new Image();
    82             img.src = _renkan.options.static_url + 'img/' + imgname + '.png';
    82             img.src = _renkan.options.static_url + 'img/' + imgname + '.png';
    83             _this.icon_cache[imgname] = img;
    83             _this.icon_cache[imgname] = img;
    84         });
    84         });
    85         
    85 
    86         var throttledMouseMove = _.throttle(function(_event, _isTouch) {
    86         var throttledMouseMove = _.throttle(function(_event, _isTouch) {
    87             _this.onMouseMove(_event, _isTouch);
    87             _this.onMouseMove(_event, _isTouch);
    88         }, Utils._MOUSEMOVE_RATE);
    88         }, Utils._MOUSEMOVE_RATE);
    89 
    89 
    90         this.canvas_$.on({
    90         this.canvas_$.on({
   110             },
   110             },
   111             touchstart: function(_event) {
   111             touchstart: function(_event) {
   112                 _event.preventDefault();
   112                 _event.preventDefault();
   113                 var _touches = _event.originalEvent.touches[0];
   113                 var _touches = _event.originalEvent.touches[0];
   114                 if (
   114                 if (
   115                         _renkan.options.allow_double_click
   115                         _renkan.options.allow_double_click &&
   116                         && new Date() - _lastTap < Utils._DOUBLETAP_DELAY
   116                         new Date() - _lastTap < Utils._DOUBLETAP_DELAY &&
   117                         && ( Math.pow(_lastTapX - _touches.pageX, 2) + Math.pow(_lastTapY - _touches.pageY, 2) < Utils._DOUBLETAP_DISTANCE )
   117                         ( Math.pow(_lastTapX - _touches.pageX, 2) + Math.pow(_lastTapY - _touches.pageY, 2) < Utils._DOUBLETAP_DISTANCE )
   118                 ) {
   118                 ) {
   119                     _lastTap = 0;
   119                     _lastTap = 0;
   120                     _this.onDoubleClick(_touches);
   120                     _this.onDoubleClick(_touches);
   121                 } else {
   121                 } else {
   122                     _lastTap = new Date();
   122                     _lastTap = new Date();
   128                 }
   128                 }
   129             },
   129             },
   130             touchmove: function(_event) {
   130             touchmove: function(_event) {
   131                 _event.preventDefault();
   131                 _event.preventDefault();
   132                 _lastTap = 0;
   132                 _lastTap = 0;
   133                 if (_event.originalEvent.touches.length == 1) {
   133                 if (_event.originalEvent.touches.length === 1) {
   134                     _this.onMouseMove(_event.originalEvent.touches[0], true);
   134                     _this.onMouseMove(_event.originalEvent.touches[0], true);
   135                 } else {
   135                 } else {
   136                     if (!_zooming) {
   136                     if (!_zooming) {
   137                         _this.onMouseUp(_event.originalEvent.touches[0], true);
   137                         _this.onMouseUp(_event.originalEvent.touches[0], true);
   138                         _this.click_target = null;
   138                         _this.click_target = null;
   145                     var _newScale = _event.originalEvent.scale * _originalScale,
   145                     var _newScale = _event.originalEvent.scale * _originalScale,
   146                     _scaleRatio = _newScale / _this.scale,
   146                     _scaleRatio = _newScale / _this.scale,
   147                     _newOffset = new paper.Point([
   147                     _newOffset = new paper.Point([
   148                                                   _this.canvas_$.width(),
   148                                                   _this.canvas_$.width(),
   149                                                   _this.canvas_$.height()
   149                                                   _this.canvas_$.height()
   150                                                   ]).multiply( .5 * ( 1 - _scaleRatio ) ).add(_this.offset.multiply( _scaleRatio ));
   150                                                   ]).multiply( 0.5 * ( 1 - _scaleRatio ) ).add(_this.offset.multiply( _scaleRatio ));
   151                     _this.setScale(_newScale, _newOffset);
   151                     _this.setScale(_newScale, _newOffset);
   152                 }
   152                 }
   153             },
   153             },
   154             touchend: function(_event) {
   154             touchend: function(_event) {
   155                 _event.preventDefault();
   155                 _event.preventDefault();
   254         bindClick(".Rk-AddNode-Button", "addNodeBtn");
   254         bindClick(".Rk-AddNode-Button", "addNodeBtn");
   255         bindClick(".Rk-AddEdge-Button", "addEdgeBtn");
   255         bindClick(".Rk-AddEdge-Button", "addEdgeBtn");
   256         bindClick(".Rk-Save-Button", "save");
   256         bindClick(".Rk-Save-Button", "save");
   257         bindClick(".Rk-Open-Button", "open");
   257         bindClick(".Rk-Open-Button", "open");
   258         this.$.find(".Rk-Bookmarklet-Button")
   258         this.$.find(".Rk-Bookmarklet-Button")
   259         .attr("href","javascript:" + Utils._BOOKMARKLET_CODE(_renkan))
   259           /*jshint scripturl:true */
   260         .click(function(){
   260           .attr("href","javascript:" + Utils._BOOKMARKLET_CODE(_renkan))
   261             _this.notif_$
   261           .click(function(){
   262             .text(_renkan.translate("Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan."))
   262               _this.notif_$
   263             .fadeIn()
   263               .text(_renkan.translate("Drag this button to your bookmark bar. When on a third-party website, click it to enable drag-and-drop from the website to Renkan."))
   264             .delay(5000)
   264               .fadeIn()
   265             .fadeOut();
   265               .delay(5000)
   266             return false;
   266               .fadeOut();
   267         });
   267               return false;
       
   268           });
   268         this.$.find(".Rk-TopBar-Button").mouseover(function() {
   269         this.$.find(".Rk-TopBar-Button").mouseover(function() {
   269             $(this).find(".Rk-TopBar-Tooltip").show();
   270             $(this).find(".Rk-TopBar-Tooltip").show();
   270         }).mouseout(function() {
   271         }).mouseout(function() {
   271             $(this).find(".Rk-TopBar-Tooltip").hide();
   272             $(this).find(".Rk-TopBar-Tooltip").hide();
   272         });
   273         });
   336             }
   337             }
   337         });
   338         });
   338 
   339 
   339         if (_renkan.options.size_bug_fix) {
   340         if (_renkan.options.size_bug_fix) {
   340             var _delay = (
   341             var _delay = (
   341                     typeof _renkan.options.size_bug_fix === "number"
   342                     typeof _renkan.options.size_bug_fix === "number" ?
   342                         ? _renkan.options.size_bug_fix
   343                         _renkan.options.size_bug_fix
   343                                 : 500
   344                                 : 500
   344             );
   345             );
   345             window.setTimeout(
   346             window.setTimeout(
   346                     function() {
   347                     function() {
   347                         _this.fixSize(true);
   348                         _this.fixSize(true);
   402                     var rxs = Utils.regexpFromTextOrArray(val);
   403                     var rxs = Utils.regexpFromTextOrArray(val);
   403                     _renkan.project.get("nodes").each(function(n) {
   404                     _renkan.project.get("nodes").each(function(n) {
   404                         if (rxs.test(n.get("title")) || rxs.test(n.get("description"))) {
   405                         if (rxs.test(n.get("title")) || rxs.test(n.get("description"))) {
   405                             _this.getRepresentationByModel(n).highlight(rxs);
   406                             _this.getRepresentationByModel(n).highlight(rxs);
   406                         } else {
   407                         } else {
   407                             _this.getRepresentationByModel(n).unhighlight(); 
   408                             _this.getRepresentationByModel(n).unhighlight();
   408                         }
   409                         }
   409                     });
   410                     });
   410                 }
   411                 }
   411             });
   412             });
   412         }
   413         }
   440 
   441 
   441     };
   442     };
   442 
   443 
   443     _(Scene.prototype).extend({
   444     _(Scene.prototype).extend({
   444         template: _.template(
   445         template: _.template(
   445                 '<% if (options.show_top_bar) { %><div class="Rk-TopBar"><% if (!options.editor_mode) { %><h2 class="Rk-PadTitle"><%- project.get("title") || translate("Untitled project")%></h2>'
   446                 '<% if (options.show_top_bar) { %><div class="Rk-TopBar"><% if (!options.editor_mode) { %><h2 class="Rk-PadTitle"><%- project.get("title") || translate("Untitled project")%></h2>' +
   446                 + '<% } else { %><input type="text" class="Rk-PadTitle" value="<%- project.get("title") || "" %>" placeholder="<%-translate("Untitled project")%>" /><% } %>'
   447                 '<% } else { %><input type="text" class="Rk-PadTitle" value="<%- project.get("title") || "" %>" placeholder="<%-translate("Untitled project")%>" /><% } %>' +
   447                 + '<% if (options.show_user_list) { %><div class="Rk-Users"><div class="Rk-CurrentUser"><div class="Rk-Edit-ColorPicker-Wrapper"><span class="Rk-CurrentUser-Color"><% if (options.user_color_editable) { %><span class="Rk-Edit-ColorTip"></span><% } %></span>'
   448                 '<% if (options.show_user_list) { %><div class="Rk-Users"><div class="Rk-CurrentUser"><div class="Rk-Edit-ColorPicker-Wrapper"><span class="Rk-CurrentUser-Color"><% if (options.user_color_editable) { %><span class="Rk-Edit-ColorTip"></span><% } %></span>' +
   448                 + '<% if (options.user_color_editable) { print(colorPicker) } %></div><span class="Rk-CurrentUser-Name">&lt;unknown user&gt;</span></div><ul class="Rk-UserList"></ul></div><% } %>'
   449                 '<% if (options.user_color_editable) { print(colorPicker) } %></div><span class="Rk-CurrentUser-Name">&lt;unknown user&gt;</span></div><ul class="Rk-UserList"></ul></div><% } %>' +
   449                 + '<% if (options.home_button_url) {%><div class="Rk-TopBar-Separator"></div><a class="Rk-TopBar-Button Rk-Home-Button" href="<%- options.home_button_url %>"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents">'
   450                 '<% if (options.home_button_url) {%><div class="Rk-TopBar-Separator"></div><a class="Rk-TopBar-Button Rk-Home-Button" href="<%- options.home_button_url %>"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents">' +
   450                 + '<%- translate(options.home_button_title) %></div></div></a><% } %>'
   451                 '<%- translate(options.home_button_title) %></div></div></a><% } %>' +
   451                 + '<% if (options.show_fullscreen_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-FullScreen-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Full Screen")%></div></div></div><% } %>'
   452                 '<% if (options.show_fullscreen_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-FullScreen-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Full Screen")%></div></div></div><% } %>' +
   452                 + '<% if (options.editor_mode) { %>'
   453                 '<% if (options.editor_mode) { %>' +
   453                 + '<% if (options.show_addnode_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddNode-Button"><div class="Rk-TopBar-Tooltip">'
   454                 '<% if (options.show_addnode_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddNode-Button"><div class="Rk-TopBar-Tooltip">' +
   454                 + '<div class="Rk-TopBar-Tooltip-Contents"><%-translate("Add Node")%></div></div></div><% } %>'
   455                 '<div class="Rk-TopBar-Tooltip-Contents"><%-translate("Add Node")%></div></div></div><% } %>' +
   455                 + '<% if (options.show_addedge_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddEdge-Button"><div class="Rk-TopBar-Tooltip">'
   456                 '<% if (options.show_addedge_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-AddEdge-Button"><div class="Rk-TopBar-Tooltip">' +
   456                 + '<div class="Rk-TopBar-Tooltip-Contents"><%-translate("Add Edge")%></div></div></div><% } %>'
   457                 '<div class="Rk-TopBar-Tooltip-Contents"><%-translate("Add Edge")%></div></div></div><% } %>' +
   457                 + '<% if (options.show_save_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-Save-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents"> </div></div></div><% } %>'
   458                 '<% if (options.show_save_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-Save-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents"> </div></div></div><% } %>' +
   458                 + '<% if (options.show_open_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-Open-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Open Project")%></div></div></div><% } %>'
   459                 '<% if (options.show_open_button) { %><div class="Rk-TopBar-Separator"></div><div class="Rk-TopBar-Button Rk-Open-Button"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents"><%-translate("Open Project")%></div></div></div><% } %>' +
   459                 + '<% if (options.show_bookmarklet) { %><div class="Rk-TopBar-Separator"></div><a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents">'
   460                 '<% if (options.show_bookmarklet) { %><div class="Rk-TopBar-Separator"></div><a class="Rk-TopBar-Button Rk-Bookmarklet-Button" href="#"><div class="Rk-TopBar-Tooltip"><div class="Rk-TopBar-Tooltip-Contents">' +
   460                 + '<%-translate("Renkan \'Drag-to-Add\' bookmarklet")%></div></div></a><% } %>'
   461                 '<%-translate("Renkan \'Drag-to-Add\' bookmarklet")%></div></div></a><% } %>' +
   461                 + '<div class="Rk-TopBar-Separator"></div><% }; if (options.show_search_field) { %>'
   462                 '<div class="Rk-TopBar-Separator"></div><% }; if (options.show_search_field) { %>' +
   462                 + '<form action="#" class="Rk-GraphSearch-Form"><input type="search" class="Rk-GraphSearch-Field" placeholder="<%- translate("Search in graph") %>" /></form><div class="Rk-TopBar-Separator"></div><% } %></div><% } %>'
   463                 '<form action="#" class="Rk-GraphSearch-Form"><input type="search" class="Rk-GraphSearch-Field" placeholder="<%- translate("Search in graph") %>" /></form><div class="Rk-TopBar-Separator"></div><% } %></div><% } %>' +
   463                 + '<div class="Rk-Editing-Space<% if (!options.show_top_bar) { %> Rk-Editing-Space-Full<% } %>">'
   464                 '<div class="Rk-Editing-Space<% if (!options.show_top_bar) { %> Rk-Editing-Space-Full<% } %>">' +
   464                 + '<div class="Rk-Labels"></div><canvas class="Rk-Canvas" resize></canvas><div class="Rk-Notifications"></div><div class="Rk-Editor">'
   465                 '<div class="Rk-Labels"></div><canvas class="Rk-Canvas" resize></canvas><div class="Rk-Notifications"></div><div class="Rk-Editor">' +
   465                 + '<% if (options.show_bins) { %><div class="Rk-Fold-Bins">&laquo;</div><% } %>'
   466                 '<% if (options.show_bins) { %><div class="Rk-Fold-Bins">&laquo;</div><% } %>' +
   466                 + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%-translate("Zoom In")%>"></div><div class="Rk-ZoomFit" title="<%-translate("Zoom Fit")%>"></div><div class="Rk-ZoomOut" title="<%-translate("Zoom Out")%>"></div>'
   467                 '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%-translate("Zoom In")%>"></div><div class="Rk-ZoomFit" title="<%-translate("Zoom Fit")%>"></div><div class="Rk-ZoomOut" title="<%-translate("Zoom Out")%>"></div>' +
   467                 + '<% if (options.editor_mode) { %><div class="Rk-ZoomSave" title="<%-translate("Zoom Save")%>"></div><% } %>'
   468                 '<% if (options.editor_mode) { %><div class="Rk-ZoomSave" title="<%-translate("Zoom Save")%>"></div><% } %>' +
   468                 + '<% if (options.editor_mode || !isNaN(parseInt(options.default_view))) { %><div class="Rk-ZoomSetSaved" title="<%-translate("View saved zoom")%>"></div><% } %></div>'
   469                 '<% if (options.editor_mode || !isNaN(parseInt(options.default_view))) { %><div class="Rk-ZoomSetSaved" title="<%-translate("View saved zoom")%>"></div><% } %></div>' +
   469                 + '</div></div>'
   470                 '</div></div>'
   470         ),
   471         ),
   471         fixSize: function(_autoscale) {
   472         fixSize: function(_autoscale) {
   472             var w = this.$.width(),
   473             var w = this.$.width(),
   473             h = this.$.height();
   474             h = this.$.height();
   474             if (this.renkan.options.show_top_bar) {
   475             if (this.renkan.options.show_top_bar) {
   506             _enddy = Math.cos(_endRads),
   507             _enddy = Math.cos(_endRads),
   507             _endXIn = Math.cos(_endRads) * _inR - _padding * _enddx,
   508             _endXIn = Math.cos(_endRads) * _inR - _padding * _enddx,
   508             _endYIn = Math.sin(_endRads) * _inR - _padding * _enddy,
   509             _endYIn = Math.sin(_endRads) * _inR - _padding * _enddy,
   509             _endXOut = Math.cos(_endRads) * _outR - _padding * _enddx,
   510             _endXOut = Math.cos(_endRads) * _outR - _padding * _enddx,
   510             _endYOut = Math.sin(_endRads) * _outR - _padding * _enddy,
   511             _endYOut = Math.sin(_endRads) * _outR - _padding * _enddy,
   511             _centerR = (_inR + _outR)/2,
   512             _centerR = (_inR + _outR) / 2,
   512             _centerRads = (_startRads + _endRads) / 2,
   513             _centerRads = (_startRads + _endRads) / 2,
   513             _centerX = Math.cos(_centerRads) * _centerR,
   514             _centerX = Math.cos(_centerRads) * _centerR,
   514             _centerY = Math.sin(_centerRads) * _centerR,
   515             _centerY = Math.sin(_centerRads) * _centerR,
   515             _centerXIn = Math.cos(_centerRads) * _inR,
   516             _centerXIn = Math.cos(_centerRads) * _inR,
   516             _centerXOut = Math.cos(_centerRads) * _outR,
   517             _centerXOut = Math.cos(_centerRads) * _outR,
   523             _path.add([_startXIn, _startYIn]);
   524             _path.add([_startXIn, _startYIn]);
   524             _path.arcTo([_centerXIn, _centerYIn], [_endXIn, _endYIn]);
   525             _path.arcTo([_centerXIn, _centerYIn], [_endXIn, _endYIn]);
   525             _path.lineTo([_endXOut,  _endYOut]);
   526             _path.lineTo([_endXOut,  _endYOut]);
   526             _path.arcTo([_centerXOut, _centerYOut], [_startXOut, _startYOut]);
   527             _path.arcTo([_centerXOut, _centerYOut], [_startXOut, _startYOut]);
   527             _path.fillColor = _options.buttons_background;
   528             _path.fillColor = _options.buttons_background;
   528             _path.opacity = .5;
   529             _path.opacity = 0.5;
   529             _path.closed = true;
   530             _path.closed = true;
   530             _path.__representation = _repr;
   531             _path.__representation = _repr;
   531             var _text = new paper.PointText(_textX,_textY);
   532             var _text = new paper.PointText(_textX,_textY);
   532             _text.characterStyle = {
   533             _text.characterStyle = {
   533                     fontSize: _options.buttons_label_font_size,
   534                     fontSize: _options.buttons_label_font_size,
   566                         _visible = false;
   567                         _visible = false;
   567                         _grp.visible = false;
   568                         _grp.visible = false;
   568                         _grp.position = _restPos;
   569                         _grp.position = _restPos;
   569                     },
   570                     },
   570                     select: function() {
   571                     select: function() {
   571                         _path.opacity = .8;
   572                         _path.opacity = 0.8;
   572                         _text.visible = true;
   573                         _text.visible = true;
   573                     },
   574                     },
   574                     unselect: function() {
   575                     unselect: function() {
   575                         _path.opacity = .5;
   576                         _path.opacity = 0.5;
   576                         _text.visible = false;
   577                         _text.visible = false;
   577                     },
   578                     },
   578                     destroy: function() {
   579                     destroy: function() {
   579                         _grp.remove();
   580                         _grp.remove();
   580                     }
   581                     }
   593 
   594 
   594             return _res;
   595             return _res;
   595         },
   596         },
   596         addToBundles: function(_edgeRepr) {
   597         addToBundles: function(_edgeRepr) {
   597             var _bundle = _(this.bundles).find(function(_bundle) {
   598             var _bundle = _(this.bundles).find(function(_bundle) {
   598                 return ( 
   599                 return (
   599                         ( _bundle.from === _edgeRepr.from_representation && _bundle.to === _edgeRepr.to_representation )
   600                         ( _bundle.from === _edgeRepr.from_representation && _bundle.to === _edgeRepr.to_representation ) ||
   600                         || ( _bundle.from === _edgeRepr.to_representation && _bundle.to === _edgeRepr.from_representation )
   601                         ( _bundle.from === _edgeRepr.to_representation && _bundle.to === _edgeRepr.from_representation )
   601                 );
   602                 );
   602             });
   603             });
   603             if (typeof _bundle !== "undefined") {
   604             if (typeof _bundle !== "undefined") {
   604                 _bundle.edges.push(_edgeRepr);
   605                 _bundle.edges.push(_edgeRepr);
   605             } else {
   606             } else {
   681                 _minx = Math.min.apply(Math, _xx),
   682                 _minx = Math.min.apply(Math, _xx),
   682                 _miny = Math.min.apply(Math, _yy),
   683                 _miny = Math.min.apply(Math, _yy),
   683                 _maxx = Math.max.apply(Math, _xx),
   684                 _maxx = Math.max.apply(Math, _xx),
   684                 _maxy = Math.max.apply(Math, _yy);
   685                 _maxy = Math.max.apply(Math, _yy);
   685                 var _scale = Math.min(
   686                 var _scale = Math.min(
   686                         this.scale * .8 * this.renkan.options.minimap_width / paper.view.bounds.width,
   687                         this.scale * 0.8 * this.renkan.options.minimap_width / paper.view.bounds.width,
   687                         this.scale * .8 * this.renkan.options.minimap_height / paper.view.bounds.height,
   688                         this.scale * 0.8 * this.renkan.options.minimap_height / paper.view.bounds.height,
   688                         ( this.renkan.options.minimap_width - 2 * this.renkan.options.minimap_padding ) / (_maxx - _minx),
   689                         ( this.renkan.options.minimap_width - 2 * this.renkan.options.minimap_padding ) / (_maxx - _minx),
   689                         ( this.renkan.options.minimap_height - 2 * this.renkan.options.minimap_padding ) / (_maxy - _miny)
   690                         ( this.renkan.options.minimap_height - 2 * this.renkan.options.minimap_padding ) / (_maxy - _miny)
   690                 );
   691                 );
   691                 this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale));
   692                 this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale));
   692                 this.minimap.scale = _scale;
   693                 this.minimap.scale = _scale;
   693             }
   694             }
   694             if (nodes.length === 1) {
   695             if (nodes.length === 1) {
   695                 this.minimap.scale = .1;
   696                 this.minimap.scale = 0.1;
   696                 this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y]).multiply(this.minimap.scale));
   697                 this.minimap.offset = this.minimap.size.divide(2).subtract(new paper.Point([nodes.at(0).get("position").x, nodes.at(0).get("position").y]).multiply(this.minimap.scale));
   697             }
   698             }
   698             this.redraw();
   699             this.redraw();
   699         },
   700         },
   700         toPaperCoords: function(_point) {
   701         toPaperCoords: function(_point) {
   705         },
   706         },
   706         toModelCoords: function(_point) {
   707         toModelCoords: function(_point) {
   707             return _point.subtract(this.offset).divide(this.scale);
   708             return _point.subtract(this.offset).divide(this.scale);
   708         },
   709         },
   709         addRepresentation: function(_type, _model) {
   710         addRepresentation: function(_type, _model) {
   710             var r = requtils.getRenderer()[_type];
   711             var RendererType = requtils.getRenderer()[_type];
   711             var _repr = new r(this, _model);
   712             var _repr = new RendererType(this, _model);
   712             this.representations.push(_repr);
   713             this.representations.push(_repr);
   713             return _repr;
   714             return _repr;
   714         },
   715         },
   715         addRepresentations: function(_type, _collection) {
   716         addRepresentations: function(_type, _collection) {
   716             var _this = this;
   717             var _this = this;
   779         },
   780         },
   780         removeRepresentation: function(_representation) {
   781         removeRepresentation: function(_representation) {
   781             _representation.destroy();
   782             _representation.destroy();
   782             this.representations = _(this.representations).reject(
   783             this.representations = _(this.representations).reject(
   783                     function(_repr) {
   784                     function(_repr) {
   784                         return _repr == _representation;
   785                         return _repr === _representation;
   785                     }
   786                     }
   786             );
   787             );
   787         },
   788         },
   788         getRepresentationByModel: function(_model) {
   789         getRepresentationByModel: function(_model) {
   789             if (!_model) {
   790             if (!_model) {
   793                 return _repr.model === _model;
   794                 return _repr.model === _model;
   794             });
   795             });
   795         },
   796         },
   796         removeRepresentationsOfType: function(_type) {
   797         removeRepresentationsOfType: function(_type) {
   797             var _representations = _(this.representations).filter(function(_repr) {
   798             var _representations = _(this.representations).filter(function(_repr) {
   798                 return _repr.type == _type;
   799                 return _repr.type === _type;
   799             }),
   800             }),
   800             _this = this;
   801             _this = this;
   801             _(_representations).each(function(_repr) {
   802             _(_representations).each(function(_repr) {
   802                 _this.removeRepresentation(_repr);
   803                 _this.removeRepresentation(_repr);
   803             });
   804             });
   988             }
   989             }
   989             paper.view.draw();
   990             paper.view.draw();
   990         },
   991         },
   991         defaultDropHandler: function(_data) {
   992         defaultDropHandler: function(_data) {
   992             var newNode = {};
   993             var newNode = {};
       
   994             var snippet = "";
   993             switch(_data["text/x-iri-specific-site"]) {
   995             switch(_data["text/x-iri-specific-site"]) {
   994                 case "twitter":
   996                 case "twitter":
   995                     var snippet = $('<div>').html(_data["text/x-iri-selected-html"]),
   997                     snippet = $('<div>').html(_data["text/x-iri-selected-html"]);
   996                     tweetdiv = snippet.find(".tweet");
   998                     var tweetdiv = snippet.find(".tweet");
   997                     newNode.title = this.renkan.translate("Tweet by ") + tweetdiv.attr("data-name");
   999                     newNode.title = this.renkan.translate("Tweet by ") + tweetdiv.attr("data-name");
   998                     newNode.uri = "http://twitter.com/" + tweetdiv.attr("data-screen-name") + "/status/" + tweetdiv.attr("data-tweet-id");
  1000                     newNode.uri = "http://twitter.com/" + tweetdiv.attr("data-screen-name") + "/status/" + tweetdiv.attr("data-tweet-id");
   999                     newNode.image = tweetdiv.find(".avatar").attr("src");
  1001                     newNode.image = tweetdiv.find(".avatar").attr("src");
  1000                     newNode.description = tweetdiv.find(".js-tweet-text:first").text();
  1002                     newNode.description = tweetdiv.find(".js-tweet-text:first").text();
  1001                     break;
  1003                     break;
  1002                 case "google":
  1004                 case "google":
  1003                     var snippet = $('<div>').html(_data["text/x-iri-selected-html"]);
  1005                     snippet = $('<div>').html(_data["text/x-iri-selected-html"]);
  1004                     newNode.title = snippet.find("h3:first").text().trim();
  1006                     newNode.title = snippet.find("h3:first").text().trim();
  1005                     newNode.uri = snippet.find("h3 a").attr("href");
  1007                     newNode.uri = snippet.find("h3 a").attr("href");
  1006                     newNode.description = snippet.find(".st:first").text().trim();
  1008                     newNode.description = snippet.find(".st:first").text().trim();
  1007                     break;
  1009                     break;
  1008                 case undefined:
       
  1009                 default:
  1010                 default:
  1010                     if (_data["text/x-iri-source-uri"]) {
  1011                     if (_data["text/x-iri-source-uri"]) {
  1011                         newNode.uri = _data["text/x-iri-source-uri"];
  1012                         newNode.uri = _data["text/x-iri-source-uri"];
  1012                     }
  1013                     }
  1013             }
  1014             }
  1014             if (_data["text/plain"] || _data["text/x-iri-selected-text"]) {
  1015             if (_data["text/plain"] || _data["text/x-iri-selected-text"]) {
  1015                 newNode.description = (_data["text/plain"] || _data["text/x-iri-selected-text"]).replace(/[\s\n]+/gm,' ').trim();
  1016                 newNode.description = (_data["text/plain"] || _data["text/x-iri-selected-text"]).replace(/[\s\n]+/gm,' ').trim();
  1016             }
  1017             }
  1017             if (_data["text/html"] || _data["text/x-iri-selected-html"]) {
  1018             if (_data["text/html"] || _data["text/x-iri-selected-html"]) {
  1018                 var snippet = $('<div>').html(_data["text/html"] || _data["text/x-iri-selected-html"]);
  1019                 snippet = $('<div>').html(_data["text/html"] || _data["text/x-iri-selected-html"]);
  1019                 var _svgimgs = snippet.find("image");
  1020                 var _svgimgs = snippet.find("image");
  1020                 if (_svgimgs.length) {
  1021                 if (_svgimgs.length) {
  1021                     newNode.image = _svgimgs.attr("xlink:href");
  1022                     newNode.image = _svgimgs.attr("xlink:href");
  1022                 }
  1023                 }
  1023                 var _svgpaths = snippet.find("path");
  1024                 var _svgpaths = snippet.find("path");
  1046             }
  1047             }
  1047             if (_data["text/x-iri-source-title"] && !newNode.title) {
  1048             if (_data["text/x-iri-source-title"] && !newNode.title) {
  1048                 newNode.title = _data["text/x-iri-source-title"];
  1049                 newNode.title = _data["text/x-iri-source-title"];
  1049             }
  1050             }
  1050             if (_data["text/html"] || _data["text/x-iri-selected-html"]) {
  1051             if (_data["text/html"] || _data["text/x-iri-selected-html"]) {
  1051                 var snippet = $('<div>').html(_data["text/html"] || _data["text/x-iri-selected-html"]);
  1052                 snippet = $('<div>').html(_data["text/html"] || _data["text/x-iri-selected-html"]);
  1052                 newNode.image = snippet.find("[data-image]").attr("data-image") || newNode.image;
  1053                 newNode.image = snippet.find("[data-image]").attr("data-image") || newNode.image;
  1053                 newNode.uri = snippet.find("[data-uri]").attr("data-uri") || newNode.uri;
  1054                 newNode.uri = snippet.find("[data-uri]").attr("data-uri") || newNode.uri;
  1054                 newNode.title = snippet.find("[data-title]").attr("data-title") || newNode.title;
  1055                 newNode.title = snippet.find("[data-title]").attr("data-title") || newNode.title;
  1055                 newNode.description = snippet.find("[data-description]").attr("data-description") || newNode.description;
  1056                 newNode.description = snippet.find("[data-description]").attr("data-description") || newNode.description;
  1056                 newNode.clipPath = snippet.find("[data-clip-path]").attr("data-clip-path") || newNode.clipPath;
  1057                 newNode.clipPath = snippet.find("[data-clip-path]").attr("data-clip-path") || newNode.clipPath;
  1067                 }
  1068                 }
  1068                 if (newNode[f] === "none" || newNode[f] === "null") {
  1069                 if (newNode[f] === "none" || newNode[f] === "null") {
  1069                     newNode[f] = undefined;
  1070                     newNode[f] = undefined;
  1070                 }
  1071                 }
  1071             }
  1072             }
  1072             
  1073 
  1073             if(typeof this.renkan.options.drop_enhancer === "function"){
  1074             if(typeof this.renkan.options.drop_enhancer === "function"){
  1074                 newNode = this.renkan.options.drop_enhancer(newNode, _data);
  1075                 newNode = this.renkan.options.drop_enhancer(newNode, _data);
  1075             }
  1076             }
  1076             
  1077 
  1077             return newNode;
  1078             return newNode;
  1078 
  1079 
  1079         },
  1080         },
  1080         dropData: function(_data, _event) {
  1081         dropData: function(_data, _event) {
  1081             if (!this.isEditable()) {
  1082             if (!this.isEditable()) {
  1086                     var jsondata = JSON.parse(_data["text/json"] || _data["application/json"]);
  1087                     var jsondata = JSON.parse(_data["text/json"] || _data["application/json"]);
  1087                     _(_data).extend(jsondata);
  1088                     _(_data).extend(jsondata);
  1088                 }
  1089                 }
  1089                 catch(e) {}
  1090                 catch(e) {}
  1090             }
  1091             }
  1091             
  1092 
  1092             var newNode = (typeof this.renkan.options.drop_handler === "undefined")?this.defaultDropHandler(_data):this.renkan.options.drop_handler(_data);
  1093             var newNode = (typeof this.renkan.options.drop_handler === "undefined")?this.defaultDropHandler(_data):this.renkan.options.drop_handler(_data);
  1093             
  1094 
  1094             var _off = this.canvas_$.offset(),
  1095             var _off = this.canvas_$.offset(),
  1095             _point = new paper.Point([
  1096             _point = new paper.Point([
  1096                                       _event.pageX - _off.left,
  1097                                       _event.pageX - _off.left,
  1097                                       _event.pageY - _off.top
  1098                                       _event.pageY - _off.top
  1098                                       ]),
  1099                                       ]),
  1117                 _repr.openEditor();
  1118                 _repr.openEditor();
  1118             }
  1119             }
  1119         },
  1120         },
  1120         fullScreen: function() {
  1121         fullScreen: function() {
  1121             var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen,
  1122             var _isFull = document.fullScreen || document.mozFullScreen || document.webkitIsFullScreen,
  1122             _el = this.renkan.$[0],
  1123               _el = this.renkan.$[0],
  1123             _requestMethods = ["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"],
  1124               _requestMethods = ["requestFullScreen","mozRequestFullScreen","webkitRequestFullScreen"],
  1124             _cancelMethods = ["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"];
  1125               _cancelMethods = ["cancelFullScreen","mozCancelFullScreen","webkitCancelFullScreen"],
       
  1126               i;
  1125             if (_isFull) {
  1127             if (_isFull) {
  1126                 for (var i = 0; i < _cancelMethods.length; i++) {
  1128                 for (i = 0; i < _cancelMethods.length; i++) {
  1127                     if (typeof document[_cancelMethods[i]] === "function") {
  1129                     if (typeof document[_cancelMethods[i]] === "function") {
  1128                         document[_cancelMethods[i]]();
  1130                         document[_cancelMethods[i]]();
  1129                         break;
  1131                         break;
  1130                     }
  1132                     }
  1131                 }
  1133                 }
  1132             } else {
  1134             } else {
  1133                 for (var i = 0; i < _requestMethods.length; i++) {
  1135                 for (i = 0; i < _requestMethods.length; i++) {
  1134                     if (typeof _el[_requestMethods[i]] === "function") {
  1136                     if (typeof _el[_requestMethods[i]] === "function") {
  1135                         _el[_requestMethods[i]]();
  1137                         _el[_requestMethods[i]]();
  1136                         break;
  1138                         break;
  1137                     }
  1139                     }
  1138                 }
  1140                 }
  1141         zoomOut: function() {
  1143         zoomOut: function() {
  1142             var _newScale = this.scale * Math.SQRT1_2,
  1144             var _newScale = this.scale * Math.SQRT1_2,
  1143             _offset = new paper.Point([
  1145             _offset = new paper.Point([
  1144                                        this.canvas_$.width(),
  1146                                        this.canvas_$.width(),
  1145                                        this.canvas_$.height()
  1147                                        this.canvas_$.height()
  1146                                        ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(this.offset.multiply( Math.SQRT1_2 ));
  1148                                        ]).multiply( 0.5 * ( 1 - Math.SQRT1_2 ) ).add(this.offset.multiply( Math.SQRT1_2 ));
  1147             this.setScale( _newScale, _offset );
  1149             this.setScale( _newScale, _offset );
  1148         },
  1150         },
  1149         zoomIn: function() {
  1151         zoomIn: function() {
  1150             var _newScale = this.scale * Math.SQRT2,
  1152             var _newScale = this.scale * Math.SQRT2,
  1151             _offset = new paper.Point([
  1153             _offset = new paper.Point([
  1152                                        this.canvas_$.width(),
  1154                                        this.canvas_$.width(),
  1153                                        this.canvas_$.height()
  1155                                        this.canvas_$.height()
  1154                                        ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(this.offset.multiply( Math.SQRT2 ));
  1156                                        ]).multiply( 0.5 * ( 1 - Math.SQRT2 ) ).add(this.offset.multiply( Math.SQRT2 ));
  1155             this.setScale( _newScale, _offset );
  1157             this.setScale( _newScale, _offset );
  1156         },
  1158         },
  1157         addNodeBtn: function() {
  1159         addNodeBtn: function() {
  1158             if (this.click_mode === Utils._CLICKMODE_ADDNODE) {
  1160             if (this.click_mode === Utils._CLICKMODE_ADDNODE) {
  1159                 this.click_mode = false;
  1161                 this.click_mode = false;
  1175             return false;
  1177             return false;
  1176         },
  1178         },
  1177         foldBins: function() {
  1179         foldBins: function() {
  1178             var foldBinsButton = this.$.find(".Rk-Fold-Bins"),
  1180             var foldBinsButton = this.$.find(".Rk-Fold-Bins"),
  1179             bins = this.renkan.$.find(".Rk-Bins");
  1181             bins = this.renkan.$.find(".Rk-Bins");
       
  1182             var _this = this;
  1180             if (bins.offset().left < 0) {
  1183             if (bins.offset().left < 0) {
  1181                 bins.animate({left: 0},250);
  1184                 bins.animate({left: 0},250);
  1182                 var _this = this;
       
  1183                 this.$.animate({left: 300},250,function() {
  1185                 this.$.animate({left: 300},250,function() {
  1184                     var w = _this.$.width();
  1186                     var w = _this.$.width();
  1185                     paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);
  1187                     paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);
  1186                 });
  1188                 });
  1187                 foldBinsButton.html("&laquo;");
  1189                 foldBinsButton.html("&laquo;");
  1188             } else {
  1190             } else {
  1189                 bins.animate({left: -300},250);
  1191                 bins.animate({left: -300},250);
  1190                 var _this = this;
       
  1191                 this.$.animate({left: 0},250,function() {
  1192                 this.$.animate({left: 0},250,function() {
  1192                     var w = _this.$.width();
  1193                     var w = _this.$.width();
  1193                     paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);
  1194                     paper.view.viewSize = new paper.Size([w, _this.canvas_$.height()]);
  1194                 });
  1195                 });
  1195                 foldBinsButton.html("&raquo;");
  1196                 foldBinsButton.html("&raquo;");
  1196             }
  1197             }
  1197         },
  1198         },
  1198         save: function() { },
  1199         save: function() { },
  1199         open: function() { }
  1200         open: function() { }
  1200     });
  1201     });
  1201     
  1202 
  1202     /* Scene End */
  1203     /* Scene End */
  1203     
  1204 
  1204     return Scene;
  1205     return Scene;
  1205     
  1206 
  1206 });
  1207 });