aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPushkar Joshi2012-04-03 10:14:49 -0700
committerPushkar Joshi2012-04-03 10:14:49 -0700
commitc838f85d28acbf2fe208a4358aef9cac73b65fbc (patch)
treebe38feb3d6d54d39426504ee504a386377c1483a
parent878743cbbb75f2fc84855ca27779597b67ab1a95 (diff)
downloadninja-c838f85d28acbf2fe208a4358aef9cac73b65fbc.tar.gz
First attempt at preventing the drifting of the canvas due to floating point roundoff errors when constantly changing stroke width
-rwxr-xr-xjs/lib/geom/sub-path.js27
-rwxr-xr-xjs/tools/PenTool.js231
2 files changed, 133 insertions, 125 deletions
diff --git a/js/lib/geom/sub-path.js b/js/lib/geom/sub-path.js
index 19a1da3b..4ded360c 100755
--- a/js/lib/geom/sub-path.js
+++ b/js/lib/geom/sub-path.js
@@ -866,6 +866,27 @@ GLSubpath.prototype.getStrokeWidth = function () {
866 return this._strokeWidth; 866 return this._strokeWidth;
867}; 867};
868 868
869GLSubpath.prototype.translateSubpathPerCanvas = function(elemMediator){
870 //check if the canvas was translated
871 var penCanvasLeft = parseInt(elemMediator.getProperty(this._canvas, "left"));//parseFloat(DocumentControllerModule.DocumentController.GetElementStyle(this._penCanvas, "left"));
872 var penCanvasTop = parseInt(elemMediator.getProperty(this._canvas, "top"));//parseFloat(DocumentControllerModule.DocumentController.GetElementStyle(this._penCanvas, "top"));
873 var penCanvasWidth = parseInt(elemMediator.getProperty(this._canvas, "width"));//this._penCanvas.width;
874 var penCanvasHeight = parseInt(elemMediator.getProperty(this._canvas, "height"));//this._penCanvas.height;
875 var penCanvasOldX = penCanvasLeft + 0.5 * penCanvasWidth;
876 var penCanvasOldY = penCanvasTop + 0.5 * penCanvasHeight;
877
878 var translateCanvasX = penCanvasOldX - this._canvasX;
879 var translateCanvasY = penCanvasOldY - this._canvasY;
880
881 //update the canvasX and canvasY parameters for this subpath and also translate the subpath points (since they're stored in stage world space)
882 if (Math.abs(translateCanvasX)>=1 || Math.abs(translateCanvasY)>=1){
883 this.setCanvasX(translateCanvasX + this._canvasX);
884 this.setCanvasY(translateCanvasY + this._canvasY);
885 this.translateAnchors(translateCanvasX, translateCanvasY, 0);
886 }
887 this._dirty=true;
888};
889
869GLSubpath.prototype.setStrokeWidth = function (w) { 890GLSubpath.prototype.setStrokeWidth = function (w) {
870 var diffStrokeWidth = w-Math.floor(this._strokeWidth);//if positive, then stroke width grew, else shrunk 891 var diffStrokeWidth = w-Math.floor(this._strokeWidth);//if positive, then stroke width grew, else shrunk
871 if (diffStrokeWidth === 0) 892 if (diffStrokeWidth === 0)
@@ -874,11 +895,14 @@ GLSubpath.prototype.setStrokeWidth = function (w) {
874 this._strokeWidth = w; 895 this._strokeWidth = w;
875 this._dirty=true; 896 this._dirty=true;
876 897
898 var ElementMediator = require("js/mediators/element-mediator").ElementMediator;
899 this.translateSubpathPerCanvas(ElementMediator);
900
877 // **** adjust the left, top, width, and height to adjust for the change in stroke width **** 901 // **** adjust the left, top, width, and height to adjust for the change in stroke width ****
878 this.createSamples(); //dirty bit is checked here 902 this.createSamples(); //dirty bit is checked here
879 this.buildLocalCoord(); //local dirty bit is checked here 903 this.buildLocalCoord(); //local dirty bit is checked here
880 904
881 //build the width and height of this canvas by looking at local coordinates (X and Y needed only) 905 //build the width and height of this canvas by looking at local coordinates
882 var bboxMin = this.getLocalBBoxMin(); 906 var bboxMin = this.getLocalBBoxMin();
883 var bboxMax = this.getLocalBBoxMax(); 907 var bboxMax = this.getLocalBBoxMax();
884 var bboxWidth = bboxMax[0] - bboxMin[0]; 908 var bboxWidth = bboxMax[0] - bboxMin[0];
@@ -892,7 +916,6 @@ GLSubpath.prototype.setStrokeWidth = function (w) {
892 var top = Math.round(bboxMid[1] - 0.5 * bboxHeight); 916 var top = Math.round(bboxMid[1] - 0.5 * bboxHeight);
893 917
894 var canvasArray=[this._canvas]; 918 var canvasArray=[this._canvas];
895 var ElementMediator = require("js/mediators/element-mediator").ElementMediator;
896 ElementMediator.setProperty(canvasArray, "width", [bboxWidth+"px"], "Changing", "penTool");//canvas.width = w; 919 ElementMediator.setProperty(canvasArray, "width", [bboxWidth+"px"], "Changing", "penTool");//canvas.width = w;
897 ElementMediator.setProperty(canvasArray, "height", [bboxHeight+"px"], "Changing", "penTool");//canvas.height = h; 920 ElementMediator.setProperty(canvasArray, "height", [bboxHeight+"px"], "Changing", "penTool");//canvas.height = h;
898 ElementMediator.setProperty(canvasArray, "left", [left+"px"],"Changing", "penTool");//DocumentControllerModule.DocumentController.SetElementStyle(canvas, "left", parseInt(left) + "px"); 921 ElementMediator.setProperty(canvasArray, "left", [left+"px"],"Changing", "penTool");//DocumentControllerModule.DocumentController.SetElementStyle(canvas, "left", parseInt(left) + "px");
diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js
index 98423113..0dbefd16 100755
--- a/js/tools/PenTool.js
+++ b/js/tools/PenTool.js
@@ -393,22 +393,7 @@ exports.PenTool = Montage.create(ShapeTool, {
393 TranslateSelectedSubpathPerPenCanvas:{ 393 TranslateSelectedSubpathPerPenCanvas:{
394 value: function() { 394 value: function() {
395 if (this._penCanvas!==null) { 395 if (this._penCanvas!==null) {
396 //obtain the 2D translation of the canvas due to the Selection tool...assuming this is called in Configure 396 this._selectedSubpath.translateSubpathPerCanvas(ElementMediator);
397 var penCanvasLeft = parseInt(ElementMediator.getProperty(this._penCanvas, "left"));//parseFloat(DocumentControllerModule.DocumentController.GetElementStyle(this._penCanvas, "left"));
398 var penCanvasTop = parseInt(ElementMediator.getProperty(this._penCanvas, "top"));//parseFloat(DocumentControllerModule.DocumentController.GetElementStyle(this._penCanvas, "top"));
399 var penCanvasWidth = parseInt(ElementMediator.getProperty(this._penCanvas, "width"));//this._penCanvas.width;
400 var penCanvasHeight = parseInt(ElementMediator.getProperty(this._penCanvas, "height"));//this._penCanvas.height;
401 var penCanvasOldX = penCanvasLeft + 0.5 * penCanvasWidth;
402 var penCanvasOldY = penCanvasTop + 0.5 * penCanvasHeight;
403
404 var translateCanvasX = penCanvasOldX - this._selectedSubpath.getCanvasX();
405 var translateCanvasY = penCanvasOldY - this._selectedSubpath.getCanvasY();
406
407 //update the canvasX and canvasY parameters for this subpath and also translate the subpath points (since they're stored in stage world space)
408 this._selectedSubpath.setCanvasX(translateCanvasX + this._selectedSubpath.getCanvasX());
409 this._selectedSubpath.setCanvasY(translateCanvasY + this._selectedSubpath.getCanvasY());
410 this._selectedSubpath.translateAnchors(translateCanvasX, translateCanvasY, 0);
411 this._selectedSubpath.createSamples(); //updates the bounding box
412 } 397 }
413 } 398 }
414 }, 399 },
@@ -444,6 +429,113 @@ exports.PenTool = Montage.create(ShapeTool, {
444 } 429 }
445 }, 430 },
446 431
432 RenderShape: {
433 value: function (w, h, midPt, planeMat, canvas) {
434 if ((Math.floor(w) === 0) || (Math.floor(h) === 0)) {
435 return;
436 }
437
438 var left = Math.round(midPt[0] - 0.5 * w);
439 var top = Math.round(midPt[1] - 0.5 * h);
440
441 if (!canvas) {
442 var newCanvas = null;
443 newCanvas = NJUtils.makeNJElement("canvas", "Subpath", "shape", {"data-RDGE-id": NJUtils.generateRandom()}, true);
444 var elementModel = TagTool.makeElement(parseInt(w), parseInt(h), planeMat, midPt, newCanvas);
445 ElementMediator.addElement(newCanvas, elementModel.data, true);
446
447 // create all the GL stuff
448 var world = this.getGLWorld(newCanvas, this._useWebGL);//this.options.use3D);//this.CreateGLWorld(planeMat, midPt, newCanvas, this._useWebGL);//fillMaterial, strokeMaterial);
449 //store a reference to this newly created canvas
450 this._penCanvas = newCanvas;
451
452 var subpath = this._selectedSubpath; //new GLSubpath();
453 subpath.setWorld(world);
454 subpath.setCanvas(newCanvas);
455
456 world.addObject(subpath);
457 world.render();
458 //TODO this will not work if there are multiple shapes in the same canvas
459 newCanvas.elementModel.shapeModel.GLGeomObj = subpath;
460 newCanvas.elementModel.shapeModel.shapeCount++;
461 if(newCanvas.elementModel.shapeModel.shapeCount === 1)
462 {
463 newCanvas.elementModel.selection = "Subpath";
464 newCanvas.elementModel.pi = "SubpathPi";
465 newCanvas.elementModel.shapeModel.strokeSize = this.options.strokeSize.value + " " + this.options.strokeSize.units;
466 var strokeColor = subpath.getStrokeColor();
467 newCanvas.elementModel.shapeModel.stroke = strokeColor;
468 if(strokeColor) {
469 newCanvas.elementModel.shapeModel.border = this.application.ninja.colorController.colorToolbar.stroke;
470 }
471 newCanvas.elementModel.shapeModel.strokeMaterial = subpath.getStrokeMaterial();
472
473 newCanvas.elementModel.shapeModel.GLGeomObj = subpath;
474 newCanvas.elementModel.shapeModel.useWebGl = this.options.use3D;
475 }
476 else
477 {
478 // TODO - update the shape's info only. shapeModel will likely need an array of shapes.
479 }
480
481 //if(newCanvas.elementModel.isShape)
482 if (true)
483 {
484 this.application.ninja.selectionController.selectElement(newCanvas);
485 }
486 } //if (!canvas) {
487 else {
488
489 var world = null;
490 if (canvas.elementModel.shapeModel && canvas.elementModel.shapeModel.GLWorld) {
491 world = canvas.elementModel.shapeModel.GLWorld;
492 } else {
493 world = this.getGLWorld(canvas, this._useWebGL);//this.options.use3D);//this.CreateGLWorld(planeMat, midPt, canvas, this._useWebGL);//fillMaterial, strokeMaterial);
494 }
495
496 if (this._entryEditMode !== this.ENTRY_SELECT_CANVAS){
497 //update the left and top of the canvas element
498 var canvasArray=[canvas];
499 w= Math.round(w);
500 h = Math.round(h);
501 ElementMediator.setProperty(canvasArray, "width", [w+"px"], "Changing", "penTool");//canvas.width = w;
502 ElementMediator.setProperty(canvasArray, "height", [h+"px"], "Changing", "penTool");//canvas.height = h;
503
504 //var bboxMid = this._selectedSubpath.getLocalBBoxMidInStageWorld();
505 //left = Math.round(bboxMid[0] - 0.5 * w);
506 //top = Math.round(bboxMid[1] - 0.5 * h);
507
508 ElementMediator.setProperty(canvasArray, "left", [left+"px"],"Changing", "penTool");//DocumentControllerModule.DocumentController.SetElementStyle(canvas, "left", parseInt(left) + "px");
509 ElementMediator.setProperty(canvasArray, "top", [top + "px"],"Changing", "penTool");//DocumentControllerModule.DocumentController.SetElementStyle(canvas, "top", parseInt(top) + "px");
510
511 //update the viewport and projection to reflect the new canvas width and height (todo might be unnecessary since we don't use RDGE for now)
512 world.setViewportFromCanvas(canvas);
513 if (this._useWebGL){
514 var cam = world.renderer.cameraManager().getActiveCamera();
515 cam.setPerspective(world.getFOV(), world.getAspect(), world.getZNear(), world.getZFar());
516 }
517 }
518
519 var subpath = this._selectedSubpath;
520
521 subpath.setDrawingTool(this);
522 subpath.setWorld(world);
523
524 world.addIfNewObject(subpath);
525 world.render();
526
527 //TODO this will not work if there are multiple shapes in the same canvas
528 canvas.elementModel.shapeModel.GLGeomObj = subpath;
529
530 //if(newCanvas.elementModel.isShape)
531 if (true)
532 {
533 this.application.ninja.selectionController.selectElement(canvas);
534 }
535 } //else of if (!canvas) {
536 } //value: function (w, h, planeMat, midPt, canvas) {
537 }, //RenderShape: {
538
447 HandleLeftButtonUp: { 539 HandleLeftButtonUp: {
448 value: function (event) { 540 value: function (event) {
449 if (this._isAltDown) { 541 if (this._isAltDown) {
@@ -603,113 +695,6 @@ exports.PenTool = Montage.create(ShapeTool, {
603 } 695 }
604 }, 696 },
605 697
606 RenderShape: {
607 value: function (w, h, midPt, planeMat, canvas) {
608 if ((Math.floor(w) === 0) || (Math.floor(h) === 0)) {
609 return;
610 }
611
612 var left = Math.round(midPt[0] - 0.5 * w);
613 var top = Math.round(midPt[1] - 0.5 * h);
614
615 if (!canvas) {
616 var newCanvas = null;
617 newCanvas = NJUtils.makeNJElement("canvas", "Subpath", "shape", {"data-RDGE-id": NJUtils.generateRandom()}, true);
618 var elementModel = TagTool.makeElement(parseInt(w), parseInt(h), planeMat, midPt, newCanvas);
619 ElementMediator.addElement(newCanvas, elementModel.data, true);
620