aboutsummaryrefslogtreecommitdiff
path: root/js/tools/BrushTool.js
diff options
context:
space:
mode:
authorPushkar Joshi2012-03-23 14:32:46 -0700
committerPushkar Joshi2012-03-23 14:32:46 -0700
commit9b7dac9215fbd7c0fe7a80d3e8f1ff378332fec3 (patch)
treecf0cad815fe98ee8d493cbf42c4d8e13a3e0aaac /js/tools/BrushTool.js
parent92bc54df4acfec849568ab619150a5da49c087fa (diff)
downloadninja-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/BrushTool.js')
-rw-r--r--js/tools/BrushTool.js116
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
17var BrushStroke = require("js/lib/geom/brush-stroke").BrushStroke; 17var 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
20var g_DoBrushToolMouseMove = true;
21
19exports.BrushTool = Montage.create(ShapeTool, { 22exports.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();