client/js/paper-renderer.js
changeset 28 805d85b3f390
parent 26 2fad193bae98
child 30 8aa0cac741a0
equal deleted inserted replaced
26:2fad193bae98 28:805d85b3f390
     1 Rkns.Renderer = {}
     1 Rkns.Renderer = {
     2 
     2     _MARGIN_X: 80,
     3 Rkns.Renderer.Utils = {
     3     _MARGIN_Y: 50,
       
     4     _MIN_DRAG_DISTANCE: 2,
       
     5     _NODE_RADIUS: 15,
       
     6     _NODE_FONT_SIZE: 10,
       
     7     _EDGE_FONT_SIZE: 9,
       
     8     _NODE_MAX_CHAR: 50,
       
     9     _EDGE_MAX_CHAR: 40,
       
    10     _ARROW_LENGTH: 16,
       
    11     _ARROW_WIDTH: 8,
     4     _EDITOR_ARROW_LENGTH : 20,
    12     _EDITOR_ARROW_LENGTH : 20,
     5     _EDITOR_ARROW_WIDTH : 40,
    13     _EDITOR_ARROW_WIDTH : 40,
     6     _EDITOR_MARGIN : 15,
    14     _EDITOR_MARGIN : 15,
     7     _EDITOR_PADDING : 10,
    15     _EDITOR_PADDING : 10,
     8     _EDITOR_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0']),
    16     _EDITOR_GRADIENT : new paper.Gradient(['#f0f0f0', '#d0d0d0'])
     9     drawEditBox : function(_coords, _path, _width, _height) {
    17 }
    10         var _isLeft = (_coords.x < paper.view.center.x ? 1 : -1),
    18 
    11             _left = _coords.x + _isLeft * ( this._EDITOR_MARGIN + this._EDITOR_ARROW_LENGTH ),
    19 Rkns.Renderer.Utils = {
    12             _right = _coords.x + _isLeft * ( this._EDITOR_MARGIN + this._EDITOR_ARROW_LENGTH + _width ),
    20     drawEditBox : function(_coords, _path, _width, _xmargin, _selector) {
       
    21         _selector.css({
       
    22             width: (_width - 2* Rkns.Renderer._EDITOR_PADDING),
       
    23         })
       
    24         var _height = _selector.outerHeight() + 2* Rkns.Renderer._EDITOR_PADDING,
       
    25             _isLeft = (_coords.x < paper.view.center.x ? 1 : -1),
       
    26             _left = _coords.x + _isLeft * ( _xmargin + Rkns.Renderer._EDITOR_ARROW_LENGTH ),
       
    27             _right = _coords.x + _isLeft * ( _xmargin + Rkns.Renderer._EDITOR_ARROW_LENGTH + _width ),
    13             _top = _coords.y - _height / 2;
    28             _top = _coords.y - _height / 2;
    14         if (_top < this._EDITOR_MARGIN) {
    29         if (_top < Rkns.Renderer._EDITOR_MARGIN) {
    15             _top = Math.min( this._EDITOR_MARGIN, _coords.y - this._EDITOR_ARROW_WIDTH / 2 );
    30             _top = Math.min( Rkns.Renderer._EDITOR_MARGIN, _coords.y - Rkns.Renderer._EDITOR_ARROW_WIDTH / 2 );
    16         }
    31         }
    17         var _bottom = _top + _height;
    32         var _bottom = _top + _height;
    18         if (_bottom > (paper.view.size.height - this._EDITOR_MARGIN)) {
    33         if (_bottom > (paper.view.size.height - Rkns.Renderer._EDITOR_MARGIN)) {
    19             _bottom = Math.max( paper.view.size.height - this._EDITOR_MARGIN, _coords.y + this._EDITOR_ARROW_WIDTH / 2 );
    34             _bottom = Math.max( paper.view.size.height - Rkns.Renderer._EDITOR_MARGIN, _coords.y + Rkns.Renderer._EDITOR_ARROW_WIDTH / 2 );
    20             _top = _bottom - _height;
    35             _top = _bottom - _height;
    21         }
    36         }
    22         _path.segments[0].point
    37         _path.segments[0].point
    23             = _path.segments[7].point
    38             = _path.segments[7].point
    24             = _coords.add([_isLeft * this._EDITOR_MARGIN, 0]);
    39             = _coords.add([_isLeft * _xmargin, 0]);
    25         _path.segments[1].point.x
    40         _path.segments[1].point.x
    26             = _path.segments[2].point.x
    41             = _path.segments[2].point.x
    27             = _path.segments[5].point.x
    42             = _path.segments[5].point.x
    28             = _path.segments[6].point.x
    43             = _path.segments[6].point.x
    29             = _left;
    44             = _left;
    34             = _path.segments[3].point.y
    49             = _path.segments[3].point.y
    35             = _top;
    50             = _top;
    36         _path.segments[4].point.y
    51         _path.segments[4].point.y
    37             = _path.segments[5].point.y
    52             = _path.segments[5].point.y
    38             = _bottom;
    53             = _bottom;
    39         _path.segments[1].point.y = _coords.y - this._EDITOR_ARROW_WIDTH / 2;
    54         _path.segments[1].point.y = _coords.y - Rkns.Renderer._EDITOR_ARROW_WIDTH / 2;
    40         _path.segments[6].point.y = _coords.y + this._EDITOR_ARROW_WIDTH / 2;
    55         _path.segments[6].point.y = _coords.y + Rkns.Renderer._EDITOR_ARROW_WIDTH / 2;
    41         _path.fillColor = new paper.GradientColor(this._EDITOR_GRADIENT, [0,_top], [0, _bottom])
    56         _path.closed = true;
    42         return {
    57         _path.fillColor = new paper.GradientColor(Rkns.Renderer._EDITOR_GRADIENT, [0,_top], [0, _bottom]);
    43             left: (this._EDITOR_PADDING + Math.min(_left, _right)),
    58         _selector.css({
    44             top: (this._EDITOR_PADDING + _top)
    59             left: (Rkns.Renderer._EDITOR_PADDING + Math.min(_left, _right)),
    45         }
    60             top: (Rkns.Renderer._EDITOR_PADDING + _top)
       
    61         });
    46     },
    62     },
    47     sector : function(_repr, _inR, _outR, _startAngle, _endAngle, _padding, _imgsrc) {
    63     sector : function(_repr, _inR, _outR, _startAngle, _endAngle, _padding, _imgsrc) {
    48         var _startRads = _startAngle * Math.PI / 180,
    64         var _startRads = _startAngle * Math.PI / 180,
    49             _endRads = _endAngle * Math.PI / 180,
    65             _endRads = _endAngle * Math.PI / 180,
    50             _img = new Image(),
    66             _img = new Image(),
   165 Rkns.Renderer.Node = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   181 Rkns.Renderer.Node = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   166 
   182 
   167 Rkns.Renderer.Node.prototype._init = function() {
   183 Rkns.Renderer.Node.prototype._init = function() {
   168     this.renderer.node_layer.activate();
   184     this.renderer.node_layer.activate();
   169     this.type = "Node";
   185     this.type = "Node";
   170     this.circle = new paper.Path.Circle([0, 0], Rkns._NODE_RADIUS);
   186     this.circle = new paper.Path.Circle([0, 0], Rkns.Renderer._NODE_RADIUS);
   171     this.circle.fillColor = '#ffffff';
   187     this.circle.fillColor = '#ffffff';
   172     this.circle.__representation = this;
   188     this.circle.__representation = this;
   173     this.title = new paper.PointText([0,0]);
   189     this.title = new paper.PointText([0,0]);
   174     this.title.characterStyle = {
   190     this.title.characterStyle = {
   175         fontSize: Rkns._NODE_FONT_SIZE,
   191         fontSize: Rkns.Renderer._NODE_FONT_SIZE,
   176         fillColor: 'black'
   192         fillColor: 'black'
   177     };
   193     };
   178     this.edit_button = new Rkns.Renderer.NodeEditButton(this.renderer, {});
   194     this.edit_button = new Rkns.Renderer.NodeEditButton(this.renderer, {});
   179     this.edit_button.node_representation = this;
   195     this.edit_button.node_representation = this;
   180     this.remove_button = new Rkns.Renderer.NodeRemoveButton(this.renderer, {});
   196     this.remove_button = new Rkns.Renderer.NodeRemoveButton(this.renderer, {});
   188 Rkns.Renderer.Node.prototype.redraw = function() {
   204 Rkns.Renderer.Node.prototype.redraw = function() {
   189     var _model_coords = new paper.Point(this.model.get("position"));
   205     var _model_coords = new paper.Point(this.model.get("position"));
   190     this.paper_coords = this.renderer.toPaperCoords(_model_coords);
   206     this.paper_coords = this.renderer.toPaperCoords(_model_coords);
   191     this.circle.position = this.paper_coords;
   207     this.circle.position = this.paper_coords;
   192     this.title.content = this.model.get("title");
   208     this.title.content = this.model.get("title");
   193     this.title.position = this.paper_coords.add([0, 2 * Rkns._NODE_RADIUS]);
   209     this.title.position = this.paper_coords.add([0, 2 * Rkns.Renderer._NODE_RADIUS]);
   194     this.circle.strokeColor = this.model.get("created_by").get("color");
   210     this.circle.strokeColor = this.model.get("created_by").get("color");
   195     this.edit_button.moveTo(this.paper_coords);
   211     this.edit_button.moveTo(this.paper_coords);
   196     this.remove_button.moveTo(this.paper_coords);
   212     this.remove_button.moveTo(this.paper_coords);
   197     this.link_button.moveTo(this.paper_coords);
   213     this.link_button.moveTo(this.paper_coords);
   198 }
   214 }
   273     this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
   289     this.to_representation = this.renderer.getRepresentationByModel(this.model.get("to"));
   274     this.line = new paper.Path();
   290     this.line = new paper.Path();
   275     this.line.add([0,0],[0,0]);
   291     this.line.add([0,0],[0,0]);
   276     this.line.__representation = this;
   292     this.line.__representation = this;
   277     this.arrow = new paper.Path();
   293     this.arrow = new paper.Path();
   278     this.arrow.add([0,0],[Rkns._ARROW_LENGTH,Rkns._ARROW_WIDTH / 2],[0,Rkns._ARROW_WIDTH]);
   294     this.arrow.add([0,0],[Rkns.Renderer._ARROW_LENGTH,Rkns.Renderer._ARROW_WIDTH / 2],[0,Rkns.Renderer._ARROW_WIDTH]);
   279     this.arrow.__representation = this;
   295     this.arrow.__representation = this;
   280     this.text = new paper.PointText();
   296     this.text = new paper.PointText();
   281     this.text.characterStyle = {
   297     this.text.characterStyle = {
   282         fontSize: Rkns._EDGE_FONT_SIZE,
   298         fontSize: Rkns.Renderer._EDGE_FONT_SIZE,
   283         fillColor: 'black'
   299         fillColor: 'black'
   284     };
   300     };
   285     this.text.paragraphStyle.justification = 'center';
   301     this.text.paragraphStyle.justification = 'center';
   286     this.text.__representation = this;
   302     this.text.__representation = this;
   287     this.text_angle = 0;
   303     this.text_angle = 0;
   379     this.line.strokeColor = _color;
   395     this.line.strokeColor = _color;
   380     this.line.add([0,0],[0,0]);
   396     this.line.add([0,0],[0,0]);
   381     this.line.__representation = this;
   397     this.line.__representation = this;
   382     this.arrow = new paper.Path();
   398     this.arrow = new paper.Path();
   383     this.arrow.fillColor = _color;
   399     this.arrow.fillColor = _color;
   384     this.arrow.add([0,0],[Rkns._ARROW_LENGTH,Rkns._ARROW_WIDTH / 2],[0,Rkns._ARROW_WIDTH]);
   400     this.arrow.add([0,0],[Rkns.Renderer._ARROW_LENGTH,Rkns.Renderer._ARROW_WIDTH / 2],[0,Rkns.Renderer._ARROW_WIDTH]);
   385     this.arrow.__representation = this;
   401     this.arrow.__representation = this;
   386     this.arrow_angle = 0;
   402     this.arrow_angle = 0;
   387 }
   403 }
   388 
   404 
   389 Rkns.Renderer.TempEdge.prototype.redraw = function() {
   405 Rkns.Renderer.TempEdge.prototype.redraw = function() {
   458     + '<p><label><%=l10n.created_by%></label> <span class="Rk-UserColor" style="background:<%=node.created_by_color%>;"></span><%=node.created_by_title%></p>'
   474     + '<p><label><%=l10n.created_by%></label> <span class="Rk-UserColor" style="background:<%=node.created_by_color%>;"></span><%=node.created_by_title%></p>'
   459 );
   475 );
   460 
   476 
   461 Rkns.Renderer.NodeEditor.prototype.redraw = function() {
   477 Rkns.Renderer.NodeEditor.prototype.redraw = function() {
   462     var _coords = this.node_representation.paper_coords,
   478     var _coords = this.node_representation.paper_coords,
   463         _model = this.node_representation.model,
   479         _model = this.node_representation.model;
   464         _css = Rkns.Renderer.Utils.drawEditBox(_coords, this.editor_block, 250, 300);
       
   465     this.editor_$
   480     this.editor_$
   466         .html(this.template({
   481         .html(this.template({
   467             node: {
   482             node: {
   468                 title: _model.get("title"),
   483                 title: _model.get("title"),
   469                 uri: _model.get("uri"),
   484                 uri: _model.get("uri"),
   471                 created_by_color: _model.get("created_by").get("color"),
   486                 created_by_color: _model.get("created_by").get("color"),
   472                 created_by_title: _model.get("created_by").get("title")
   487                 created_by_title: _model.get("created_by").get("title")
   473             },
   488             },
   474             l10n: this.renderer.renkan.l10n
   489             l10n: this.renderer.renkan.l10n
   475         }))
   490         }))
   476         .show()
   491         .show();
   477         .css(_css);
   492     Rkns.Renderer.Utils.drawEditBox(_coords, this.editor_block, 250, 20, this.editor_$);
   478     var _this = this;
   493     var _this = this;
   479     this.editor_$.find(".Rk-CloseX").click(function() {
   494     this.editor_$.find(".Rk-CloseX").click(function() {
   480         _this.renderer.removeRepresentation(_this);
   495         _this.renderer.removeRepresentation(_this);
   481         paper.view.draw();
   496         paper.view.draw();
   482     });
   497     });
   531     + '<p><label><%=l10n.created_by%> </label><span class="Rk-UserColor" style="background:<%=edge.created_by_color%>;"></span><%=edge.created_by_title%></p>'
   546     + '<p><label><%=l10n.created_by%> </label><span class="Rk-UserColor" style="background:<%=edge.created_by_color%>;"></span><%=edge.created_by_title%></p>'
   532 );
   547 );
   533 
   548 
   534 Rkns.Renderer.EdgeEditor.prototype.redraw = function() {
   549 Rkns.Renderer.EdgeEditor.prototype.redraw = function() {
   535     var _coords = this.edge_representation.paper_coords,
   550     var _coords = this.edge_representation.paper_coords,
   536         _model = this.edge_representation.model,
   551         _model = this.edge_representation.model;
   537         _css = Rkns.Renderer.Utils.drawEditBox(_coords, this.editor_block, 250, 200);
       
   538     this.editor_$
   552     this.editor_$
   539         .html(this.template({
   553         .html(this.template({
   540             edge: {
   554             edge: {
   541                 title: _model.get("title"),
   555                 title: _model.get("title"),
   542                 uri: _model.get("uri"),
   556                 uri: _model.get("uri"),
   548                 created_by_color: _model.get("created_by").get("color"),
   562                 created_by_color: _model.get("created_by").get("color"),
   549                 created_by_title: _model.get("created_by").get("title")
   563                 created_by_title: _model.get("created_by").get("title")
   550             },
   564             },
   551             l10n: this.renderer.renkan.l10n
   565             l10n: this.renderer.renkan.l10n
   552         }))
   566         }))
   553         .show()
   567         .show();
   554         .css(_css);
   568     Rkns.Renderer.Utils.drawEditBox(_coords, this.editor_block, 250, 5, this.editor_$);
   555     var _this = this;
   569     var _this = this;
   556     this.editor_$.find(".Rk-CloseX").click(function() {
   570     this.editor_$.find(".Rk-CloseX").click(function() {
   557         _this.renderer.removeRepresentation(_this);
   571         _this.renderer.removeRepresentation(_this);
   558         paper.view.draw();
   572         paper.view.draw();
   559     });
   573     });
   560     this.editor_$.find("input, textarea").bind("keyup change", function() {
   574     this.editor_$.find("input, textarea").bind("keyup change", function() {
       
   575         _this.editor_$.find(".Rk-Edit-Goto").attr("href",_this.editor_$.find(".Rk-Edit-URI").val());
   561         var _data = {
   576         var _data = {
   562             title: _this.editor_$.find(".Rk-Edit-Title").val(),
   577             title: _this.editor_$.find(".Rk-Edit-Title").val(),
   563             uri: _this.editor_$.find(".Rk-Edit-URI").val()
   578             uri: _this.editor_$.find(".Rk-Edit-URI").val()
   564         }
   579         }
   565         _model.set(_data);
   580         _model.set(_data);
   578 Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   593 Rkns.Renderer.NodeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   579 
   594 
   580 Rkns.Renderer.NodeEditButton.prototype._init = function() {
   595 Rkns.Renderer.NodeEditButton.prototype._init = function() {
   581     this.renderer.node_layer.activate();
   596     this.renderer.node_layer.activate();
   582     this.type = "Node-edit-button";
   597     this.type = "Node-edit-button";
   583     this.sector = Rkns.Renderer.Utils.sector(this, 1 + Rkns._NODE_RADIUS, 3 * Rkns._NODE_RADIUS, - 90, 30, 2, 'img/edit.png');
   598     this.sector = Rkns.Renderer.Utils.sector(this, 1 + Rkns.Renderer._NODE_RADIUS, 3 * Rkns.Renderer._NODE_RADIUS, - 90, 30, 2, 'img/edit.png');
   584 }
   599 }
   585 
   600 
   586 Rkns.Renderer.NodeEditButton.prototype.moveTo = function(_pos) {
   601 Rkns.Renderer.NodeEditButton.prototype.moveTo = function(_pos) {
   587     this.sector.moveTo(_pos);
   602     this.sector.moveTo(_pos);
   588 }
   603 }
   621 Rkns.Renderer.NodeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   636 Rkns.Renderer.NodeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   622 
   637 
   623 Rkns.Renderer.NodeRemoveButton.prototype._init = function() {
   638 Rkns.Renderer.NodeRemoveButton.prototype._init = function() {
   624     this.renderer.node_layer.activate();
   639     this.renderer.node_layer.activate();
   625     this.type = "Node-remove-button";
   640     this.type = "Node-remove-button";
   626     this.sector = Rkns.Renderer.Utils.sector(this, 1 + Rkns._NODE_RADIUS, 3 * Rkns._NODE_RADIUS, -210, -90, 2, 'img/remove.png');
   641     this.sector = Rkns.Renderer.Utils.sector(this, 1 + Rkns.Renderer._NODE_RADIUS, 3 * Rkns.Renderer._NODE_RADIUS, -210, -90, 2, 'img/remove.png');
   627 }
   642 }
   628 
   643 
   629 Rkns.Renderer.NodeRemoveButton.prototype.moveTo = function(_pos) {
   644 Rkns.Renderer.NodeRemoveButton.prototype.moveTo = function(_pos) {
   630     this.sector.moveTo(_pos);
   645     this.sector.moveTo(_pos);
   631 }
   646 }
   664 Rkns.Renderer.NodeLinkButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   679 Rkns.Renderer.NodeLinkButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   665 
   680 
   666 Rkns.Renderer.NodeLinkButton.prototype._init = function() {
   681 Rkns.Renderer.NodeLinkButton.prototype._init = function() {
   667     this.renderer.node_layer.activate();
   682     this.renderer.node_layer.activate();
   668     this.type = "Node-link-button";
   683     this.type = "Node-link-button";
   669     this.sector = Rkns.Renderer.Utils.sector(this, 1 + Rkns._NODE_RADIUS , 3 * Rkns._NODE_RADIUS, 30, 150, 2, 'img/link.png');
   684     this.sector = Rkns.Renderer.Utils.sector(this, 1 + Rkns.Renderer._NODE_RADIUS , 3 * Rkns.Renderer._NODE_RADIUS, 30, 150, 2, 'img/link.png');
   670 }
   685 }
   671 
   686 
   672 Rkns.Renderer.NodeLinkButton.prototype.moveTo = function(_pos) {
   687 Rkns.Renderer.NodeLinkButton.prototype.moveTo = function(_pos) {
   673     this.sector.moveTo(_pos);
   688     this.sector.moveTo(_pos);
   674 }
   689 }
   701 Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   716 Rkns.Renderer.EdgeEditButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   702 
   717 
   703 Rkns.Renderer.EdgeEditButton.prototype._init = function() {
   718 Rkns.Renderer.EdgeEditButton.prototype._init = function() {
   704     this.renderer.edge_layer.activate();
   719     this.renderer.edge_layer.activate();
   705     this.type = "Edge-edit-button";
   720     this.type = "Edge-edit-button";
   706     this.sector = Rkns.Renderer.Utils.sector(this, 5 , 2 * Rkns._NODE_RADIUS, - 60, 60, 2, 'img/edit.png');
   721     this.sector = Rkns.Renderer.Utils.sector(this, 5 , 2 * Rkns.Renderer._NODE_RADIUS, - 60, 60, 2, 'img/edit.png');
   707 }
   722 }
   708 
   723 
   709 Rkns.Renderer.EdgeEditButton.prototype.moveTo = function(_pos) {
   724 Rkns.Renderer.EdgeEditButton.prototype.moveTo = function(_pos) {
   710     this.sector.moveTo(_pos);
   725     this.sector.moveTo(_pos);
   711 }
   726 }
   743 Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   758 Rkns.Renderer.EdgeRemoveButton = Rkns.Utils.inherit(Rkns.Renderer._BaseRepresentation);
   744 
   759 
   745 Rkns.Renderer.EdgeRemoveButton.prototype._init = function() {
   760 Rkns.Renderer.EdgeRemoveButton.prototype._init = function() {
   746     this.renderer.edge_layer.activate();
   761     this.renderer.edge_layer.activate();
   747     this.type = "Edge-remove-button";
   762     this.type = "Edge-remove-button";
   748     this.sector = Rkns.Renderer.Utils.sector(this, 5, 2 * Rkns._NODE_RADIUS, - 240, -120, 2, 'img/remove.png');
   763     this.sector = Rkns.Renderer.Utils.sector(this, 5, 2 * Rkns.Renderer._NODE_RADIUS, - 240, -120, 2, 'img/remove.png');
   749 }
   764 }
   750 Rkns.Renderer.EdgeRemoveButton.prototype.moveTo = function(_pos) {
   765 Rkns.Renderer.EdgeRemoveButton.prototype.moveTo = function(_pos) {
   751     this.sector.moveTo(_pos);
   766     this.sector.moveTo(_pos);
   752 }
   767 }
   753 
   768 
   781 
   796 
   782 /* */
   797 /* */
   783 
   798 
   784 Rkns.Renderer.Scene = function(_renkan) {
   799 Rkns.Renderer.Scene = function(_renkan) {
   785     this.renkan = _renkan;
   800     this.renkan = _renkan;
   786     this._MARGIN_X = 80;
       
   787     this._MARGIN_Y = 50;
       
   788     this.$ = Rkns.$(".Rk-Render");
   801     this.$ = Rkns.$(".Rk-Render");
   789     this.representations = [];
   802     this.representations = [];
   790     this.$.html(this.template({
   803     this.$.html(this.template({
   791         l10n: _renkan.l10n
   804         l10n: _renkan.l10n
   792     }))
   805     }))
   801     this.edge_layer = new paper.Layer();
   814     this.edge_layer = new paper.Layer();
   802     this.node_layer = new paper.Layer();
   815     this.node_layer = new paper.Layer();
   803     this.overlay_layer = new paper.Layer();
   816     this.overlay_layer = new paper.Layer();
   804     var _tool = new paper.Tool(),
   817     var _tool = new paper.Tool(),
   805         _this = this;
   818         _this = this;
   806     _tool.minDistance = Rkns._MIN_DRAG_DISTANCE;
   819     _tool.minDistance = Rkns.Renderer._MIN_DRAG_DISTANCE;
   807     _tool.onMouseMove = function(_event) {
   820     _tool.onMouseMove = function(_event) {
   808         _this.onMouseMove(_event);
   821         _this.onMouseMove(_event);
   809     }
   822     }
   810     _tool.onMouseDown = function(_event) {
   823     _tool.onMouseDown = function(_event) {
   811         _this.onMouseDown(_event);
   824         _this.onMouseDown(_event);
   828     this.editor_$.find(".Rk-ZoomOut").click(function() {
   841     this.editor_$.find(".Rk-ZoomOut").click(function() {
   829         _this.offset = new paper.Point([
   842         _this.offset = new paper.Point([
   830             _this.canvas_$.width(),
   843             _this.canvas_$.width(),
   831             _this.canvas_$.height()
   844             _this.canvas_$.height()
   832         ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(_this.offset.multiply( Math.SQRT1_2 ));
   845         ]).multiply( .5 * ( 1 - Math.SQRT1_2 ) ).add(_this.offset.multiply( Math.SQRT1_2 ));
   833         _this.scale *= Math.SQRT1_2;
   846         _this.setScale( _this.scale * Math.SQRT1_2 );
   834         _this.redraw();
   847         _this.redraw();
   835     });
   848     });
   836     this.editor_$.find(".Rk-ZoomIn").click(function() {
   849     this.editor_$.find(".Rk-ZoomIn").click(function() {
   837         _this.offset = new paper.Point([
   850         _this.offset = new paper.Point([
   838             _this.canvas_$.width(),
   851             _this.canvas_$.width(),
   839             _this.canvas_$.height()
   852             _this.canvas_$.height()
   840         ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 ));
   853         ]).multiply( .5 * ( 1 - Math.SQRT2 ) ).add(_this.offset.multiply( Math.SQRT2 ));
   841         _this.scale *= Math.SQRT2;
   854         _this.setScale( _this.scale * Math.SQRT2 );
   842         _this.redraw();
   855         _this.redraw();
   843     });
   856     });
   844     paper.view.onResize = function(_event) {
   857     paper.view.onResize = function(_event) {
   845         _this.offset = _this.offset.add(_event.delta.divide(2));
   858         _this.offset = _this.offset.add(_event.delta.divide(2));
   846         _this.redraw();
   859         _this.redraw();
   869     '<canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor">'
   882     '<canvas class="Rk-Canvas" resize></canvas><div class="Rk-Editor">'
   870     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%=l10n.zoom_in%>"></div><div class="Rk-ZoomOut" title="<%=l10n.zoom_out%>"></div></div>'
   883     + '<div class="Rk-ZoomButtons"><div class="Rk-ZoomIn" title="<%=l10n.zoom_in%>"></div><div class="Rk-ZoomOut" title="<%=l10n.zoom_out%>"></div></div>'
   871     + '</div>'
   884     + '</div>'
   872 );
   885 );
   873 
   886 
       
   887 Rkns.Renderer.Scene.prototype.setScale = function(_newScale) {
       
   888     this.scale = _newScale;
       
   889     this.redraw();
       
   890 }
       
   891 
   874 Rkns.Renderer.Scene.prototype.autoScale = function() {
   892 Rkns.Renderer.Scene.prototype.autoScale = function() {
   875     if (this.renkan.project.get("nodes").length) {
   893     if (this.renkan.project.get("nodes").length) {
   876         var _xx = this.renkan.project.get("nodes").map(function(_node) { return _node.get("position").x }),
   894         var _xx = this.renkan.project.get("nodes").map(function(_node) { return _node.get("position").x }),
   877             _yy = this.renkan.project.get("nodes").map(function(_node) { return _node.get("position").y }),
   895             _yy = this.renkan.project.get("nodes").map(function(_node) { return _node.get("position").y }),
   878             _minx = Math.min.apply(Math, _xx),
   896             _minx = Math.min.apply(Math, _xx),
   879             _miny = Math.min.apply(Math, _yy),
   897             _miny = Math.min.apply(Math, _yy),
   880             _maxx = Math.max.apply(Math, _xx),
   898             _maxx = Math.max.apply(Math, _xx),
   881             _maxy = Math.max.apply(Math, _yy);
   899             _maxy = Math.max.apply(Math, _yy);
   882         this.scale = Math.min((paper.view.size.width - 2 * this._MARGIN_X) / (_maxx - _minx), (paper.view.size.height - 2 * this._MARGIN_Y) / (_maxy - _miny));
   900         var _scale = Math.min((paper.view.size.width - 2 * Rkns.Renderer._MARGIN_X) / (_maxx - _minx), (paper.view.size.height - 2 * Rkns.Renderer._MARGIN_Y) / (_maxy - _miny));
   883         this.offset = paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(this.scale));
   901         this.offset = paper.view.center.subtract(new paper.Point([(_maxx + _minx) / 2, (_maxy + _miny) / 2]).multiply(_scale));
   884         this.redraw();
   902         this.setScale(_scale);
   885     }
   903     }
   886 }
   904 }
   887 
   905 
   888 Rkns.Renderer.Scene.prototype.toPaperCoords = function(_point) {
   906 Rkns.Renderer.Scene.prototype.toPaperCoords = function(_point) {
   889     return _point.multiply(this.scale).add(this.offset);
   907     return _point.multiply(this.scale).add(this.offset);
  1047                 _event.pageX - _off.left,
  1065                 _event.pageX - _off.left,
  1048                 _event.pageY - _off.top
  1066                 _event.pageY - _off.top
  1049             ]).subtract(this.offset).multiply( Math.SQRT2 - 1 );
  1067             ]).subtract(this.offset).multiply( Math.SQRT2 - 1 );
  1050         if (this.totalScroll > 0) {
  1068         if (this.totalScroll > 0) {
  1051             this.offset = this.offset.subtract(_delta);
  1069             this.offset = this.offset.subtract(_delta);
  1052             this.scale *= Math.SQRT2;
  1070             this.setScale( this.scale * Math.SQRT2 );
  1053         } else {
  1071         } else {
  1054             this.offset = this.offset.add(_delta.divide( Math.SQRT2 ));
  1072             this.offset = this.offset.add(_delta.divide( Math.SQRT2 ));
  1055             this.scale *= Math.SQRT1_2;
  1073             this.setScale( this.scale * Math.SQRT1_2);
  1056         }
  1074         }
  1057         this.totalScroll = 0;
  1075         this.totalScroll = 0;
  1058         this.redraw();
  1076         this.redraw();
  1059     }
  1077     }
  1060 }
  1078 }