diff options
author | Pushkar Joshi | 2012-04-19 09:40:39 -0700 |
---|---|---|
committer | Pushkar Joshi | 2012-04-19 09:40:39 -0700 |
commit | b1013db1b1a44d5fcd2e1a244d3c21c013d23e6e (patch) | |
tree | f00e8bb5f9dd3f7887dc8bdd18ff3e6fd5b0f662 | |
parent | a8123f065e7be7566a0588dd87ccac1cd59a0b8e (diff) | |
download | ninja-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-x | js/lib/geom/sub-path.js | 15 | ||||
-rwxr-xr-x | js/tools/PenTool.js | 49 |
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 | ||
279 | GLSubpath.prototype.setCanvasCenterLocalCoord = function(center){ | ||
280 | this._canvasCenterLocalCoord = center; | ||
281 | }; | ||
282 | |||
283 | GLSubpath.prototype.getCanvasCenterLocalCoord = function(){ | ||
284 | return this._canvasCenterLocalCoord; | ||
285 | }; | ||
286 | |||
277 | GLSubpath.prototype.getNumAnchors = function () { | 287 | GLSubpath.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 | }, |