aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPushkar Joshi2012-04-19 09:40:39 -0700
committerPushkar Joshi2012-04-19 09:40:39 -0700
commitb1013db1b1a44d5fcd2e1a244d3c21c013d23e6e (patch)
treef00e8bb5f9dd3f7887dc8bdd18ff3e6fd5b0f662
parenta8123f065e7be7566a0588dd87ccac1cd59a0b8e (diff)
downloadninja-b1013db1b1a44d5fcd2e1a244d3c21c013d23e6e.tar.gz
store the canvas center (in local space) per each subpath, instead of tracking it by the pen tool. This fixes the bug where the canvas transform was incorrectly applied when the stroke width was changed
-rwxr-xr-xjs/lib/geom/sub-path.js15
-rwxr-xr-xjs/tools/PenTool.js49
2 files changed, 36 insertions, 28 deletions
diff --git a/js/lib/geom/sub-path.js b/js/lib/geom/sub-path.js
index 2ecafa1c..60335990 100755
--- a/js/lib/geom/sub-path.js
+++ b/js/lib/geom/sub-path.js
@@ -34,6 +34,8 @@ var GLSubpath = function GLSubpath() {
34 this._Anchors = []; 34 this._Anchors = [];
35 this._BBoxMin = [0, 0, 0]; 35 this._BBoxMin = [0, 0, 0];
36 this._BBoxMax = [0, 0, 0]; 36 this._BBoxMax = [0, 0, 0];
37 this._canvasCenterLocalCoord = [0,0,0];
38
37 this._isClosed = false; 39 this._isClosed = false;
38 40
39 this._Samples = []; //polyline representation of this curve in canvas space 41 this._Samples = []; //polyline representation of this curve in canvas space
@@ -274,6 +276,14 @@ GLSubpath.prototype.setIsClosed = function (isClosed) {
274 } 276 }
275}; 277};
276 278
279GLSubpath.prototype.setCanvasCenterLocalCoord = function(center){
280 this._canvasCenterLocalCoord = center;
281};
282
283GLSubpath.prototype.getCanvasCenterLocalCoord = function(){
284 return this._canvasCenterLocalCoord;
285};
286
277GLSubpath.prototype.getNumAnchors = function () { 287GLSubpath.prototype.getNumAnchors = function () {
278 return this._Anchors.length; 288 return this._Anchors.length;
279}; 289};
@@ -681,13 +691,16 @@ GLSubpath.prototype.setStrokeWidth = function (w) {
681 if (this._dirty){ 691 if (this._dirty){
682 this.createSamples(false); //this will also update the bounding box 692 this.createSamples(false); //this will also update the bounding box
683 } else{ 693 } else{
684 this.computeBoundingBox(false); 694 this.computeBoundingBox(true,false);
685 } 695 }
686 this.offsetPerBBoxMin(); //this will shift the local coordinates such that the bbox min point is at (0,0) 696 this.offsetPerBBoxMin(); //this will shift the local coordinates such that the bbox min point is at (0,0)
687 697
688 //figure out the adjustment to the canvas position and size 698 //figure out the adjustment to the canvas position and size
689 var delta = Math.round(diffStrokeWidth*0.5); 699 var delta = Math.round(diffStrokeWidth*0.5);
690 700
701 //update the canvas center (it's simply the center of the new bbox in this case)
702 this._canvasCenterLocalCoord = [0.5*(this._BBoxMax[0]+this._BBoxMin[0]),0.5*(this._BBoxMax[1]+this._BBoxMin[1]),0.5*(this._BBoxMax[2]+this._BBoxMin[2])];
703
691 //update the width, height, left and top 704 //update the width, height, left and top
692 var ElementMediator = require("js/mediators/element-mediator").ElementMediator; 705 var ElementMediator = require("js/mediators/element-mediator").ElementMediator;
693 var penCanvasCurrentWidth = parseInt(ElementMediator.getProperty(this._canvas, "width")); 706 var penCanvasCurrentWidth = parseInt(ElementMediator.getProperty(this._canvas, "width"));
diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js
index 7263bf52..765d4589 100755
--- a/js/tools/PenTool.js
+++ b/js/tools/PenTool.js
@@ -71,10 +71,6 @@ exports.PenTool = Montage.create(ShapeTool, {
71 // todo this might be unnecessary as we can get this from element mediator (but that may be slow) 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 }, 72 _selectedSubpathPlaneMat: { value: null, writable: true },
73 73
74 //bbox of the selected subpath in local coordinates
75 // (used for id-ing when the local center has shifted, i.e. the bbox of the subpath has grown)
76 _selectedSubpathLocalCenter: {value: null, writable: true},
77
78 //the center of the subpath center in stageworld space 74 //the center of the subpath center in stageworld space
79 _selectedSubpathCanvasCenter: {value: null, writable: true}, 75 _selectedSubpathCanvasCenter: {value: null, writable: true},
80 76
@@ -228,7 +224,6 @@ exports.PenTool = Montage.create(ShapeTool, {
228 this._selectedSubpath = new SubPath(); 224 this._selectedSubpath = new SubPath();
229 this._selectedSubpathCanvas = null; 225 this._selectedSubpathCanvas = null;
230 this._selectedSubpathPlaneMat = null; 226 this._selectedSubpathPlaneMat = null;
231 this._selectedSubpathLocalCenter = null;
232 this._isNewPath = true; 227 this._isNewPath = true;
233 228
234 if (this._entryEditMode === this.ENTRY_SELECT_PATH){ 229 if (this._entryEditMode === this.ENTRY_SELECT_PATH){
@@ -411,6 +406,9 @@ exports.PenTool = Montage.create(ShapeTool, {
411 return; 406 return;
412 } 407 }
413 408
409 if (!this._selectedSubpath ){
410 return; //nothing to do in case no subpath is selected
411 }
414 //clear the canvas before we draw anything else 412 //clear the canvas before we draw anything else
415 this.application.ninja.stage.clearDrawingCanvas(); 413 this.application.ninja.stage.clearDrawingCanvas();
416 this._hoveredAnchorIndex = -1; 414 this._hoveredAnchorIndex = -1;
@@ -426,16 +424,12 @@ exports.PenTool = Montage.create(ShapeTool, {
426 } 424 }
427 425
428 var hitRec = this.getHitRecord(event.pageX, event.pageY, false); 426 var hitRec = this.getHitRecord(event.pageX, event.pageY, false);
429 427 var drawingCanvas = this._selectedSubpath.getCanvas();
430 var drawingCanvas=null, globalMousePos=null, localMousePos=null; 428 if (!drawingCanvas){
431 if (this._selectedSubpath ){ 429 drawingCanvas = ViewUtils.getStageElement();
432 drawingCanvas = this._selectedSubpath.getCanvas();
433 if (!drawingCanvas){
434 drawingCanvas = ViewUtils.getStageElement();
435 }
436 globalMousePos = hitRec.getScreenPoint();
437 localMousePos = ViewUtils.globalToLocal(globalMousePos, drawingCanvas);
438 } 430 }
431 var globalMousePos = hitRec.getScreenPoint();
432 var localMousePos = ViewUtils.globalToLocal(globalMousePos, drawingCanvas);
439 433
440 if (this._isDrawing) { 434 if (this._isDrawing) {
441 //if there is a selected subpath with a selected anchor point 435 //if there is a selected subpath with a selected anchor point
@@ -768,16 +762,14 @@ exports.PenTool = Montage.create(ShapeTool, {
768 var bboxMid = VecUtils.vecInterpolate(3, bboxMin, bboxMax, 0.5); 762 var bboxMid = VecUtils.vecInterpolate(3, bboxMin, bboxMax, 0.5);
769 763
770 //sandwich the planeMat between with the translation to the previous center of the canvas in local space and its inverse 764 //sandwich the planeMat between with the translation to the previous center of the canvas in local space and its inverse
771 if (this._selectedSubpathLocalCenter) { 765 var centerDisp = VecUtils.vecSubtract(3, bboxMid, this._selectedSubpath.getCanvasCenterLocalCoord());
772 var centerDisp = VecUtils.vecSubtract(3, bboxMid, this._selectedSubpathLocalCenter); 766 var tMat = Matrix.Translation([centerDisp[0], centerDisp[1],centerDisp[2]]);
773 var tMat = Matrix.Translation([centerDisp[0], centerDisp[1],centerDisp[2]]); 767 var tInvMat = Matrix.Translation([-centerDisp[0], -centerDisp[1], -centerDisp[2]]);
774 var tInvMat = Matrix.Translation([-centerDisp[0], -centerDisp[1], -centerDisp[2]]); 768 var newMat = Matrix.I(4);
775 var newMat = Matrix.I(4); 769 glmat4.multiply( tInvMat, this._selectedSubpathPlaneMat, newMat);
776 glmat4.multiply( tInvMat, this._selectedSubpathPlaneMat, newMat); 770 glmat4.multiply( newMat, tMat, newMat);
777 glmat4.multiply( newMat, tMat, newMat); 771 this._selectedSubpathPlaneMat = newMat;
778 this._selectedSubpathPlaneMat = newMat; 772 ViewUtils.setMatrixForElement(this._selectedSubpathCanvas, newMat, true);
779 ViewUtils.setMatrixForElement(this._selectedSubpathCanvas, newMat, true);
780 }
781 773
782 var localToStageWorldMat = ViewUtils.getLocalToStageWorldMatrix(this._selectedSubpathCanvas, false, false); 774 var localToStageWorldMat = ViewUtils.getLocalToStageWorldMatrix(this._selectedSubpathCanvas, false, false);
783 this._selectedSubpathCanvasCenter = MathUtils.transformAndDivideHomogeneousPoint(bboxMid, localToStageWorldMat); 775 this._selectedSubpathCanvasCenter = MathUtils.transformAndDivideHomogeneousPoint(bboxMid, localToStageWorldMat);
@@ -810,11 +802,11 @@ exports.PenTool = Montage.create(ShapeTool, {
810 this._selectedSubpath.makeDirty(); 802 this._selectedSubpath.makeDirty();
811 this._selectedSubpath.createSamples(false); 803 this._selectedSubpath.createSamples(false);
812 this._selectedSubpath.offsetPerBBoxMin(); 804 this._selectedSubpath.offsetPerBBoxMin();
813 bboxMin = this._selectedSubpath.getBBoxMin();
814 bboxMax = this._selectedSubpath.getBBoxMax();
815 805
816 //compute and store the center of the bbox in local space 806 //compute and store the center of the bbox in local space
817 this._selectedSubpathLocalCenter = VecUtils.vecInterpolate(3, bboxMin, bboxMax, 0.5); 807 bboxMin = this._selectedSubpath.getBBoxMin();
808 bboxMax = this._selectedSubpath.getBBoxMax();
809 this._selectedSubpath.setCanvasCenterLocalCoord(VecUtils.vecInterpolate(3, bboxMin, bboxMax, 0.5));
818 } 810 }
819 }, 811 },
820 812
@@ -852,6 +844,9 @@ exports.PenTool = Montage.create(ShapeTool, {
852 this._selectedSubpathPlaneMat = null; 844 this._selectedSubpathPlaneMat = null;
853 this._snapTargetIndex = -1; 845 this._snapTargetIndex = -1;
854 this._selectedSubpath = null; 846 this._selectedSubpath = null;
847 if (this._entryEditMode === this.ENTRY_SELECT_PATH){
848 this._entryEditMode = this.ENTRY_SELECT_NONE;
849 }
855 this.application.ninja.stage.clearDrawingCanvas(); 850 this.application.ninja.stage.clearDrawingCanvas();
856 } 851 }
857 }, 852 },