aboutsummaryrefslogtreecommitdiff
path: root/js/tools/PenTool.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/tools/PenTool.js')
-rwxr-xr-xjs/tools/PenTool.js849
1 files changed, 412 insertions, 437 deletions
diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js
index 5145eb39..06aac46c 100755
--- a/js/tools/PenTool.js
+++ b/js/tools/PenTool.js
@@ -18,8 +18,6 @@ var ViewUtils = require("js/helper-classes/3D/view-utils").ViewUtils;
18var AnchorPoint = require("js/lib/geom/anchor-point").AnchorPoint; 18var AnchorPoint = require("js/lib/geom/anchor-point").AnchorPoint;
19var SubPath = require("js/lib/geom/sub-path").SubPath; 19var SubPath = require("js/lib/geom/sub-path").SubPath;
20 20
21//todo remove this global var
22var g_DoPenToolMouseMove = true;
23 21
24exports.PenTool = Montage.create(ShapeTool, { 22exports.PenTool = Montage.create(ShapeTool, {
25 23
@@ -35,14 +33,11 @@ exports.PenTool = Montage.create(ShapeTool, {
35 _parentNode: { enumerable: false, value: null, writable: true }, 33 _parentNode: { enumerable: false, value: null, writable: true },
36 _toolsPropertiesContainer: { enumerable: false, value: null, writable: true }, 34 _toolsPropertiesContainer: { enumerable: false, value: null, writable: true },
37 35
38 // Need to keep track of current mouse position for KEY modifiers event which do not have mouse coordinates 36 //set this to true if you want to keep making subpaths after closing current subpath (debugging only)
39 _currentX: { value: 0, writable: true }, 37 _makeMultipleSubpaths: { value: true, writable: true },
40 _currentY: { value: 0, writable: true },
41
42 //the subpaths are what is displayed on the screen currently, with _selectedSubpath being the active one currently being edited
43 _selectedSubpath: { value: null, writable: true },
44 _makeMultipleSubpaths: { value: true, writable: true }, //set this to true if you want to keep making subpaths after closing current subpath
45 38
39 //set this to false if you don't want the mouse move handler being called when the mouse is not down (debugging only)
40 _trackMouseMoveWhenUp: {value: true, writable: false},
46 41
47 //whether the user has held down the Alt key 42 //whether the user has held down the Alt key
48 _isAltDown: { value: false, writable: true }, 43 _isAltDown: { value: false, writable: true },
@@ -50,7 +45,8 @@ exports.PenTool = Montage.create(ShapeTool, {
50 //whether the user has held down the Esc key 45 //whether the user has held down the Esc key
51 _isEscapeDown: {value: false, writable: true }, 46 _isEscapeDown: {value: false, writable: true },
52 47
53 //whether we have just started a new path (set true in mousedown, and set false in mouse up 48 //whether we have just started a new path (may set true in mousedown, and always set false in mouse up
49 //todo this seems to be unnecessary
54 _isNewPath: {value: false, writable: true}, 50 _isNewPath: {value: false, writable: true},
55 51
56 //whether we have clicked one of the endpoints after entering the pen tool in ENTRY_SELECT_PATH edit mode 52 //whether we have clicked one of the endpoints after entering the pen tool in ENTRY_SELECT_PATH edit mode
@@ -59,22 +55,26 @@ exports.PenTool = Montage.create(ShapeTool, {
59 //when the user wants to place a selected anchor point on top of another point, this is the target where the point will be placed 55 //when the user wants to place a selected anchor point on top of another point, this is the target where the point will be placed
60 _snapTargetIndex: { value: -1, writable: true }, 56 _snapTargetIndex: { value: -1, writable: true },
61 57
62 //whether or not we're using webgl for drawing 58 //index of the anchor point that the user has hovered over
63 _useWebGL: {value: false, writable: false }, 59 _hoveredAnchorIndex: {value: -1, writable: true},
64 60
65 //the canvas created by the pen tool...this is grown or shrunk with the path (if the canvas was not already provided) 61 //whether or not we're using webgl for drawing (set to false until we have webgl-ready stroke and fill regions)
66 _penCanvas: { value: null, writable: true }, 62 _useWebGL: {value: false, writable: false },
67 63
68 //the plane matrix for the first click...so the entire path is on the same plane 64 //the _selectedSubpath is the active subpath currently being edited
69 _penPlaneMat: { value: null, writable: true }, 65 _selectedSubpath: { value: null, writable: true },
70 66
71 //the plane equation (in stage world space) for the current path being drawn 67 //the canvas for the selected subpath...this is grown or shrunk by the pen tool with the subpath (if the canvas was not already provided)
72 _dragPlane: {value: null, writable: true}, 68 _selectedSubpathCanvas: { value: null, writable: true },
73 69
74 //index of the anchor point that the user has hovered over 70 //the plane matrix for the first click...so the entire path is on the same plane
75 _hoveredAnchorIndex: {value: -1, writable: true}, 71 // todo this might be unnecessary as we can get this from element mediator (but that may be slow)
72 _selectedSubpathPlaneMat: { value: null, writable: true },
76 73
77 //constants used for picking points --- NOTE: these should be user-settable parameters 74 //the center of the subpath center in stageworld space
75 _selectedSubpathCanvasCenter: {value: null, writable: true},
76
77 //constants used for picking points --- todo: these should be user-settable parameters
78 _PICK_POINT_RADIUS: { value: 4, writable: false }, 78 _PICK_POINT_RADIUS: { value: 4, writable: false },
79 _DISPLAY_ANCHOR_RADIUS: { value: 5, writable: false }, 79 _DISPLAY_ANCHOR_RADIUS: { value: 5, writable: false },
80 _DISPLAY_SELECTED_ANCHOR_RADIUS: { value: 10, writable: false }, 80 _DISPLAY_SELECTED_ANCHOR_RADIUS: { value: 10, writable: false },
@@ -89,58 +89,46 @@ exports.PenTool = Montage.create(ShapeTool, {
89 EDIT_PREV_NEXT: { value: 8, writable: false }, 89 EDIT_PREV_NEXT: { value: 8, writable: false },
90 _editMode: { value: this.EDIT_NONE, writable: true }, 90 _editMode: { value: this.EDIT_NONE, writable: true },
91 91
92 //constants used for selection modes on entry to pen tool (mutually exclusive) 92 //constants used for selection modes on entry to pen tool (mutually exclusive i.e. cannot be OR-ed)
93 ENTRY_SELECT_NONE: { value: 0, writable: false}, 93 ENTRY_SELECT_NONE: { value: 0, writable: false},
94 ENTRY_SELECT_CANVAS: { value: 1, writable: false}, 94 ENTRY_SELECT_CANVAS: { value: 1, writable: false},
95 ENTRY_SELECT_PATH: { value: 2, writable: false}, 95 ENTRY_SELECT_PATH: { value: 2, writable: false},
96 _entryEditMode: {value: this.ENTRY_SELECT_NONE, writable: true}, 96 _entryEditMode: {value: this.ENTRY_SELECT_NONE, writable: true},
97 97
98 98
99 99 // get the stage world position corresponding to the (x,y) mouse event position by querying the snap manager
100 _getUnsnappedPosition: { 100 // but temporarily turning off all snapping
101 value: function(x,y){ 101 _getMouseEventPosition : {
102 value: function(x,y, getStageWorld, doSnap){
102 var elemSnap = snapManager.elementSnapEnabled(); 103 var elemSnap = snapManager.elementSnapEnabled();
103 var gridSnap = snapManager.gridSnapEnabled(); 104 var gridSnap = snapManager.gridSnapEnabled();
104 var alignSnap = snapManager.snapAlignEnabled(); 105 var alignSnap = snapManager.snapAlignEnabled();
105 106
106 snapManager.enableElementSnap(false); 107 if (!doSnap){
107 snapManager.enableGridSnap(false); 108 snapManager.enableElementSnap(false);
108 snapManager.enableSnapAlign(false); 109 snapManager.enableGridSnap(false);
110 snapManager.enableSnapAlign(false);
111 }
109 112
110 var point = webkitConvertPointFromPageToNode(this.application.ninja.stage.canvas, new WebKitPoint(x,y)); 113 var point = webkitConvertPointFromPageToNode(this.application.ninja.stage.canvas, new WebKitPoint(x,y));
111 var unsnappedpos = //snapManager.snap(point.x, point.y, false).calculateStageWorldPoint(); 114 var pos;
112 DrawingToolBase.getHitRecPos(snapManager.snap(point.x, point.y, false)); 115 if (getStageWorld){
113 this._dragPlane = snapManager.getDragPlane(); 116 pos = (snapManager.snap(point.x, point.y, false)).calculateStageWorldPoint();
117 } else {
118 pos = (snapManager.snap(point.x, point.y, false)).getScreenPoint();
119 }
120 var dragPlane = snapManager.getDragPlane();
114 121
115 snapManager.enableElementSnap(elemSnap); 122 if (!doSnap){
116 snapManager.enableGridSnap(gridSnap); 123 snapManager.enableElementSnap(elemSnap);
117 snapManager.enableSnapAlign(alignSnap); 124 snapManager.enableGridSnap(gridSnap);
125 snapManager.enableSnapAlign(alignSnap);
126 }
118 127
119 return unsnappedpos; 128 return [pos, dragPlane];
120 } 129 }
121 }, 130 },
122 131
123 _getUnsnappedScreenPosition: {
124 value: function(x,y){
125 var elemSnap = snapManager.elementSnapEnabled();
126 var gridSnap = snapManager.gridSnapEnabled();
127 var alignSnap = snapManager.snapAlignEnabled();
128
129 snapManager.enableElementSnap(false);
130 snapManager.enableGridSnap(false);
131 snapManager.enableSnapAlign(false);
132
133 var point = webkitConvertPointFromPageToNode(this.application.ninja.stage.canvas, new WebKitPoint(x,y));
134 var unsnappedpos = (snapManager.snap(point.x, point.y, false)).getScreenPoint();
135 this._dragPlane = snapManager.getDragPlane();
136
137 snapManager.enableElementSnap(elemSnap);
138 snapManager.enableGridSnap(gridSnap);
139 snapManager.enableSnapAlign(alignSnap);
140
141 return unsnappedpos;
142 }
143 },
144 ShowToolProperties: { 132 ShowToolProperties: {
145 value: function () { 133 value: function () {
146 this._penView = PenView.create(); 134 this._penView = PenView.create();
@@ -152,6 +140,43 @@ exports.PenTool = Montage.create(ShapeTool, {
152 140
153 }, 141 },
154 142
143 //use the snap manager to build a hit record corresponding to the screen X, Y position
144 // will use the plane of the selected path as the working plane if available, else use stage
145 getHitRecord:{
146 value: function(x,y){
147 var drawingCanvas = ViewUtils.getStageElement();
148 if (this._selectedSubpathCanvas){
149 drawingCanvas = this._selectedSubpathCanvas;
150 }
151 var contentPlane = ViewUtils.getUnprojectedElementPlane(drawingCanvas);
152 snapManager.pushWorkingPlane(contentPlane);
153 var tmpPoint = webkitConvertPointFromPageToNode(this.application.ninja.stage.canvas, new WebKitPoint(x,y));
154 var hitRec = snapManager.snap(tmpPoint.x, tmpPoint.y, false);
155 snapManager.popWorkingPlane();
156 return hitRec;
157 }
158 },
159
160 // **********************************************************************************************************
161 // Mouse down handler
162 // IF the selected subpath is null, it means we're going to start a new subpath
163 // Create a new subpath
164 // Compute the mouse position in stage world space (lying on stage or selected subpath canvas)
165 // IF selected subpath does not have a canvas yet,
166 // IF this is the first anchor point of the selected subpath
167 // Store the plane mat and drag plane of this hit record (will be used for creating a canvas)
168 // Add the mouse position (in stage world space) as an anchor point
169 // ELSE (we may add to the selected subpath)
170 // Compute the mouse position in local (selected subpath canvas) space
171 // IF we hit the path:
172 // Either select an anchor or insert an anchor and select it
173 // (also set proper flags when select endpoint of open path in ENTRY_SELECT_PATH mode)
174 // ELSE
175 // If selected subpath is closed (and we're not in ENTRY_SELECT_PATH mode)
176 // Create a new subpath
177 // Add the mouse position (in selected subpath's local space) as an anchor point (call global to local)
178 // Draw the selected subpath anchors and the selected subpath itself in the stage's context
179 // **********************************************************************************************************
155 HandleLeftButtonDown: 180 HandleLeftButtonDown:
156 { 181 {
157 value: function (event) { 182 value: function (event) {
@@ -160,118 +185,145 @@ exports.PenTool = Montage.create(ShapeTool, {
160 //NOTE: this will work on Webkit only...IE has different codes (left: 1, middle: 4, right: 2) 185 //NOTE: this will work on Webkit only...IE has different codes (left: 1, middle: 4, right: 2)
161 return; 186 return;
162 } 187 }
188