aboutsummaryrefslogtreecommitdiff
path: root/js/tools/PenTool.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/tools/PenTool.js')
-rwxr-xr-xjs/tools/PenTool.js160
1 files changed, 115 insertions, 45 deletions
diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js
index 7749d525..ddc8bc04 100755
--- a/js/tools/PenTool.js
+++ b/js/tools/PenTool.js
@@ -66,14 +66,14 @@ exports.PenTool = Montage.create(ShapeTool, {
66 _penPlaneMat: { value: null, writable: true }, 66 _penPlaneMat: { value: null, writable: true },
67 67
68 //index of the anchor point that the user has hovered over 68 //index of the anchor point that the user has hovered over
69 _hoveredAnchorIndex: {value: null, writable: true}, 69 _hoveredAnchorIndex: {value: -1, writable: true},
70 70
71 //constants used for picking points --- NOTE: these should be user-settable parameters 71 //constants used for picking points --- NOTE: these should be user-settable parameters
72 _PICK_POINT_RADIUS: { value: 10, writable: false }, 72 _PICK_POINT_RADIUS: { value: 10, writable: false },
73 _DISPLAY_ANCHOR_RADIUS: { value: 5, writable: false }, 73 _DISPLAY_ANCHOR_RADIUS: { value: 5, writable: false },
74 _DISPLAY_SELECTED_ANCHOR_RADIUS: { value: 10, writable: false }, 74 _DISPLAY_SELECTED_ANCHOR_RADIUS: { value: 10, writable: false },
75 _DISPLAY_SELECTED_ANCHOR_PREV_RADIUS: { value: 5, writable: false }, 75 _DISPLAY_SELECTED_ANCHOR_PREV_RADIUS: { value: 2, writable: false },
76 _DISPLAY_SELECTED_ANCHOR_NEXT_RADIUS: { value: 5, writable: false }, 76 _DISPLAY_SELECTED_ANCHOR_NEXT_RADIUS: { value: 2, writable: false },
77 77
78 //constants used for editing modes (can be OR-ed) 78 //constants used for editing modes (can be OR-ed)
79 EDIT_NONE: { value: 0, writable: false }, 79 EDIT_NONE: { value: 0, writable: false },
@@ -760,9 +760,7 @@ exports.PenTool = Montage.create(ShapeTool, {
760 var verticalOffset = this.application.ninja.stage.userContentTop; 760 var verticalOffset = this.application.ninja.stage.userContentTop;
761 //display the subpath as a sequence of cubic beziers 761 //display the subpath as a sequence of cubic beziers
762 ctx.lineWidth = 1;//TODO replace hardcoded stroke width with some programmatically set value (should not be same as stroke width) 762 ctx.lineWidth = 1;//TODO replace hardcoded stroke width with some programmatically set value (should not be same as stroke width)
763 if (ctx.lineWidth == subpath.getStrokeWidth()) 763 ctx.strokeStyle = "green";
764 ctx.lineWidth = 3;
765 ctx.strokeStyle = "black";
766 //if (subpath.getStrokeColor()) 764 //if (subpath.getStrokeColor())
767 // ctx.strokeStyle = MathUtils.colorToHex( subpath.getStrokeColor() ); 765 // ctx.strokeStyle = MathUtils.colorToHex( subpath.getStrokeColor() );
768 ctx.beginPath(); 766 ctx.beginPath();
@@ -812,34 +810,53 @@ exports.PenTool = Montage.create(ShapeTool, {
812 var verticalOffset = this.application.ninja.stage.userContentTop;//stageManagerModule.stageManager.userContentTop; 810 var verticalOffset = this.application.ninja.stage.userContentTop;//stageManagerModule.stageManager.userContentTop;
813 811
814 //display circles and squares near all control points 812 //display circles and squares near all control points
815 ctx.fillStyle = "#FF4444"; 813 ctx.fillStyle = "#FFFFFF";
816 ctx.lineWidth = 2; 814 ctx.lineWidth = 1;
817 ctx.strokeStyle = "black"; 815 ctx.strokeStyle = "green";
816 var anchorDelta = 2;
817 var selAnchorDelta = 4;
818
818 for (var i = 0; i < numAnchors; i++) { 819 for (var i = 0; i < numAnchors; i++) {
819 var px = subpath.getAnchor(i).getPosX(); 820 var px = subpath.getAnchor(i).getPosX();
820 var py = subpath.getAnchor(i).getPosY(); 821 var py = subpath.getAnchor(i).getPosY();
821 ctx.beginPath(); 822 ctx.beginPath();
822 ctx.arc(px + horizontalOffset, py + verticalOffset, this._DISPLAY_ANCHOR_RADIUS, 0, 2 * Math.PI, false); 823 //ctx.arc(px + horizontalOffset, py + verticalOffset, this._DISPLAY_ANCHOR_RADIUS, 0, 2 * Math.PI, false);
824 ctx.moveTo(px-anchorDelta+horizontalOffset, py-anchorDelta+verticalOffset);
825 ctx.lineTo(px+anchorDelta+horizontalOffset, py-anchorDelta+verticalOffset);
826 ctx.lineTo(px+anchorDelta+horizontalOffset, py+anchorDelta+verticalOffset);
827 ctx.lineTo(px-anchorDelta+horizontalOffset, py+anchorDelta+verticalOffset);
828 ctx.closePath();
823 ctx.fill(); 829 ctx.fill();
824 ctx.stroke(); 830 ctx.stroke();
825 } 831 }
826 832
827 //display the hovered over anchor point 833 //display the hovered over anchor point
828 ctx.lineWidth = 2; 834 ctx.lineWidth = 2;
829 ctx.strokeStyle = "black"; 835 if (this._hoveredAnchorIndex>=0 && this._hoveredAnchorIndex<numAnchors) {
830 if (this._hoveredAnchorIndex && this._hoveredAnchorIndex>=0 && this._hoveredAnchorIndex<numAnchors) {
831 var px = subpath.getAnchor(this._hoveredAnchorIndex).getPosX(); 836 var px = subpath.getAnchor(this._hoveredAnchorIndex).getPosX();
832 var py = subpath.getAnchor(this._hoveredAnchorIndex).getPosY(); 837 var py = subpath.getAnchor(this._hoveredAnchorIndex).getPosY();
833 ctx.beginPath(); 838 ctx.beginPath();
834 ctx.arc(px + horizontalOffset, py + verticalOffset, this._DISPLAY_ANCHOR_RADIUS*1.5, 0, 2 * Math.PI, false); 839 //ctx.arc(px + horizontalOffset, py + verticalOffset, this._DISPLAY_ANCHOR_RADIUS*1.5, 0, 2 * Math.PI, false);
840 ctx.moveTo(px-selAnchorDelta+horizontalOffset, py-selAnchorDelta+verticalOffset);
841 ctx.lineTo(px+selAnchorDelta+horizontalOffset, py-selAnchorDelta+verticalOffset);
842 ctx.lineTo(px+selAnchorDelta+horizontalOffset, py+selAnchorDelta+verticalOffset);
843 ctx.lineTo(px-selAnchorDelta+horizontalOffset, py+selAnchorDelta+verticalOffset);
844 ctx.closePath();
835 ctx.stroke(); 845 ctx.stroke();
836 } 846 }
837 847
848
838 //display selected anchor and its prev. and next points 849 //display selected anchor and its prev. and next points
839 if (this._selectedSubpath && subpath === this._selectedSubpath && this._selectedSubpath.getSelectedAnchorIndex()!== -1) { 850 if (this._selectedSubpath && subpath === this._selectedSubpath && this._selectedSubpath.getSelectedAnchorIndex()!== -1) {
840 ctx.lineWidth = 2; 851 ctx.lineWidth = 1;
841 ctx.strokeStyle = "black"; 852 var defFill = "#FFFFFF";
853 var defStroke = "green";
854 var selHandleFill = "#000000"
855
856 ctx.strokeStyle = defStroke;
857 ctx.fillStyle = defFill;
842 var selAnchor = this._selectedSubpath.getAnchor(this._selectedSubpath.getSelectedAnchorIndex()); 858 var selAnchor = this._selectedSubpath.getAnchor(this._selectedSubpath.getSelectedAnchorIndex());
859 var whichPoint = this._selectedSubpath.getSelectedMode(); //which of the selected handles to highlight
843 860
844 //line from prev to anchor 861 //line from prev to anchor
845 ctx.beginPath(); 862 ctx.beginPath();
@@ -848,10 +865,16 @@ exports.PenTool = Montage.create(ShapeTool, {
848 ctx.stroke(); 865 ctx.stroke();
849 866
850 //selected anchor prev 867 //selected anchor prev
851 ctx.fillStyle = "#AAAAAA";
852 ctx.beginPath(); 868 ctx.beginPath();
853 ctx.arc(selAnchor.getPrevX() + horizontalOffset, selAnchor.getPrevY() + verticalOffset, this._DISPLAY_SELECTED_ANCHOR_PREV_RADIUS, 0, 2 * Math.PI, false); 869 ctx.arc(selAnchor.getPrevX() + horizontalOffset, selAnchor.getPrevY() + verticalOffset, this._DISPLAY_SELECTED_ANCHOR_PREV_RADIUS, 0, 2 * Math.PI, false);
854 ctx.fill(); 870 ctx.closePath();
871 if (whichPoint & this._selectedSubpath.SEL_PREV){
872 ctx.fillStyle = selHandleFill;
873 ctx.fill();
874 ctx.fillStyle = defFill;
875 }else {
876 ctx.fill();
877 }
855 ctx.stroke(); 878 ctx.stroke();
856 879
857 //line from next to anchor 880 //line from next to anchor
@@ -861,16 +884,27 @@ exports.PenTool = Montage.create(ShapeTool, {
861 ctx.stroke(); 884 ctx.stroke();
862 885
863 //selected anchor next 886 //selected anchor next
864 ctx.fillStyle = "#666666";
865 ctx.beginPath(); 887 ctx.beginPath();
866 ctx.arc(selAnchor.getNextX() + horizontalOffset, selAnchor.getNextY() + verticalOffset, this._DISPLAY_SELECTED_ANCHOR_NEXT_RADIUS, 0, 2 * Math.PI, false); 888 ctx.arc(selAnchor.getNextX() + horizontalOffset, selAnchor.getNextY() + verticalOffset, this._DISPLAY_SELECTED_ANCHOR_NEXT_RADIUS, 0, 2 * Math.PI, false);
867 ctx.fill(); 889 if (whichPoint & this._selectedSubpath.SEL_NEXT){
890 ctx.fillStyle = selHandleFill;
891 ctx.fill();
892 ctx.fillStyle = defFill;
893 }else {
894 ctx.fill();
895 }
868 ctx.stroke(); 896 ctx.stroke();
869 897
870 //selected anchor point 898 //selected anchor point
871 ctx.fillStyle = "#8ED6FF"; 899 var px = selAnchor.getPosX();
900 var py = selAnchor.getPosY();
872 ctx.beginPath(); 901 ctx.beginPath();
873 ctx.arc(selAnchor.getPosX() + horizontalOffset, selAnchor.getPosY() + verticalOffset, this._DISPLAY_SELECTED_ANCHOR_RADIUS, 0, 2 * Math.PI, false); 902 //ctx.arc(selAnchor.getPosX() + horizontalOffset, selAnchor.getPosY() + verticalOffset, this._DISPLAY_SELECTED_ANCHOR_RADIUS, 0, 2 * Math.PI, false);
903 ctx.moveTo(px-selAnchorDelta+horizontalOffset, py-selAnchorDelta+verticalOffset);
904 ctx.lineTo(px+selAnchorDelta+horizontalOffset, py-selAnchorDelta+verticalOffset);
905 ctx.lineTo(px+selAnchorDelta+horizontalOffset, py+selAnchorDelta+verticalOffset);
906 ctx.lineTo(px-selAnchorDelta+horizontalOffset, py+selAnchorDelta+verticalOffset);
907 ctx.closePath();
874 ctx.fill(); 908 ctx.fill();
875 ctx.stroke(); 909 ctx.stroke();
876 910
@@ -879,7 +913,12 @@ exports.PenTool = Montage.create(ShapeTool, {
879 ctx.lineWidth = 2; 913 ctx.lineWidth = 2;
880 ctx.strokeStyle = "red"; 914 ctx.strokeStyle = "red";
881 ctx.beginPath(); 915 ctx.beginPath();
882 ctx.arc(this._snapTarget.getPosX() + horizontalOffset, this._snapTarget.getPosY() + verticalOffset, this._DISPLAY_SELECTED_ANCHOR_RADIUS * 2, 0, 2 * Math.PI, false); 916 //ctx.arc(this._snapTarget.getPosX() + horizontalOffset, this._snapTarget.getPosY() + verticalOffset, this._DISPLAY_SELECTED_ANCHOR_RADIUS * 2, 0, 2 * Math.PI, false);
917 ctx.moveTo(px-selAnchorDelta+horizontalOffset, py-selAnchorDelta+verticalOffset);
918 ctx.lineTo(px+selAnchorDelta+horizontalOffset, py-selAnchorDelta+verticalOffset);
919 ctx.lineTo(px+selAnchorDelta+horizontalOffset, py+selAnchorDelta+verticalOffset);
920 ctx.lineTo(px-selAnchorDelta+horizontalOffset, py+selAnchorDelta+verticalOffset);
921 ctx.closePath();
883 ctx.stroke(); 922 ctx.stroke();
884 } 923 }
885 } //if this._selectedSubpath && subpath === this._selectedSubpath && this._selectedSubpath.getSelectedAnchorIndex()!== -1 924 } //if this._selectedSubpath && subpath === this._selectedSubpath && this._selectedSubpath.getSelectedAnchorIndex()!== -1
@@ -955,33 +994,64 @@ exports.PenTool = Montage.create(ShapeTool, {
955 994
956 handleDelete:{ 995 handleDelete:{
957 value: function(event){ 996 value: function(event){
958 //clear the selected subpath...the only new additions to this function w.r.t. ToolBase 997 var len = this.application.ninja.selectedElements.length;
959 if (this._selectedSubpath){ 998 if (len===0) {
960 if (this._selectedSubpath.getSelectedAnchorIndex()>=0){ 999 //clear the selected subpath...the only new additions to this function w.r.t. ToolBase
961 this._hoveredAnchorIndex=-1; 1000 if (this._selectedSubpath){
962 this._selectedSubpath.removeAnchor(this._selectedSubpath.getSelectedAnchorIndex()); 1001 if (this._selectedSubpath.getSelectedAnchorIndex()>=0){
963 this._selectedSubpath.createSamples(); 1002 this._hoveredAnchorIndex=-1;
964 //clear the canvas 1003 this._selectedSubpath.removeAnchor(this._selectedSubpath.getSelectedAnchorIndex());
965 this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas(); 1004 this._selectedSubpath.createSamples();
966 this.DrawSubpathAnchors(this._selectedSubpath); 1005 //clear the canvas
967 this.ShowSelectedSubpath(); 1006 this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas();
1007 this.DrawSubpathAnchors(this._selectedSubpath);
1008 this.ShowSelectedSubpath();
1009 }
1010 else {
1011 this._selectedSubpath.clearAllAnchors(); //perhaps unnecessary
1012 this._selectedSubpath = null;
1013 //clear the canvas
1014 this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas();
1015
1016 //undo/redo...go through ElementController and NJEvent
1017 var els = [];
1018 ElementController.removeElement(this._penCanvas);
1019 els.push(this._penCanvas);
1020 NJevent( "deleteSelection", els );
1021 this._penCanvas = null;
1022 }
1023 }
1024 //do nothing if there was no selected subpath and if there was no selection
1025 }
1026 else {
1027
1028 //undo/redo...go through ElementMediator (see ElementMediator.handleDeleting() from where the much of this function is copied)
1029 //clear the canvas