From abeb9f1e23679200bb2f4a3ccbcebfb37645975c Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Thu, 9 Feb 2012 10:45:50 -0800 Subject: first phase of simple resampling to prevent tiny segments --- js/helper-classes/RDGE/GLBrushStroke.js | 54 +++++++++- js/tools/BrushTool.js | 170 ++++++++++++++++---------------- 2 files changed, 138 insertions(+), 86 deletions(-) diff --git a/js/helper-classes/RDGE/GLBrushStroke.js b/js/helper-classes/RDGE/GLBrushStroke.js index fdf1595c..59017a0c 100644 --- a/js/helper-classes/RDGE/GLBrushStroke.js +++ b/js/helper-classes/RDGE/GLBrushStroke.js @@ -67,7 +67,23 @@ function GLBrushStroke() { this.getNumPoints = function () { return this._Points.length; } this.getPoint = function (index) { return this._Points[index]; } - this.addPoint = function (anchorPt) { this._Points.push(anchorPt); this._dirty=true; } + this.addPoint = function (pt) + { + //add the point if it is some epsilon away from the previous point + var doAddPoint=true; + var numPoints = this._Points.length; + if (numPoints>0) { + var prevPt = this._Points[numPoints-1]; + var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; + var diffPtMag = diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]; + if (diffPtMag<4) + doAddPoint=false; + } + if (doAddPoint) { + this._Points.push(pt); + this._dirty=true; + } + } this.insertPoint = function(pt, index){ this._Points.splice(index, 0, pt); this._dirty=true;} this.isDirty = function(){return this._dirty;} this.makeDirty = function(){this._dirty=true;} @@ -167,7 +183,9 @@ function GLBrushStroke() { var bboxWidth = bboxMax[0] - bboxMin[0]; var bboxHeight = bboxMax[1] - bboxMin[1]; ctx.clearRect(0, 0, bboxWidth, bboxHeight); -/* + + + /* ctx.lineWidth = this._strokeWidth; ctx.strokeStyle = "black"; if (this._strokeColor) @@ -185,7 +203,35 @@ function GLBrushStroke() { ctx.lineTo(pt[0]-bboxMin[0], pt[1]-bboxMin[1]); } ctx.stroke(); - */ + */ + + var firstPt = this._Points[0]; + var prevX = firstPt[0]-bboxMin[0]; + var prevY = firstPt[1]-bboxMin[1]; + for (var i = 1; i < numPoints; i++) { + var pt = this._Points[i]; + ctx.globalCompositeOperation = 'source-over'; + var x = pt[0]-bboxMin[0]; + var y = pt[1]-bboxMin[1]; + var r = ctx.createLinearGradient(prevX, prevY, x, y); + r.addColorStop(1, 'rgba(0,0,0,0.01)'); + r.addColorStop(0.5,'rgba(255,0,0,1.0)'); + r.addColorStop(0, 'rgba(0,0,0,0.01)'); + + ctx.fillStyle = r; + //ctx.fillStyle = "rgba(0,128,0,0.15)"; + var w2 = this._strokeWidth*0.5; + ctx.moveTo(prevX-w2, prevY); + ctx.lineTo(prevX+w2, prevY); + ctx.lineTo(x+w2, y); + ctx.lineTo(x-w2, y); + ctx.fill(); + + prevX = x; + prevY = y; + } + + /* var R2 = this._strokeWidth; var R = R2*0.5; var hardness = 0.25; //for a pencil, this is always 1 //TODO get hardness parameter from user interface @@ -209,6 +255,8 @@ function GLBrushStroke() { //ctx.globalCompositeOperation = 'source-in'; //ctx.rect(x-R, y-R, R2, R2); } + */ + ctx.restore(); } //render() diff --git a/js/tools/BrushTool.js b/js/tools/BrushTool.js index ce8ffbb9..97df84a0 100644 --- a/js/tools/BrushTool.js +++ b/js/tools/BrushTool.js @@ -65,12 +65,30 @@ exports.BrushTool = Montage.create(ShapeTool, { if (this._selectedBrushStroke === null){ this._selectedBrushStroke = new GLBrushStroke(); } - console.log("BrushTool Start"); NJevent("enableStageMove");//stageManagerModule.stageManager.enableMouseMove(); } //value: function (event) { }, //HandleLeftButtonDown + _getUnsnappedPosition: { + value: function(x,y){ + var elemSnap = snapManager.elementSnapEnabled(); + var gridSnap = snapManager.gridSnapEnabled(); + var alignSnap = snapManager.snapAlignEnabled(); + snapManager.enableElementSnap(false); + snapManager.enableGridSnap(false); + snapManager.enableSnapAlign(false); + + var point = webkitConvertPointFromPageToNode(this.application.ninja.stage.canvas, new WebKitPoint(x,y)); + var unsnappedpos = DrawingToolBase.getHitRecPos(snapManager.snap(point.x, point.y, false)); + + snapManager.enableElementSnap(elemSnap); + snapManager.enableGridSnap(gridSnap); + snapManager.enableSnapAlign(alignSnap); + + return unsnappedpos; + } + }, //need to override this function because the ShapeTool's definition contains a clearDrawingCanvas call - Pushkar // might not need to override once we draw using OpenGL instead of SVG // Also took out all the snapping code for now...need to add that back @@ -84,20 +102,10 @@ exports.BrushTool = Montage.create(ShapeTool, { } if (this._isDrawing) { - snapManager.enableElementSnap(false); - snapManager.enableGridSnap(false); - snapManager.enableSnapAlign(false); - //this.doDraw(event); - //var currMousePos = this.getMouseUpPos(); - //instead of doDraw call own DrawingTool - var point = webkitConvertPointFromPageToNode(this.application.ninja.stage.canvas, new WebKitPoint(event.pageX, event.pageY)); - var hitRecSnapPoint = DrawingToolBase.getUpdatedSnapPointNoAppLevelEnabling(point.x, point.y, true, this.mouseDownHitRec); - var currMousePos = DrawingToolBase.getHitRecPos(hitRecSnapPoint); - + var currMousePos = this._getUnsnappedPosition(event.pageX, event.pageY); if (this._selectedBrushStroke){ this._selectedBrushStroke.addPoint(currMousePos); } - this.ShowCurrentBrushStrokeOnStage(); } //if (this._isDrawing) { @@ -123,7 +131,6 @@ exports.BrushTool = Montage.create(ShapeTool, { this._isDrawing = false; this._hasDraw = false; - console.log("BrushTool Stop"); //TODO get these values from the options if (this._selectedBrushStroke){ @@ -192,92 +199,89 @@ exports.BrushTool = Montage.create(ShapeTool, { RenderShape: { - value: function (w, h, planeMat, midPt, canvas) { - if ((Math.floor(w) === 0) || (Math.floor(h) === 0)) { - return; - } + value: function (w, h, planeMat, midPt, canvas) { + if ((Math.floor(w) === 0) || (Math.floor(h) === 0)) { + return; + } - var left = Math.round(midPt[0] - 0.5 * w); - var top = Math.round(midPt[1] - 0.5 * h); + var left = Math.round(midPt[0] - 0.5 * w); + var top = Math.round(midPt[1] - 0.5 * h); - if (!canvas) { - var newCanvas = NJUtils.makeNJElement("canvas", "Brushstroke", "shape", null, true); - var elementModel = TagTool.makeElement(w, h, planeMat, midPt, newCanvas); - ElementMediator.addElement(newCanvas, elementModel.data, true); + if (!canvas) { + var newCanvas = NJUtils.makeNJElement("canvas", "Brushstroke", "shape", null, true); + var elementModel = TagTool.makeElement(w, h, planeMat, midPt, newCanvas); + ElementMediator.addElement(newCanvas, elementModel.data, true); - // create all the GL stuff - var world = this.getGLWorld(newCanvas, this._useWebGL); - //store a reference to this newly created canvas - this._brushStrokeCanvas = newCanvas; + // create all the GL stuff + var world = this.getGLWorld(newCanvas, this._useWebGL); + //store a reference to this newly created canvas + this._brushStrokeCanvas = newCanvas; - var brushStroke = this._selectedBrushStroke; - if (brushStroke){ - brushStroke.setWorld(world); + var brushStroke = this._selectedBrushStroke; + if (brushStroke){ + brushStroke.setWorld(world); - brushStroke.setPlaneMatrix(planeMat); - var planeMatInv = glmat4.inverse( planeMat, [] ); - brushStroke.setPlaneMatrixInverse(planeMatInv); - brushStroke.setPlaneCenter(midPt); + brushStroke.setPlaneMatrix(planeMat); + var planeMatInv = glmat4.inverse( planeMat, [] ); + brushStroke.setPlaneMatrixInverse(planeMatInv); + brushStroke.setPlaneCenter(midPt); - world.addObject(brushStroke); - world.render(); - //TODO this will not work if there are multiple shapes in the same canvas - newCanvas.elementModel.shapeModel.GLGeomObj = brushStroke; - } - } //if (!canvas) { - else { - - var world = null; - if (canvas.elementModel.shapeModel && canvas.elementModel.shapeModel.GLWorld) { - world = canvas.elementModel.shapeModel.GLWorld; - } else { - world = this.getGLWorld(canvas, this._useWebGL);//this.options.use3D);//this.CreateGLWorld(planeMat, midPt, canvas, this._useWebGL);//fillMaterial, strokeMaterial); - } + world.addObject(brushStroke); + world.render(); + //TODO this will not work if there are multiple shapes in the same canvas + newCanvas.elementModel.shapeModel.GLGeomObj = brushStroke; + } + } //if (!canvas) { + else { + var world = null; + if (canvas.elementModel.shapeModel && canvas.elementModel.shapeModel.GLWorld) { + world = canvas.elementModel.shapeModel.GLWorld; + } else { + world = this.getGLWorld(canvas, this._useWebGL); + } - if (this._entryEditMode !== this.ENTRY_SELECT_CANVAS){ - //update the left and top of the canvas element - var canvasArray=[canvas]; - ElementMediator.setProperty(canvasArray, "left", [parseInt(left)+"px"],"Changing", "brushTool"); - ElementMediator.setProperty(canvasArray, "top", [parseInt(top) + "px"],"Changing", "brushTool"); - canvas.width = w; - canvas.height = h; - //update the viewport and projection to reflect the new canvas width and height - world.setViewportFromCanvas(canvas); - if (this._useWebGL){ - var cam = world.renderer.cameraManager().getActiveCamera(); - cam.setPerspective(world.getFOV(), world.getAspect(), world.getZNear(), world.getZFar()); + + if (this._entryEditMode !== this.ENTRY_SELECT_CANVAS){ + //update the left and top of the canvas element + var canvasArray=[canvas]; + ElementMediator.setProperty(canvasArray, "left", [parseInt(left)+"px"],"Changing", "brushTool"); + ElementMediator.setProperty(canvasArray, "top", [parseInt(top) + "px"],"Changing", "brushTool"); + canvas.width = w; + canvas.height = h; + //update the viewport and projection to reflect the new canvas width and height + world.setViewportFromCanvas(canvas); + if (this._useWebGL){ + var cam = world.renderer.cameraManager().getActiveCamera(); + cam.setPerspective(world.getFOV(), world.getAspect(), world.getZNear(), world.getZFar()); + } } - } - var brushStroke = this._selectedBrushStroke; + var brushStroke = this._selectedBrushStroke; - if (brushStroke){ - brushStroke.setDrawingTool(this); + if (brushStroke){ + brushStroke.setDrawingTool(this); - brushStroke.setPlaneMatrix(planeMat); - var planeMatInv = glmat4.inverse( planeMat, [] ); - brushStroke.setPlaneMatrixInverse(planeMatInv); - brushStroke.setPlaneCenter(midPt); + brushStroke.setPlaneMatrix(planeMat); + var planeMatInv = glmat4.inverse( planeMat, [] ); + brushStroke.setPlaneMatrixInverse(planeMatInv); + brushStroke.setPlaneCenter(midPt); - brushStroke.setWorld(world); - world.addIfNewObject(brushStroke); - //world.addObject(subpath); - world.render(); - //TODO this will not work if there are multiple shapes in the same canvas - canvas.elementModel.shapeModel.GLGeomObj = brushStroke; - } - } //else of if (!canvas) { - } //value: function (w, h, planeMat, midPt, canvas) { - }, //RenderShape: { + brushStroke.setWorld(world); + world.addIfNewObject(brushStroke); + //world.addObject(subpath); + world.render(); + //TODO this will not work if there are multiple shapes in the same canvas + canvas.elementModel.shapeModel.GLGeomObj = brushStroke; + } + } //else of if (!canvas) { + } //value: function (w, h, planeMat, midPt, canvas) { + }, //RenderShape: { + Configure: { value: function (wasSelected) { if (wasSelected) { - console.log("Picked BrushTool"); - //todo these calls have no effect because the drawing-tool-base (in getInitialSnapPoint) overrides them with what's set at the application level - snapManager.enableElementSnap(false); - snapManager.enableGridSnap(false); - snapManager.enableSnapAlign(false); + console.log("Entered BrushTool"); } else { console.log("Left BrushTool"); -- cgit v1.2.3 From fcb12cc09eb3cd3b42bd215877ba18f449275b75 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Fri, 10 Feb 2012 14:16:56 -0800 Subject: render the brush stroke as a sequence of rectangles, with each rectangle having its own linear gradient --- js/helper-classes/RDGE/GLBrushStroke.js | 78 ++++++++++++++++++++++++++++----- 1 file changed, 66 insertions(+), 12 deletions(-) diff --git a/js/helper-classes/RDGE/GLBrushStroke.js b/js/helper-classes/RDGE/GLBrushStroke.js index 59017a0c..8fb6ab25 100644 --- a/js/helper-classes/RDGE/GLBrushStroke.js +++ b/js/helper-classes/RDGE/GLBrushStroke.js @@ -76,7 +76,7 @@ function GLBrushStroke() { var prevPt = this._Points[numPoints-1]; var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; var diffPtMag = diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]; - if (diffPtMag<4) + if (diffPtMag<16)//TODO hook this up to the variable that measures flow/wetness of the paint brush...a smaller number-> more samples doAddPoint=false; } if (doAddPoint) { @@ -184,7 +184,6 @@ function GLBrushStroke() { var bboxHeight = bboxMax[1] - bboxMin[1]; ctx.clearRect(0, 0, bboxWidth, bboxHeight); - /* ctx.lineWidth = this._strokeWidth; ctx.strokeStyle = "black"; @@ -205,31 +204,87 @@ function GLBrushStroke() { ctx.stroke(); */ - var firstPt = this._Points[0]; - var prevX = firstPt[0]-bboxMin[0]; - var prevY = firstPt[1]-bboxMin[1]; + var isDebug = false; + var prevPt = this._Points[0]; + var prevX = prevPt[0]-bboxMin[0]; + var prevY = prevPt[1]-bboxMin[1]; + prevPt = [prevX,prevY]; for (var i = 1; i < numPoints; i++) { var pt = this._Points[i]; ctx.globalCompositeOperation = 'source-over'; var x = pt[0]-bboxMin[0]; var y = pt[1]-bboxMin[1]; - var r = ctx.createLinearGradient(prevX, prevY, x, y); - r.addColorStop(1, 'rgba(0,0,0,0.01)'); - r.addColorStop(0.5,'rgba(255,0,0,1.0)'); - r.addColorStop(0, 'rgba(0,0,0,0.01)'); + pt = [x,y]; - ctx.fillStyle = r; - //ctx.fillStyle = "rgba(0,128,0,0.15)"; + //vector from prev to current pt + var seg = VecUtils.vecSubtract(2, pt, prevPt); + var segDir = VecUtils.vecNormalize(2, seg, 1.0); + + var segMidPt = VecUtils.vecInterpolate(2, pt, prevPt, 0.5); var w2 = this._strokeWidth*0.5; + var segDirOrtho = [w2*segDir[1], -w2*segDir[0]]; + + //add half the strokewidth to the segMidPt + var lgStart = VecUtils.vecAdd(2, segMidPt, segDirOrtho); + var lgEnd = VecUtils.vecSubtract(2, segMidPt, segDirOrtho); + + ctx.save(); + ctx.beginPath(); + + if (isDebug) { + ctx.strokeStyle="black"; + ctx.lineWidth = 1; + + ctx.moveTo(lgStart[0], lgStart[1]); + ctx.lineTo(lgEnd[0], lgEnd[1]); + ctx.stroke(); + } + + var lg = ctx.createLinearGradient(lgStart[0], lgStart[1], lgEnd[0], lgEnd[1]); + lg.addColorStop(1, 'rgba(0,0,0,0.0)'); + lg.addColorStop(0.5,'rgba(255,0,0,1.0)'); + lg.addColorStop(0, 'rgba(0,0,0,0.0)'); + ctx.fillStyle = lg; + + if (isDebug){ + ctx.strokeStyle="blue"; + ctx.lineWidth=0.5; + } ctx.moveTo(prevX-w2, prevY); ctx.lineTo(prevX+w2, prevY); ctx.lineTo(x+w2, y); ctx.lineTo(x-w2, y); + ctx.lineTo(prevX-w2, prevY); ctx.fill(); + ctx.closePath(); + ctx.restore(); + + prevPt = pt; prevX = x; prevY = y; } + + + if (isDebug) + ctx.stroke(); + + if (isDebug){ + //draw the skeleton of this stroke + ctx.lineWidth = 1; + ctx.strokeStyle = "black"; + var pt = this._Points[0]; + ctx.beginPath(); + ctx.moveTo(pt[0]-bboxMin[0],pt[1]-bboxMin[1]); + for (var i = 1; i < numPoints; i++) { + pt = this._Points[i]; + var x = pt[0]-bboxMin[0]; + var y = pt[1]-bboxMin[1]; + ctx.lineTo(x,y); + } + ctx.stroke(); + } + /* var R2 = this._strokeWidth; @@ -256,7 +311,6 @@ function GLBrushStroke() { //ctx.rect(x-R, y-R, R2, R2); } */ - ctx.restore(); } //render() -- cgit v1.2.3 From 209e0781e926212bbaaad9e8ca4b61a0c389b30f Mon Sep 17 00:00:00 2001 From: Nivesh Rajbhandari Date: Tue, 28 Feb 2012 17:19:42 -0800 Subject: We need to remove color buttons from the color model when updating the PI for selection change. Signed-off-by: Nivesh Rajbhandari --- js/components/ui/color-chip.reel/color-chip.js | 15 +++++++++++++++ js/panels/properties/content.reel/content.js | 22 ++++++++++++++++++++++ .../color-select.reel/color-select.html | 4 +++- .../custom-rows/color-select.reel/color-select.js | 21 +++++++++++++++++++++ .../properties/sections/custom.reel/custom.js | 5 +++++ 5 files changed, 66 insertions(+), 1 deletion(-) diff --git a/js/components/ui/color-chip.reel/color-chip.js b/js/components/ui/color-chip.reel/color-chip.js index ed1ac27a..7a7411da 100755 --- a/js/components/ui/color-chip.reel/color-chip.js +++ b/js/components/ui/color-chip.reel/color-chip.js @@ -92,6 +92,21 @@ var ColorChip = exports.ColorChip = Montage.create(Component, { this.changeDelegate(evt); } } + }, + + destroy: { + value: function() { + this.application.ninja.colorController.removeButton(this.mode, this.chipBtn); + var mode = this.mode; + if(this.iconType) { + if(this.iconType === "fillIcon") { + mode = "fill"; + } else if(this.iconType === "strokeIcon") { + mode = "stroke"; + } + } + this.application.ninja.colorController.removeButton(mode, this.icon); + } } }); diff --git a/js/panels/properties/content.reel/content.js b/js/panels/properties/content.reel/content.js index 8fa33a75..58c37db4 100755 --- a/js/panels/properties/content.reel/content.js +++ b/js/panels/properties/content.reel/content.js @@ -156,6 +156,17 @@ exports.Content = Montage.create(Component, { this.positionSize.widthSize = parseFloat(ElementsMediator.getProperty(stage, "width")); if(this.customPi !== stage.elementModel.pi) { + // We need to unregister color chips from the previous selection from the Color Model + var len = this.customSections.length; + for(var n = 0, controls; n < len; n++) { + controls = this.customSections[n].content.controls; + if(controls["colorSelect"]) { + controls["colorSelect"].destroy(); + } else if(controls["stageBackground"]) { + controls["stageBackground"].destroy(); + } + } + this.customPi = stage.elementModel.pi; this.displayCustomProperties(stage, stage.elementModel.pi); } @@ -221,6 +232,17 @@ exports.Content = Montage.create(Component, { // Custom Section if(this.customPi !== el.elementModel.pi) { + // We need to unregister color chips from the previous selection from the Color Model + var len = this.customSections.length; + for(var n = 0, controls; n < len; n++) { + controls = this.customSections[n].content.controls; + if(controls["colorSelect"]) { + controls["colorSelect"].destroy(); + } else if(controls["stageBackground"]) { + controls["stageBackground"].destroy(); + } + } + this.customPi = el.elementModel.pi; this.displayCustomProperties(el, el.elementModel.pi); } diff --git a/js/panels/properties/sections/custom-rows/color-select.reel/color-select.html b/js/panels/properties/sections/custom-rows/color-select.reel/color-select.html index 9c2588b9..96cc4de7 100755 --- a/js/panels/properties/sections/custom-rows/color-select.reel/color-select.html +++ b/js/panels/properties/sections/custom-rows/color-select.reel/color-select.html @@ -14,7 +14,9 @@ "properties" : { "element" : {"#": "section"}, "Stroke" : {"#": "Stroke"}, - "Fill" : {"#": "Fill"} + "Fill" : {"#": "Fill"}, + "strokeChip" : {"@": "colorChip"}, + "fillChip" : {"@": "colorChip2"} } }, diff --git a/js/panels/properties/sections/custom-rows/color-select.reel/color-select.js b/js/panels/properties/sections/custom-rows/color-select.reel/color-select.js index 60f8efef..3e81ff67 100755 --- a/js/panels/properties/sections/custom-rows/color-select.reel/color-select.js +++ b/js/panels/properties/sections/custom-rows/color-select.reel/color-select.js @@ -17,6 +17,14 @@ exports.ColorSelect = Montage.create(Component, { value: null }, + strokeChip: { + value: null + }, + + fillChip: { + value: null + }, + handleChange: { value: function(e) { @@ -57,6 +65,19 @@ exports.ColorSelect = Montage.create(Component, { // } } + }, + + destroy: { + value: function() { + if(this.strokeChip) + { + this.strokeChip.destroy(); + } + if(this.fillChip) + { + this.fillChip.destroy(); + } + } } }); \ No newline at end of file diff --git a/js/panels/properties/sections/custom.reel/custom.js b/js/panels/properties/sections/custom.reel/custom.js index a2b9b9fa..a537d323 100755 --- a/js/panels/properties/sections/custom.reel/custom.js +++ b/js/panels/properties/sections/custom.reel/custom.js @@ -59,6 +59,8 @@ exports.CustomSection = Montage.create(Component, { if(obj1.visible === false) tmpRow.colorVisible = obj1.visible; if(obj2.visible === false) tmpRow.color2Visible = obj2.visible; + // TODO - Hack for now to reference the color select object to unregister color chips + this.controls["colorSelect"] = tmpRow; } else { @@ -344,6 +346,9 @@ exports.CustomSection = Montage.create(Component, { this.controls[aField.id] = obj; + // TODO - Hack for now to reference the color select object to unregister color chips + this.controls["stageBackground"] = obj; + return obj; } } -- cgit v1.2.3 From d417b3315f1aa6dd52fea10cbf5f17a213ef8726 Mon Sep 17 00:00:00 2001 From: Nivesh Rajbhandari Date: Wed, 29 Feb 2012 06:50:51 -0800 Subject: SnapManager fixes for sag tags. Signed-off-by: Nivesh Rajbhandari --- js/helper-classes/3D/snap-manager.js | 6 ++++-- js/helper-classes/3D/view-utils.js | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/js/helper-classes/3D/snap-manager.js b/js/helper-classes/3D/snap-manager.js index 94202dc5..372be345 100755 --- a/js/helper-classes/3D/snap-manager.js +++ b/js/helper-classes/3D/snap-manager.js @@ -597,7 +597,8 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { } // TODO - Don't traverse components' children - if(elt.elementModel && elt.elementModel.isComponent) +// if(elt.elementModel && elt.elementModel.isComponent) + if(elt.nodeName.toLowerCase() === "svg" || (elt.elementModel && (elt.elementModel.isComponent || (elt.elementModel.selection === "SVG")))) { return; } @@ -1007,7 +1008,8 @@ var SnapManager = exports.SnapManager = Montage.create(Component, { } // TODO - Don't traverse components' children - if(elt.elementModel && elt.elementModel.isComponent) +// if(elt.elementModel && elt.elementModel.isComponent) + if(elt.nodeName.toLowerCase() === "svg" || (elt.elementModel && (elt.elementModel.isComponent || (elt.elementModel.selection === "SVG")))) { return; } diff --git a/js/helper-classes/3D/view-utils.js b/js/helper-classes/3D/view-utils.js index bedda8bf..c1f59397 100755 --- a/js/helper-classes/3D/view-utils.js +++ b/js/helper-classes/3D/view-utils.js @@ -580,7 +580,8 @@ exports.ViewUtils = Montage.create(Component, { if (elt.style.height) h = MathUtils.styleToNumber(elt.style.height); } - if (elt instanceof SVGSVGElement) { +// if (elt instanceof SVGSVGElement) { + if(elt.nodeName.toLowerCase() === "svg") { if(w instanceof SVGAnimatedLength) w = w.animVal.value; if(h instanceof SVGAnimatedLength) -- cgit v1.2.3 From f931c48a7d0bcf1222cf05787e3294839ed0b9fb Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Wed, 29 Feb 2012 09:47:41 -0800 Subject: resample the brush stroke so we don't have gaps if the path is drawn rapidly, and, allow to change the stroke color, and, more efficient stroke rendering by drawing translated radial gradients (instead of creating new gradients for each stroke sample) --- js/helper-classes/RDGE/GLBrushStroke.js | 74 ++++++++++++++++++++++++++------- js/tools/BrushTool.js | 12 +++--- 2 files changed, 65 insertions(+), 21 deletions(-) diff --git a/js/helper-classes/RDGE/GLBrushStroke.js b/js/helper-classes/RDGE/GLBrushStroke.js index 8fb6ab25..52ac79f5 100755 --- a/js/helper-classes/RDGE/GLBrushStroke.js +++ b/js/helper-classes/RDGE/GLBrushStroke.js @@ -34,6 +34,9 @@ function GLBrushStroke() { this._strokeMaterial; this._strokeStyle = "Solid"; + //the wetness of the brush (currently this is multiplied to the square of the stroke width, but todo should be changed + this._WETNESS_FACTOR = 0.010625;//0.0625; + //drawing context this._world = null; @@ -69,21 +72,23 @@ function GLBrushStroke() { this.getPoint = function (index) { return this._Points[index]; } this.addPoint = function (pt) { - //add the point if it is some epsilon away from the previous point - var doAddPoint=true; + //add the point only if it is some epsilon away from the previous point var numPoints = this._Points.length; if (numPoints>0) { + var threshold = this._WETNESS_FACTOR*this._strokeWidth*this._strokeWidth; var prevPt = this._Points[numPoints-1]; var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; var diffPtMag = diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]; - if (diffPtMag<16)//TODO hook this up to the variable that measures flow/wetness of the paint brush...a smaller number-> more samples - doAddPoint=false; - } - if (doAddPoint) { + if (diffPtMag>threshold){ + this._Points.push(pt); + this._dirty=true; + } + }else{ this._Points.push(pt); this._dirty=true; } } + this.insertPoint = function(pt, index){ this._Points.splice(index, 0, pt); this._dirty=true;} this.isDirty = function(){return this._dirty;} this.makeDirty = function(){this._dirty=true;} @@ -127,10 +132,39 @@ function GLBrushStroke() { this.computeMetaGeometry = function(){ if (this._dirty){ + var numPoints = this._Points.length; + + //**** add samples to the path if needed...linear interpolation for now + if (numPoints>1) { + var threshold = this._WETNESS_FACTOR*this._strokeWidth*this._strokeWidth; + var prevPt = this._Points[0]; + var prevIndex = 0; + for (var i=1;ithreshold){ + //insert points along the prev. to current point + var numNewPoints = Math.floor(distance/threshold); + for (var j=0;j0){ - this._selectedBrushStroke.computeMetaGeometry(); + //this._selectedBrushStroke.computeMetaGeometry(); var ctx = this.application.ninja.stage.drawingContext;//stageManagerModule.stageManager.drawingContext; if (ctx === null) throw ("null drawing context in Brushtool::ShowCurrentBrushStrokeOnStage"); -- cgit v1.2.3 From 795329d2225ff3b760f7f0ea3bb6b5e68f6c6b5b Mon Sep 17 00:00:00 2001 From: Jose Antonio Marquez Date: Wed, 29 Feb 2012 10:07:53 -0800 Subject: Making class level url template variable Created a class level variable for the URL to be parsed out of the user files. --- js/mediators/io-mediator.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/js/mediators/io-mediator.js b/js/mediators/io-mediator.js index 6b26668b..e763c67c 100644 --- a/js/mediators/io-mediator.js +++ b/js/mediators/io-mediator.js @@ -38,6 +38,12 @@ exports.IoMediator = Montage.create(Component, { pio: { enumerable: false, value: ProjectIo + }, + //////////////////////////////////////////////////////////////////// + // + appTemplatesUrl: { + enumerable: false, + value: new RegExp(chrome.extension.getURL('js/document/templates/montage-html/'), 'gi') }, //////////////////////////////////////////////////////////////////// // @@ -209,8 +215,7 @@ exports.IoMediator = Montage.create(Component, { template.document.content.document.head.innerHTML = template.head; //Getting all CSS (style or link) tags var styletags = template.document.content.document.getElementsByTagName('style'), - linktags = template.document.content.document.getElementsByTagName('link'), - url = new RegExp(chrome.extension.getURL('js/document/templates/montage-html/'), 'gi'); //TODO: Make public into var + linktags = template.document.content.document.getElementsByTagName('link'); //Looping through link tags and removing file recreated elements for (var j in styletags) { if (styletags[j].getAttribute) { @@ -345,7 +350,7 @@ exports.IoMediator = Montage.create(Component, { webgltag.innerHTML = json; } // - return this.getPrettyHtml(template.document.content.document.documentElement.outerHTML.replace(url, '')); + return this.getPrettyHtml(template.document.content.document.documentElement.outerHTML.replace(this.appTemplatesUrl, '')); } }, //////////////////////////////////////////////////////////////////// @@ -354,7 +359,7 @@ exports.IoMediator = Montage.create(Component, { enumerable: false, value: function (list) { //Variable to store CSS definitions - var i, str, url, css = ''; + var i, str, css = ''; //Looping through list if (list && list.length > 0) { //Adding each list item to string and also adding breaks @@ -362,10 +367,8 @@ exports.IoMediator = Montage.create(Component, { css += list[i].cssText; } } - //TODO: Add better logic for creating this string - url = new RegExp(chrome.extension.getURL('js/document/templates/montage-html/'), 'gi'); //Returning the CSS string - return this.getPrettyCss(css.replace(url, '')); + return this.getPrettyCss(css.replace(this.appTemplatesUrl, '')); } }, //////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From f000a3cced9adbfff1d7aa641e6eb42ad6edf7e8 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Wed, 29 Feb 2012 10:21:06 -0800 Subject: change in comment only --- js/helper-classes/RDGE/GLBrushStroke.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/helper-classes/RDGE/GLBrushStroke.js b/js/helper-classes/RDGE/GLBrushStroke.js index 52ac79f5..f63bcc8a 100755 --- a/js/helper-classes/RDGE/GLBrushStroke.js +++ b/js/helper-classes/RDGE/GLBrushStroke.js @@ -34,7 +34,7 @@ function GLBrushStroke() { this._strokeMaterial; this._strokeStyle = "Solid"; - //the wetness of the brush (currently this is multiplied to the square of the stroke width, but todo should be changed + //the wetness of the brush (currently this is multiplied to the square of the stroke width, but todo should be changed to not depend on stroke width entirely this._WETNESS_FACTOR = 0.010625;//0.0625; //drawing context -- cgit v1.2.3 From bb3e42b531848b400670df6caf0f3ce02adf1243 Mon Sep 17 00:00:00 2001 From: Jose Antonio Marquez Date: Wed, 29 Feb 2012 11:28:58 -0800 Subject: Fix: Caching issue with chrome tab API Using window.open to test movie. --- js/document/html-document.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/js/document/html-document.js b/js/document/html-document.js index 6853f4d7..60eecc59 100755 --- a/js/document/html-document.js +++ b/js/document/html-document.js @@ -649,7 +649,8 @@ exports.HTMLDocument = Montage.create(TextDocument, { //TODO: Add logic to handle save before preview this.saveAll(); //Launching 'blank' tab for testing movie - chrome.tabs.create({url: this.application.ninja.coreIoApi.rootUrl+this.application.ninja.documentController._activeDocument.uri.split(this.application.ninja.coreIoApi.cloudData.root)[1]}); + window.open(this.application.ninja.coreIoApi.rootUrl+this.application.ninja.documentController._activeDocument.uri.split(this.application.ninja.coreIoApi.cloudData.root)[1]); + //chrome.tabs.create({url: this.application.ninja.coreIoApi.rootUrl+this.application.ninja.documentController._activeDocument.uri.split(this.application.ninja.coreIoApi.cloudData.root)[1]}); } }, //////////////////////////////////////////////////////////////////// -- cgit v1.2.3 From 46fb52be241dced940d46629c809a09c86ed4438 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Wed, 29 Feb 2012 11:38:33 -0800 Subject: changed the registration point of the brush tool icon and added a temporary check to prevent extremely long brush strokes --- js/data/tools-data.js | 2 +- js/helper-classes/RDGE/GLBrushStroke.js | 16 +++++++--------- js/tools/BrushTool.js | 6 +++++- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/js/data/tools-data.js b/js/data/tools-data.js index cf48757d..3abdb60f 100755 --- a/js/data/tools-data.js +++ b/js/data/tools-data.js @@ -141,7 +141,7 @@ exports.ToolsData = Montage.create(Montage, { "spriteSheet": true, "action": "BrushTool", "toolTip": "Brush Tool", - "cursor": "url('images/tools/brush_down.png'), default", + "cursor": "url('images/tools/brush_down.png') 9 17, default", "lastInGroup": false, "container": false, "selected": false diff --git a/js/helper-classes/RDGE/GLBrushStroke.js b/js/helper-classes/RDGE/GLBrushStroke.js index f63bcc8a..07a4a039 100755 --- a/js/helper-classes/RDGE/GLBrushStroke.js +++ b/js/helper-classes/RDGE/GLBrushStroke.js @@ -35,7 +35,8 @@ function GLBrushStroke() { this._strokeStyle = "Solid"; //the wetness of the brush (currently this is multiplied to the square of the stroke width, but todo should be changed to not depend on stroke width entirely - this._WETNESS_FACTOR = 0.010625;//0.0625; + //smaller value means more samples for the path + this._WETNESS_FACTOR = 0.25; //drawing context this._world = null; @@ -75,10 +76,10 @@ function GLBrushStroke() { //add the point only if it is some epsilon away from the previous point var numPoints = this._Points.length; if (numPoints>0) { - var threshold = this._WETNESS_FACTOR*this._strokeWidth*this._strokeWidth; + var threshold = this._WETNESS_FACTOR*this._strokeWidth; var prevPt = this._Points[numPoints-1]; var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; - var diffPtMag = diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]; + var diffPtMag = Math.sqrt(diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]); if (diffPtMag>threshold){ this._Points.push(pt); this._dirty=true; @@ -136,7 +137,7 @@ function GLBrushStroke() { //**** add samples to the path if needed...linear interpolation for now if (numPoints>1) { - var threshold = this._WETNESS_FACTOR*this._strokeWidth*this._strokeWidth; + var threshold = this._WETNESS_FACTOR*this._strokeWidth; var prevPt = this._Points[0]; var prevIndex = 0; for (var i=1;i this._MAX_ALLOWED_SAMPLES){ + console.log("leaving the resampling because numPoints is greater than limit:"+this._MAX_ALLOWED_SAMPLES); + break; + } } } -- cgit v1.2.3 From a89e30ab834a48be32b6122e0c8ac1e0c3ed43e8 Mon Sep 17 00:00:00 2001 From: Nivesh Rajbhandari Date: Wed, 29 Feb 2012 11:58:28 -0800 Subject: Fix for performance issue when moving shapes. We don't need to call render except if the geometry and materials change. This is more easy to see with shapes like the brush tool. Signed-off-by: Nivesh Rajbhandari --- js/controllers/elements/shapes-controller.js | 11 ++++++++++- js/tools/SelectionTool.js | 16 +++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/js/controllers/elements/shapes-controller.js b/js/controllers/elements/shapes-controller.js index e0bff70c..749a1dd9 100755 --- a/js/controllers/elements/shapes-controller.js +++ b/js/controllers/elements/shapes-controller.js @@ -19,43 +19,51 @@ exports.ShapesController = Montage.create(CanvasController, { this.setShapeProperty(el, "strokeSize", value); el.elementModel.shapeModel.GLGeomObj.setStrokeWidth(val); el.elementModel.shapeModel.GLGeomObj.buildBuffers(); + el.elementModel.shapeModel.GLWorld.render(); break; case "innerRadius": this.setShapeProperty(el, "innerRadius", value); el.elementModel.shapeModel.GLGeomObj.setInnerRadius(val/100); el.elementModel.shapeModel.GLGeomObj.buildBuffers(); + el.elementModel.shapeModel.GLWorld.render(); break; case "tlRadius": this.setShapeProperty(el, "tlRadius", value); el.elementModel.shapeModel.GLGeomObj.setTLRadius(val); el.elementModel.shapeModel.GLGeomObj.buildBuffers(); + el.elementModel.shapeModel.GLWorld.render(); break; case "trRadius": this.setShapeProperty(el, "trRadius", value); el.elementModel.shapeModel.GLGeomObj.setTRRadius(val); el.elementModel.shapeModel.GLGeomObj.buildBuffers(); + el.elementModel.shapeModel.GLWorld.render(); break; case "blRadius": this.setShapeProperty(el, "blRadius", value); el.elementModel.shapeModel.GLGeomObj.setBLRadius(val); el.elementModel.shapeModel.GLGeomObj.buildBuffers(); + el.elementModel.shapeModel.GLWorld.render(); break; case "brRadius": this.setShapeProperty(el, "brRadius", value); el.elementModel.shapeModel.GLGeomObj.setBRRadius(val); el.elementModel.shapeModel.GLGeomObj.buildBuffers(); + el.elementModel.shapeModel.GLWorld.render(); break; case "width": el.elementModel.shapeModel.GLGeomObj.setWidth(val); CanvasController.setProperty(el, p, value); el.elementModel.shapeModel.GLWorld.setViewportFromCanvas(el); el.elementModel.shapeModel.GLGeomObj.buildBuffers(); + el.elementModel.shapeModel.GLWorld.render(); break; case "height": el.elementModel.shapeModel.GLGeomObj.setHeight(val); CanvasController.setProperty(el, p, value); el.elementModel.shapeModel.GLWorld.setViewportFromCanvas(el); el.elementModel.shapeModel.GLGeomObj.buildBuffers(); + el.elementModel.shapeModel.GLWorld.render(); break; case "useWebGl": var canvas = njModule.NJUtils.makeNJElement("canvas", "Canvas", "shape", el.className, true); @@ -76,6 +84,7 @@ exports.ShapesController = Montage.create(CanvasController, { el.elementModel.shapeModel.GLGeomObj.setStrokeMaterial(sm); el.elementModel.shapeModel.strokeMaterial = sm; el.elementModel.shapeModel.GLGeomObj.buildBuffers(); + el.elementModel.shapeModel.GLWorld.render(); } break; case "fillMaterial": @@ -85,12 +94,12 @@ exports.ShapesController = Montage.create(CanvasController, { el.elementModel.shapeModel.GLGeomObj.setFillMaterial(fm); el.elementModel.shapeModel.fillMaterial = fm; el.elementModel.shapeModel.GLGeomObj.buildBuffers(); + el.elementModel.shapeModel.GLWorld.render(); } break; default: CanvasController.setProperty(el, p, value); } - el.elementModel.shapeModel.GLWorld.render(); } }, diff --git a/js/tools/SelectionTool.js b/js/tools/SelectionTool.js index 83d52d52..caa9e8d6 100755 --- a/js/tools/SelectionTool.js +++ b/js/tools/SelectionTool.js @@ -312,12 +312,26 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { } if(addToUndoStack) { - ElementsMediator.setProperties(this.application.ninja.selectedElements, + // if we have a delta, that means the transform handles were used and + // we should update the width and height too. Otherwise, just update left and top. + if(this._delta) + { + ElementsMediator.setProperties(this.application.ninja.selectedElements, { "left": newLeft, "top": newTop, "width": newWidth, "height": newHeight }, "Change", "selectionTool", { "left" : previousLeft, "top" : previousTop, "width": previousWidth, "height": previousHeight} ); + } + else + { + ElementsMediator.setProperties(this.application.ninja.selectedElements, + { "left": newLeft, "top": newTop }, + "Change", + "selectionTool", + { "left" : previousLeft, "top" : previousTop } + ); + } } // Save previous value for undo/redo this._undoArray = []; -- cgit v1.2.3