client/js/paper-renderer.js
changeset 4 f5297dde9053
parent 3 7722ec70c01b
child 5 67085e6281e5
equal deleted inserted replaced
3:7722ec70c01b 4:f5297dde9053
     2 
     2 
     3 Rkns.Renderers.Paper__Controllers = {}
     3 Rkns.Renderers.Paper__Controllers = {}
     4 
     4 
     5 Rkns.Renderers.Paper__Controllers._Base = function(_renderer, _element) {
     5 Rkns.Renderers.Paper__Controllers._Base = function(_renderer, _element) {
     6     if (typeof _renderer !== "undefined") {
     6     if (typeof _renderer !== "undefined") {
       
     7         this.id = Rkns.Utils.getUID('controller');
     7         this._renderer = _renderer;
     8         this._renderer = _renderer;
     8         this._element = _element;
     9         this._element = _element;
     9         this._element.__controller = this;
    10         this._element.__controller = this;
    10     }
    11     }
    11 }
    12 }
    12 
    13 
       
    14 Rkns.Renderers.Paper__Controllers._Base.prototype.select = function() {}
       
    15 
       
    16 Rkns.Renderers.Paper__Controllers._Base.prototype.unselect = function() {}
       
    17 
    13 Rkns.Renderers.Paper__Controllers.Node = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
    18 Rkns.Renderers.Paper__Controllers.Node = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
    14 
    19 
    15 Rkns.Renderers.Paper__Controllers.Node.prototype._init = function() {
    20 Rkns.Renderers.Paper__Controllers.Node.prototype._init = function() {
    16     this._renderer.node_layer.activate();
    21     this._renderer.node_layer.activate();
    17     this.type = "node";
    22     this.type = "node";
    18     this.node_circle = new paper.Path.Circle([0, 0], 20);
    23     this.node_circle = new paper.Path.Circle([0, 0], Rkns._NODE_RADIUS);
    19     this.node_circle.fillColor = '#ffffff';
    24     this.node_circle.fillColor = '#ffffff';
    20     this.node_circle.__controller = this;
    25     this.node_circle.__controller = this;
    21     this.node_text = new paper.PointText([0,0]);
    26     this.node_text = new paper.PointText([0,0]);
    22     this.node_text.characterStyle = {
    27     this.node_text.characterStyle = {
    23         fontSize: 14,
    28         fontSize: Rkns._NODE_FONT_SIZE,
    24         fillColor: 'black'
    29         fillColor: 'black'
    25     };
    30     };
    26     this.node_text.paragraphStyle.justification = 'center';
    31     this.node_text.paragraphStyle.justification = 'center';
    27     this.node_text.__controller = this;
    32     this.node_text.__controller = this;
    28     this.redraw();
       
    29 }
    33 }
    30 
    34 
    31 Rkns.Renderers.Paper__Controllers.Node.prototype.redraw = function() {
    35 Rkns.Renderers.Paper__Controllers.Node.prototype.redraw = function() {
    32     this.node_model_coords = new paper.Point(this._element.position);
    36     this.node_model_coords = new paper.Point(this._element.position);
    33     this.node_paper_coords = this._renderer.toPaperCoords(this.node_model_coords);
    37     this.node_paper_coords = this._renderer.toPaperCoords(this.node_model_coords);
    34     this.node_circle.position = this.node_paper_coords;
    38     this.node_circle.position = this.node_paper_coords;
    35     this.node_text.content = this._element.title;
    39     this.node_text.content = this._element.title;
    36     this.node_text.position = this.node_paper_coords.add([0, 35]);
    40     this.node_text.position = this.node_paper_coords.add([0, 2 * Rkns._NODE_RADIUS]);
    37     this.node_circle.strokeColor = this._element.created_by.color;
    41     this.node_circle.strokeColor = this._element.created_by.color;
    38 }
    42 }
    39 
    43 
    40 Rkns.Renderers.Paper__Controllers.Node.prototype.paperShift = function(_delta) {
    44 Rkns.Renderers.Paper__Controllers.Node.prototype.paperShift = function(_delta) {
    41     this._element.setPosition(Rkns._FROM_GRAPHICS, this._renderer.toModelCoords(this.node_paper_coords.add(_delta)));
    45     this._element.setPosition(this._renderer.toModelCoords(this.node_paper_coords.add(_delta)));
       
    46     this._renderer._project.serializer.save();
    42     this._renderer.redraw();
    47     this._renderer.redraw();
    43 }
    48 }
    44 
    49 
       
    50 Rkns.Renderers.Paper__Controllers.Node.prototype.select = function(_delta) {
       
    51     this.node_circle.strokeWidth = 3;
       
    52 }
       
    53 
       
    54 Rkns.Renderers.Paper__Controllers.Node.prototype.unselect = function(_delta) {
       
    55     this.node_circle.strokeWidth = 1;
       
    56 }
       
    57 
    45 /* */
    58 /* */
    46 
    59 
    47 Rkns.Renderers.Paper__Controllers.Edge = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
    60 Rkns.Renderers.Paper__Controllers.Edge = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
    48 
       
    49 
    61 
    50 Rkns.Renderers.Paper__Controllers.Edge.prototype._init = function() {
    62 Rkns.Renderers.Paper__Controllers.Edge.prototype._init = function() {
    51     this._renderer.edge_layer.activate();
    63     this._renderer.edge_layer.activate();
    52     this.type = "edge";
    64     this.type = "edge";
    53     this.from_node_controller = this._element.from.__controller;
    65     this.from_node_controller = this._element.from.__controller;
    54     this.to_node_controller = this._element.to.__controller;
    66     this.to_node_controller = this._element.to.__controller;
    55     this.edge_line = new paper.Path();
    67     this.edge_line = new paper.Path();
    56     this.edge_line.add([0,0],[0,0]);
    68     this.edge_line.add([0,0],[0,0]);
    57     this.edge_line.__controller = this;
    69     this.edge_line.__controller = this;
       
    70     this.edge_arrow = new paper.Path();
       
    71     this.edge_arrow.add([0,0],[Rkns._ARROW_LENGTH,Rkns._ARROW_WIDTH / 2],[0,Rkns._ARROW_WIDTH]);
       
    72     this.edge_arrow.__controller = this;
    58     this.edge_text = new paper.PointText();
    73     this.edge_text = new paper.PointText();
    59     this.edge_text.characterStyle = {
    74     this.edge_text.characterStyle = {
    60         fontSize: 10,
    75         fontSize: Rkns._EDGE_FONT_SIZE,
    61         fillColor: 'black'
    76         fillColor: 'black'
    62     };
    77     };
    63     this.edge_text.paragraphStyle.justification = 'center';
    78     this.edge_text.paragraphStyle.justification = 'center';
    64     this.edge_text.__controller = this;
    79     this.edge_text.__controller = this;
    65     this.edge_angle = 0;
    80     this.edge_text_angle = 0;
       
    81     this.edge_arrow_angle = 0;
    66 }
    82 }
    67 
    83 
    68 Rkns.Renderers.Paper__Controllers.Edge.prototype.redraw = function() {
    84 Rkns.Renderers.Paper__Controllers.Edge.prototype.redraw = function() {
    69     this.edge_line.strokeColor = this._element.created_by.color;
       
    70     var _p0 = this.from_node_controller.node_paper_coords,
    85     var _p0 = this.from_node_controller.node_paper_coords,
    71         _p1 = this.to_node_controller.node_paper_coords,
    86         _p1 = this.to_node_controller.node_paper_coords,
    72         _a = _p1.subtract(_p0).angle;
    87         _a = _p1.subtract(_p0).angle,
       
    88         _center = _p0.add(_p1).divide(2),
       
    89         _color = this._element.created_by.color;
       
    90     this.edge_line.strokeColor = _color;
    73     this.edge_line.segments[0].point = _p0;
    91     this.edge_line.segments[0].point = _p0;
    74     this.edge_line.segments[1].point = _p1;
    92     this.edge_line.segments[1].point = _p1;
    75     this.edge_text.content = this._element.title;
    93     this.edge_arrow.rotate(_a - this.edge_arrow_angle);
    76     this.edge_text.position = _p0.add(_p1).divide(2);
    94     this.edge_arrow.fillColor = _color;
       
    95     this.edge_arrow.position = _center;
       
    96     this.edge_arrow_angle = _a;
    77     if (_a > 90) {
    97     if (_a > 90) {
    78         _a -= 180;
    98         _a -= 180;
    79     }
    99     }
    80     if (_a < -90) {
   100     if (_a < -90) {
    81         _a += 180;
   101         _a += 180;
    82     }
   102     }
    83     this.edge_text.rotate(_a - this.edge_angle);
   103     this.edge_text.rotate(_a - this.edge_text_angle);
    84     this.edge_angle = _a;
   104     this.edge_text.content = this._element.title;
       
   105     this.edge_text.position = _center;
       
   106     this.edge_text_angle = _a;
       
   107 }
       
   108 
       
   109 Rkns.Renderers.Paper__Controllers.Edge.prototype.select = function(_delta) {
       
   110     this.edge_line.strokeWidth = 3;
       
   111 }
       
   112 
       
   113 Rkns.Renderers.Paper__Controllers.Edge.prototype.unselect = function(_delta) {
       
   114     this.edge_line.strokeWidth = 1;
    85 }
   115 }
    86 
   116 
    87 Rkns.Renderers.Paper__Controllers.Edge.prototype.paperShift = function(_delta) {
   117 Rkns.Renderers.Paper__Controllers.Edge.prototype.paperShift = function(_delta) {
    88     this.from_node_controller.paperShift(_delta);
   118     this.from_node_controller.paperShift(_delta);
    89     this.to_node_controller.paperShift(_delta);
   119     this.to_node_controller.paperShift(_delta);
    90     this._renderer.redraw();
   120     this._renderer.redraw();
    91 }
   121 }
    92 
       
    93 /* */
   122 /* */
    94 
   123 
       
   124 Rkns.Renderers.Paper__Controllers.TempEdge = Rkns.Utils.inherit(Rkns.Renderers.Paper__Controllers._Base);
       
   125 
       
   126 Rkns.Renderers.Paper__Controllers.TempEdge.prototype._init = function() {
       
   127     this._renderer.edge_layer.activate();
       
   128     this.type = "temp-edge";
       
   129     var _color = this._renderer._project.current_user.color;
       
   130     this.edge_line = new paper.Path();
       
   131     this.edge_line.strokeColor = _color;
       
   132     this.edge_line.add([0,0],[0,0]);
       
   133     this.edge_line.__controller = this;
       
   134     this.edge_arrow = new paper.Path();
       
   135     this.edge_arrow.fillColor = _color;
       
   136     this.edge_arrow.add([0,0],[Rkns._ARROW_LENGTH,Rkns._ARROW_WIDTH / 2],[0,Rkns._ARROW_WIDTH]);
       
   137     this.edge_arrow.__controller = this;
       
   138     this.edge_arrow_angle = 0;
       
   139 }
       
   140 
       
   141 Rkns.Renderers.Paper__Controllers.TempEdge.prototype.redraw = function() {
       
   142     var _p0 = this.from_node_controller.node_paper_coords,
       
   143         _p1 = this.end_pos,
       
   144         _a = _p1.subtract(_p0).angle,
       
   145         _c = _p0.add(_p1).divide(2);
       
   146     this.edge_line.segments[0].point = _p0;
       
   147     this.edge_line.segments[1].point = _p1;
       
   148     this.edge_arrow.rotate(_a - this.edge_arrow_angle);
       
   149     this.edge_arrow.position = _c;
       
   150     this.edge_arrow_angle = _a;
       
   151 }
       
   152 
       
   153 Rkns.Renderers.Paper__Controllers.TempEdge.prototype.paperShift = function(_delta) {
       
   154     this.end_pos = this.end_pos.add(_delta);
       
   155     this._renderer.onMouseMove({point: this.end_pos});
       
   156     this.redraw();
       
   157 }
       
   158 
       
   159 Rkns.Renderers.Paper__Controllers.TempEdge.prototype.finishEdge = function(_event) {
       
   160     var _hitResult = paper.project.hitTest(_event.point);
       
   161     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
       
   162         var _target = _hitResult.item.__controller;
       
   163         if (_target.type === "node" && this.from_node_controller._element.id !== _target._element.id) {
       
   164             this._renderer._project.addEdge({
       
   165                 from: this.from_node_controller._element.id,
       
   166                 to: _target._element.id
       
   167             }, Rkns._RENDER_AND_SAVE)
       
   168         }
       
   169     }
       
   170     this.edge_arrow.remove();
       
   171     this.edge_line.remove();
       
   172     this._renderer.controllers.removeId(this.id);
       
   173 }
       
   174 
       
   175 /* */
       
   176 
    95 Rkns.Renderers.Paper.prototype._init = function() {
   177 Rkns.Renderers.Paper.prototype._init = function() {
    96     paper.setup(document.getElementById(this._project._opts.canvas_id));
   178     this._MARGIN_X = 80;
       
   179     this._MARGIN_Y = 50;
       
   180     var _canvas_id = this._project._opts.canvas_id;
       
   181     this.$ = Rkns.$("#"+_canvas_id)
       
   182     paper.setup(document.getElementById(_canvas_id));
    97     this.scale = 1;
   183     this.scale = 1;
    98     this.offset = paper.view.center;
   184     this.offset = paper.view.center;
    99     this.totalScroll = 0;
   185     this.totalScroll = 0;
   100     this.dragging_target = null;
   186     this.dragging_target = null;
       
   187     this.selected_target = null;
   101     this.edge_layer = new paper.Layer();
   188     this.edge_layer = new paper.Layer();
   102     this.node_layer = new paper.Layer();
   189     this.node_layer = new paper.Layer();
   103     var _tool = new paper.Tool(),
   190     var _tool = new paper.Tool(),
   104         _this = this;
   191         _this = this;
       
   192     _tool.onMouseMove = function(_event) {
       
   193         _this.onMouseMove(_event);
       
   194     }
   105     _tool.onMouseDown = function(_event) {
   195     _tool.onMouseDown = function(_event) {
   106         _this.onMouseDown(_event);
   196         _this.onMouseDown(_event);
   107     }
   197     }
   108     _tool.onMouseDrag = function(_event) {
   198     _tool.onMouseDrag = function(_event) {
   109         _this.onMouseDrag(_event);
   199         _this.onMouseDrag(_event);
   110     }
   200     }
   111     Rkns.$("#"+this._project._opts.canvas_id).mousewheel(function(_event, _delta) {
   201     _tool.onMouseUp = function(_event) {
       
   202         _this.onMouseUp(_event);
       
   203     }
       
   204     this.$.mousewheel(function(_event, _delta) {
   112         _this.onScroll(_event, _delta);
   205         _this.onScroll(_event, _delta);
       
   206     })
       
   207     this.$.dblclick(function(_event) {
       
   208         _this.onDoubleClick(_event);
   113     })
   209     })
   114     paper.view.onResize = function(_event) {
   210     paper.view.onResize = function(_event) {
   115         _this.offset = _this.offset.add(_event.delta.divide(2));
   211         _this.offset = _this.offset.add(_event.delta.divide(2));
   116         _this.redraw();
   212         _this.redraw();
   117     }
   213     }
   132         _yy = this._project.nodes.map(function(_node) { return _node.position.y }),
   228         _yy = this._project.nodes.map(function(_node) { return _node.position.y }),
   133         _minx = Math.min.apply(Math, _xx),
   229         _minx = Math.min.apply(Math, _xx),
   134         _miny = Math.min.apply(Math, _yy),
   230         _miny = Math.min.apply(Math, _yy),
   135         _maxx = Math.max.apply(Math, _xx),
   231         _maxx = Math.max.apply(Math, _xx),
   136         _maxy = Math.max.apply(Math, _yy);
   232         _maxy = Math.max.apply(Math, _yy);
   137     this.scale = Math.min((paper.view.size.width - 160) / (_maxx - _minx), (paper.view.size.height - 100) / (_maxy - _miny));
   233     this.scale = Math.min((paper.view.size.width - 2 * this._MARGIN_X) / (_maxx - _minx), (paper.view.size.height - 2 * this._MARGIN_Y) / (_maxy - _miny));
   138     this.offset = paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(this.scale));
   234     this.offset = paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(this.scale));
   139     this.nodes = this._project.nodes.map(function(_node) {
   235     this.controllers = new Rkns.Model.List();
   140         return new Rkns.Renderers.Paper__Controllers.Node(_this, _node);
   236     this._project.nodes.forEach(function(_node) {
       
   237         _this.addElement("Node", _node);
   141     });
   238     });
   142     this.edges = this._project.edges.map(function(_edge) {
   239     this._project.edges.forEach(function(_edge) {
   143         return new Rkns.Renderers.Paper__Controllers.Edge(_this, _edge);
   240         _this.addElement("Edge", _edge);
   144     });
   241     });
   145     
   242     
   146     this.redraw();
   243     this.redraw();
   147 }
   244 }
   148 
   245 
       
   246 Rkns.Renderers.Paper.prototype.addElement = function(_type, _element) {
       
   247     var _el = new Rkns.Renderers.Paper__Controllers[_type](this, _element);
       
   248     this.controllers.push(_el);
       
   249     return _el;
       
   250 }
       
   251 
   149 Rkns.Renderers.Paper.prototype.redraw = function() {
   252 Rkns.Renderers.Paper.prototype.redraw = function() {
   150     Rkns._(this.nodes).each(function(_node) {
   253     this.controllers.forEach(function(_controller) {
   151         _node.redraw();
   254         _controller.redraw();
   152     });
       
   153     Rkns._(this.edges).each(function(_edge) {
       
   154         _edge.redraw();
       
   155     });
   255     });
   156     paper.view.draw();
   256     paper.view.draw();
       
   257 }
       
   258 
       
   259 Rkns.Renderers.Paper.prototype.onMouseMove = function(_event) {
       
   260     var _hitResult = paper.project.hitTest(_event.point);
       
   261     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
       
   262         if (this.selected_target !== _hitResult.item.__controller) {
       
   263             if (this.selected_target) {
       
   264                 this.selected_target.unselect();
       
   265             }
       
   266             this.selected_target = _hitResult.item.__controller;
       
   267             this.selected_target.select();
       
   268         }
       
   269     } else {
       
   270         if (this.selected_target) {
       
   271             this.selected_target.unselect();
       
   272         }
       
   273         this.selected_target = null;
       
   274     }
   157 }
   275 }
   158 
   276 
   159 Rkns.Renderers.Paper.prototype.onMouseDown = function(_event) {
   277 Rkns.Renderers.Paper.prototype.onMouseDown = function(_event) {
   160     var _hitResult = paper.project.hitTest(_event.point);
   278     var _hitResult = paper.project.hitTest(_event.point);
   161     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
   279     if (_hitResult && typeof _hitResult.item.__controller !== "undefined") {
   162         this.dragging_target = _hitResult.item.__controller;
   280         this.dragging_target = _hitResult.item.__controller;
       
   281         if (this.dragging_target.type === "node" && _hitResult.type === "stroke") {
       
   282             var _tmpEdge = this.addElement("TempEdge",{});
       
   283             _tmpEdge.end_pos = _event.point;
       
   284             _tmpEdge.from_node_controller = this.dragging_target;
       
   285             _tmpEdge.redraw();
       
   286             this.dragging_target = _tmpEdge;
       
   287         }
   163     } else {
   288     } else {
   164         this.dragging_target = null;
   289         this.dragging_target = null;
   165     }
   290     }
   166 }
   291 }
   167 
   292 
   172         this.offset = this.offset.add(_event.delta);
   297         this.offset = this.offset.add(_event.delta);
   173         this.redraw();
   298         this.redraw();
   174     }
   299     }
   175 }
   300 }
   176 
   301 
       
   302 Rkns.Renderers.Paper.prototype.onMouseUp = function(_event) {
       
   303     if (this.dragging_target && this.dragging_target.type === "temp-edge") {
       
   304         this.dragging_target.finishEdge(_event);
       
   305     }
       
   306     this.dragging_target = null;
       
   307 }
       
   308 
   177 Rkns.Renderers.Paper.prototype.onScroll = function(_event, _scrolldelta) {
   309 Rkns.Renderers.Paper.prototype.onScroll = function(_event, _scrolldelta) {
   178     this.totalScroll += _scrolldelta;
   310     this.totalScroll += _scrolldelta;
   179     if (Math.abs(this.totalScroll) >= 1) {
   311     if (Math.abs(this.totalScroll) >= 1) {
   180         var _off = Rkns.$("#"+this._project._opts.canvas_id).offset(),
   312         var _off = this.$.offset(),
   181             _delta = new paper.Point([
   313             _delta = new paper.Point([
   182                 _event.pageX - _off.left,
   314                 _event.pageX - _off.left,
   183                 _event.pageY - _off.top
   315                 _event.pageY - _off.top
   184             ]).subtract(this.offset).multiply( Math.SQRT2 - 1 );
   316             ]).subtract(this.offset).multiply( Math.SQRT2 - 1 );
   185         if (this.totalScroll > 0) {
   317         if (this.totalScroll > 0) {
   191         }
   323         }
   192         this.totalScroll = 0;
   324         this.totalScroll = 0;
   193         this.redraw();
   325         this.redraw();
   194     }
   326     }
   195 }
   327 }
       
   328 
       
   329 Rkns.Renderers.Paper.prototype.onDoubleClick = function(_event) {
       
   330     var _off = this.$.offset(),
       
   331         _point = new paper.Point([
       
   332             _event.pageX - _off.left,
       
   333             _event.pageY - _off.top
       
   334         ]);
       
   335     var _hitResult = paper.project.hitTest(_point);
       
   336     if (!_hitResult || typeof _hitResult.item.__controller === "undefined") {
       
   337         var _coords = this.toModelCoords(_point);
       
   338         this._project.addNode({
       
   339             position: {
       
   340                 x: _coords.x,
       
   341                 y: _coords.y
       
   342             }
       
   343         }, Rkns._RENDER_AND_SAVE);
       
   344     }
       
   345     paper.view.draw();
       
   346 }