diff options
author | Pushkar Joshi | 2012-03-23 14:32:46 -0700 |
---|---|---|
committer | Pushkar Joshi | 2012-03-23 14:32:46 -0700 |
commit | 9b7dac9215fbd7c0fe7a80d3e8f1ff378332fec3 (patch) | |
tree | cf0cad815fe98ee8d493cbf42c4d8e13a3e0aaac /js/tools | |
parent | 92bc54df4acfec849568ab619150a5da49c087fa (diff) | |
download | ninja-9b7dac9215fbd7c0fe7a80d3e8f1ff378332fec3.tar.gz |
Almost working version of brush tool that uses only local coordinates to store the brush stroke points. Current version does not yet update the width and height of the brush stroke canvas upon changing the brush stroke through the PI. Also, current version does not obtain 3D position of points properly from the drawing tool base (see BrushTool _getUnsnappedPosition)
Diffstat (limited to 'js/tools')
-rw-r--r-- | js/tools/BrushTool.js | 116 |
1 files changed, 90 insertions, 26 deletions
diff --git a/js/tools/BrushTool.js b/js/tools/BrushTool.js index a135c1e5..f3c6773d 100644 --- a/js/tools/BrushTool.js +++ b/js/tools/BrushTool.js | |||
@@ -16,6 +16,9 @@ var snapManager = require("js/helper-classes/3D/snap-manager").SnapManager; | |||
16 | 16 | ||
17 | var BrushStroke = require("js/lib/geom/brush-stroke").BrushStroke; | 17 | var BrushStroke = require("js/lib/geom/brush-stroke").BrushStroke; |
18 | 18 | ||
19 | //whether or not we want the mouse move to be handled all the time (not just while drawing) inside the brush tool | ||
20 | var g_DoBrushToolMouseMove = true; | ||
21 | |||
19 | exports.BrushTool = Montage.create(ShapeTool, { | 22 | exports.BrushTool = Montage.create(ShapeTool, { |
20 | hasReel: { value: false }, | 23 | hasReel: { value: false }, |
21 | _toolID: { value: "brushTool" }, | 24 | _toolID: { value: "brushTool" }, |
@@ -36,6 +39,7 @@ exports.BrushTool = Montage.create(ShapeTool, { | |||
36 | //view options | 39 | //view options |
37 | _brushStrokeCanvas: {value: null, writable: true}, | 40 | _brushStrokeCanvas: {value: null, writable: true}, |
38 | _brushStrokePlaneMat: {value: null, writable: true}, | 41 | _brushStrokePlaneMat: {value: null, writable: true}, |
42 | _draggingPlane: {value: null, writable: true}, | ||
39 | 43 | ||
40 | //the current brush stroke | 44 | //the current brush stroke |
41 | _selectedBrushStroke: {value: null, writable: true}, | 45 | _selectedBrushStroke: {value: null, writable: true}, |
@@ -61,9 +65,8 @@ exports.BrushTool = Montage.create(ShapeTool, { | |||
61 | } | 65 | } |
62 | 66 | ||
63 | this.startDraw(event); | 67 | this.startDraw(event); |
64 | if (this._brushStrokePlaneMat === null) { | 68 | this._brushStrokePlaneMat = this.mouseDownHitRec.getPlaneMatrix(); |
65 | this._brushStrokePlaneMat = this.mouseDownHitRec.getPlaneMatrix(); | 69 | |
66 | } | ||
67 | //start a new brush stroke | 70 | //start a new brush stroke |
68 | if (this._selectedBrushStroke === null){ | 71 | if (this._selectedBrushStroke === null){ |
69 | this._selectedBrushStroke = new BrushStroke(); | 72 | this._selectedBrushStroke = new BrushStroke(); |
@@ -73,6 +76,7 @@ exports.BrushTool = Montage.create(ShapeTool, { | |||
73 | if (this.application.ninja.colorController.colorToolbar.fill.webGlColor){ | 76 | if (this.application.ninja.colorController.colorToolbar.fill.webGlColor){ |
74 | this._selectedBrushStroke.setSecondStrokeColor(this.application.ninja.colorController.colorToolbar.fill.webGlColor); | 77 | this._selectedBrushStroke.setSecondStrokeColor(this.application.ninja.colorController.colorToolbar.fill.webGlColor); |
75 | } | 78 | } |
79 | |||
76 | //add this point to the brush stroke in case the user does a mouse up before doing a mouse move | 80 | //add this point to the brush stroke in case the user does a mouse up before doing a mouse move |
77 | var currMousePos = this._getUnsnappedPosition(event.pageX, event.pageY); | 81 | var currMousePos = this._getUnsnappedPosition(event.pageX, event.pageY); |
78 | this._selectedBrushStroke.addPoint(currMousePos); | 82 | this._selectedBrushStroke.addPoint(currMousePos); |
@@ -114,7 +118,8 @@ exports.BrushTool = Montage.create(ShapeTool, { | |||
114 | } | 118 | } |
115 | 119 | ||
116 | } | 120 | } |
117 | NJevent("enableStageMove");//stageManagerModule.stageManager.enableMouseMove(); | 121 | if (!g_DoBrushToolMouseMove) |
122 | NJevent("enableStageMove");//stageManagerModule.stageManager.enableMouseMove(); | ||
118 | } //value: function (event) { | 123 | } //value: function (event) { |
119 | }, //HandleLeftButtonDown | 124 | }, //HandleLeftButtonDown |
120 | 125 | ||
@@ -129,7 +134,9 @@ exports.BrushTool = Montage.create(ShapeTool, { | |||
129 | snapManager.enableSnapAlign(false); | 134 | snapManager.enableSnapAlign(false); |
130 | 135 | ||
131 | var point = webkitConvertPointFromPageToNode(this.application.ninja.stage.canvas, new WebKitPoint(x,y)); | 136 | var point = webkitConvertPointFromPageToNode(this.application.ninja.stage.canvas, new WebKitPoint(x,y)); |
137 | //todo fix this function to allow us to get the correct location (in 3D) for the mouse position | ||
132 | var unsnappedpos = DrawingToolBase.getHitRecPos(snapManager.snap(point.x, point.y, false)); | 138 | var unsnappedpos = DrawingToolBase.getHitRecPos(snapManager.snap(point.x, point.y, false)); |
139 | this._draggingPlane = snapManager.getDragPlane(); | ||
133 | 140 | ||
134 | snapManager.enableElementSnap(elemSnap); | 141 | snapManager.enableElementSnap(elemSnap); |
135 | snapManager.enableGridSnap(gridSnap); | 142 | snapManager.enableGridSnap(gridSnap); |
@@ -150,13 +157,15 @@ exports.BrushTool = Montage.create(ShapeTool, { | |||
150 | return; | 157 | return; |
151 | } | 158 | } |
152 | 159 | ||
160 | var currMousePos = this._getUnsnappedPosition(event.pageX, event.pageY); | ||
153 | if (this._isDrawing) { | 161 | if (this._isDrawing) { |
154 | var currMousePos = this._getUnsnappedPosition(event.pageX, event.pageY); | ||
155 | if (this._selectedBrushStroke && this._selectedBrushStroke.getNumPoints()<1000){ | 162 | if (this._selectedBrushStroke && this._selectedBrushStroke.getNumPoints()<1000){ |
156 | this._selectedBrushStroke.addPoint(currMousePos); | 163 | this._selectedBrushStroke.addPoint(currMousePos); |
157 | } | 164 | } |
158 | this.ShowCurrentBrushStrokeOnStage(); | 165 | this.ShowCurrentBrushStrokeOnStage(); |
159 | } //if (this._isDrawing) { | 166 | } else { |
167 | this.ShowCurrentBrushIconOnStage(currMousePos); | ||
168 | } | ||
160 | 169 | ||
161 | //this.drawLastSnap(); //TODO.. is this line necessary if we're not snapping? // Required cleanup for both Draw/Feedbacks | 170 | //this.drawLastSnap(); //TODO.. is this line necessary if we're not snapping? // Required cleanup for both Draw/Feedbacks |
162 | 171 | ||
@@ -167,27 +176,69 @@ exports.BrushTool = Montage.create(ShapeTool, { | |||
167 | 176 | ||
168 | HandleLeftButtonUp: { | 177 | HandleLeftButtonUp: { |
169 | value: function (event) { | 178 | value: function (event) { |
170 | /*var drawData = this.getDrawingData(); | ||
171 | if (drawData) { | ||
172 | if (this._brushStrokePlaneMat === null) { | ||
173 | this._brushStrokePlaneMat = drawData.planeMat; | ||
174 | } | ||
175 | } | ||
176 | if (this._isDrawing) { | ||
177 | this.doDraw(event); | ||
178 | }*/ | ||
179 | this.endDraw(event); | 179 | this.endDraw(event); |
180 | 180 | ||
181 | this._isDrawing = false; | 181 | this._isDrawing = false; |
182 | this._hasDraw = false; | 182 | this._hasDraw = false; |
183 | 183 | ||
184 | 184 | //finish giving enough info. to the brush stroke | |
185 | this._selectedBrushStroke.setPlaneMatrix(this._brushStrokePlaneMat); | ||
186 | this._selectedBrushStroke.setPlaneMatrixInverse(glmat4.inverse(this._brushStrokePlaneMat,[])); | ||
187 | this._selectedBrushStroke.setDragPlane(this._draggingPlane); | ||
188 | |||
185 | //display the previously drawn stroke in a separate canvas | 189 | //display the previously drawn stroke in a separate canvas |
186 | this.RenderCurrentBrushStroke(); | 190 | this.RenderCurrentBrushStroke(); |
187 | 191 | ||
188 | this._selectedBrushStroke = null; | 192 | this._selectedBrushStroke = null; |
189 | this._brushStrokeCanvas = null; | 193 | this._brushStrokeCanvas = null; |
190 | NJevent("disableStageMove"); | 194 | if (!g_DoBrushToolMouseMove) |
195 | NJevent("disableStageMove"); | ||
196 | } | ||
197 | }, | ||
198 | |||
199 | ShowCurrentBrushIconOnStage:{ | ||
200 | value: function(currMousePos) { | ||
201 | //clear the canvas before we draw anything else | ||
202 | this.application.ninja.stage.clearDrawingCanvas(); | ||
203 | //display the brush icon of proper size (query the options bar) | ||
204 | var strokeSize = 1; | ||
205 | if (this.options.strokeSize) { | ||
206 | strokeSize = ShapesController.GetValueInPixels(this.options.strokeSize.value, this.options.strokeSize.units); | ||
207 | } | ||
208 | var useCalligraphic = false; | ||
209 | if (this.options.useCalligraphic){ | ||
210 | useCalligraphic = this.options.useCalligraphic; | ||
211 | } | ||
212 | var ctx = this.application.ninja.stage.drawingContext;//stageManagerModule.stageManager.drawingContext; | ||
213 | if (ctx === null) | ||
214 | throw ("null drawing context in Brushtool::ShowCurrentBrushStrokeOnStage"); | ||
215 | ctx.save(); | ||
216 | |||
217 | var horizontalOffset = this.application.ninja.stage.userContentLeft; | ||
218 | var verticalOffset = this.application.ninja.stage.userContentTop; | ||
219 | var halfStrokeWidth = 0.5*strokeSize; | ||
220 | ctx.beginPath(); | ||
221 | if (!useCalligraphic) { | ||
222 | //for round brushes, draw a circle at the current mouse position | ||
223 | ctx.arc(currMousePos[0] + horizontalOffset, currMousePos[1]+ verticalOffset, halfStrokeWidth, 0, 2 * Math.PI, false); | ||
224 | } else { | ||
225 | //draw an angled stroke to represent the brush tip | ||
226 | var strokeAngle = 0; | ||
227 | if (this.options.strokeAngle){ | ||
228 | strokeAngle= this.options.strokeAngle.value; | ||
229 | } | ||
230 | strokeAngle = Math.PI * strokeAngle/180; | ||
231 | var deltaDisplacement = [Math.cos(strokeAngle),Math.sin(strokeAngle)]; | ||
232 | deltaDisplacement = VecUtils.vecNormalize(2, deltaDisplacement, 1); | ||
233 | var startPos = VecUtils.vecSubtract(2, currMousePos, [-horizontalOffset+halfStrokeWidth*deltaDisplacement[0],-verticalOffset+halfStrokeWidth*deltaDisplacement[1]]); | ||
234 | ctx.moveTo(startPos[0], startPos[1]); | ||
235 | var endPos = VecUtils.vecAdd(2, startPos, [strokeSize*deltaDisplacement[0], strokeSize*deltaDisplacement[1]]); | ||
236 | ctx.lineTo(endPos[0], endPos[1]); | ||
237 | ctx.lineWidth = 2; | ||
238 | } | ||
239 | ctx.strokeStyle = "black"; | ||
240 | ctx.stroke(); | ||
241 | ctx.restore(); | ||
191 | } | 242 | } |
192 | }, | 243 | }, |
193 | 244 | ||
@@ -196,20 +247,16 @@ exports.BrushTool = Montage.create(ShapeTool, { | |||
196 | //clear the canvas before we draw anything else | 247 | //clear the canvas before we draw anything else |
197 | this.application.ninja.stage.clearDrawingCanvas(); | 248 | this.application.ninja.stage.clearDrawingCanvas(); |
198 | if (this._selectedBrushStroke && this._selectedBrushStroke.getNumPoints()>0){ | 249 | if (this._selectedBrushStroke && this._selectedBrushStroke.getNumPoints()>0){ |
199 | //this._selectedBrushStroke.computeMetaGeometry(); | ||
200 | var ctx = this.application.ninja.stage.drawingContext;//stageManagerModule.stageManager.drawingContext; | 250 | var ctx = this.application.ninja.stage.drawingContext;//stageManagerModule.stageManager.drawingContext; |
201 | if (ctx === null) | 251 | if (ctx === null) |
202 | throw ("null drawing context in Brushtool::ShowCurrentBrushStrokeOnStage"); | 252 | throw ("null drawing context in Brushtool::ShowCurrentBrushStrokeOnStage"); |
203 | ctx.save(); | 253 | ctx.save(); |
204 | |||
205 | var horizontalOffset = this.application.ninja.stage.userContentLeft; | 254 | var horizontalOffset = this.application.ninja.stage.userContentLeft; |
206 | var verticalOffset = this.application.ninja.stage.userContentTop; | 255 | var verticalOffset = this.application.ninja.stage.userContentTop; |
207 | var origX = -horizontalOffset; | 256 | var origX = -horizontalOffset; |
208 | var origY = -verticalOffset; | 257 | var origY = -verticalOffset; |
209 | this._selectedBrushStroke.drawToContext(ctx, origX, origY); | 258 | this._selectedBrushStroke.drawToContext(ctx, origX, origY, true); |
210 | |||
211 | ctx.restore(); | 259 | ctx.restore(); |
212 | |||
213 | } | 260 | } |
214 | } | 261 | } |
215 | }, | 262 | }, |
@@ -217,7 +264,20 @@ exports.BrushTool = Montage.create(ShapeTool, { | |||
217 | RenderCurrentBrushStroke:{ | 264 | RenderCurrentBrushStroke:{ |
218 | value: function() { | 265 | value: function() { |
219 | if (this._selectedBrushStroke){ | 266 | if (this._selectedBrushStroke){ |
220 | this._selectedBrushStroke.computeMetaGeometry(); | 267 | //DEBUGGING |
268 | /*var localData = this._selectedBrushStroke.buildLocalDataFromStageWorldCoord(); | ||
269 | var bboxWidth = localData[1]; | ||
270 | var bboxHeight = localData[2]; | ||
271 | var bboxMid = localData[0];*/ | ||
272 | this._selectedBrushStroke.init(); | ||
273 | var bboxWidth = this._selectedBrushStroke.getWidth(); |