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 631c9750e5ad6d7739d8683c31aa3a9f8f3b4e4c Mon Sep 17 00:00:00 2001 From: Kruti Shah Date: Tue, 28 Feb 2012 15:01:41 -0800 Subject: Timeline: Fix Selection , Partially Fix adding element to an already animated track with one element Signed-off-by: Kruti Shah --- .../Timeline/TimelinePanel.reel/TimelinePanel.js | 27 ++++++++++++++++++---- .../Timeline/TimelineTrack.reel/TimelineTrack.js | 1 + 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js index 01b03531..81415951 100644 --- a/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js +++ b/js/panels/Timeline/TimelinePanel.reel/TimelinePanel.js @@ -256,6 +256,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { while(this.application.ninja.currentDocument.documentRoot.children[myIndex]) { this._openDoc=true; + this._captureSelection=true; NJevent('newLayer',{key:this._hashKey,ele:this.application.ninja.currentDocument.documentRoot.children[myIndex]}) myIndex++; } @@ -579,7 +580,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.arrTracks.splice(myIndex, 0, newTrack); this.arrLayers.splice(myIndex, 0, thingToPush); this._LayerUndoPosition = myIndex; -// this.selectLayer(myIndex); + this.selectLayer(myIndex); this.hashLayerNumber.setItem(this._hashKey, thingToPush); this.hashInstance.setItem(this._hashKey, thingToPush, myIndex); this.hashTrackInstance.setItem(this._hashKey, newTrack, myIndex); @@ -592,7 +593,7 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.hashLayerNumber.setItem(this._hashKey, thingToPush); this.hashInstance.setItem(this._hashKey, thingToPush, thingToPush.layerPosition); this.hashTrackInstance.setItem(this._hashKey, newTrack, newTrack.trackPosition); -// this.selectLayer(0); + this.selectLayer(0); } @@ -722,9 +723,21 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { handleElementAdded:{ value:function (event) { + event.detail.uuid=nj.generateRandom(); - this.hashElementMapToLayer.setItem(event.detail.uuid, event.detail,this.currentLayerSelected); - this.currentLayerSelected.elementsList.push(event.detail); + if(this.currentLayerSelected.elementsList[0]!==undefined){ + if(this.currentTrackSelected.isTrackAnimated){ + this.application.ninja.stage.clearDrawingCanvas(); + alert("cannot add elements to a layer with animated element");/* check how to clear the canvas*/ + return; + }else{ + this.hashElementMapToLayer.setItem(event.detail.uuid, event.detail,this.currentLayerSelected); + this.currentLayerSelected.elementsList.push(event.detail); + } + }else{ + this.hashElementMapToLayer.setItem(event.detail.uuid, event.detail,this.currentLayerSelected); + this.currentLayerSelected.elementsList.push(event.detail); + } } }, @@ -948,7 +961,11 @@ var TimelinePanel = exports.TimelinePanel = Montage.create(Component, { this.currentTrackSelected = this.arrTracks[layerIndex]; if(!this._openDoc){ if(this._captureSelection){ - this.application.ninja.selectionController.selectElements(this.currentLayerSelected.elementsList) + if(this.currentLayerSelected.elementsList.length >= 1){ + this.application.ninja.selectionController.selectElements(this.currentLayerSelected.elementsList); + }else{ + this.application.ninja.selectionController.executeSelectElement(); + } } this._captureSelection = true; } diff --git a/js/panels/Timeline/TimelineTrack.reel/TimelineTrack.js b/js/panels/Timeline/TimelineTrack.reel/TimelineTrack.js index 43cd7477..bf97c0fd 100644 --- a/js/panels/Timeline/TimelineTrack.reel/TimelineTrack.js +++ b/js/panels/Timeline/TimelineTrack.reel/TimelineTrack.js @@ -519,6 +519,7 @@ var TimelineTrack = exports.TimelineTrack = Montage.create(Component, { i++; this.nextKeyframe += 1; } + this.isTrackAnimated = true; } } else{ -- cgit v1.2.3 From 72c3277e5b03343afc043c033fecda95b6c229bc Mon Sep 17 00:00:00 2001 From: Jonathan Duran Date: Wed, 29 Feb 2012 07:39:03 -0800 Subject: fix for creatingNewFile flag Signed-off-by: Ananya Sen Signed-off-by: Jonathan Duran --- js/controllers/document-controller.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/js/controllers/document-controller.js b/js/controllers/document-controller.js index 02031922..64ff2c7e 100755 --- a/js/controllers/document-controller.js +++ b/js/controllers/document-controller.js @@ -195,7 +195,10 @@ var DocumentController = exports.DocumentController = Montage.create(Component, value:function(doc){ var response = doc || null;//default just for testing if(!!response && response.success && (response.status!== 500) && !!response.uri){ + + this.isNewFilePath = true;//path identifier flag this.creatingNewFile = true;//flag for timeline to identify new file flow + this.application.ninja.ioMediator.fileOpen(response.uri, this.openFileCallback.bind(this)); }else if(!!response && !response.success){ //Todo: restrict directory path to the sandbox, in the dialog itself @@ -224,9 +227,10 @@ var DocumentController = exports.DocumentController = Montage.create(Component, //TODO: Add UI to handle error codes, shouldn't be alert windows if(!!response && (response.status === 204)) { - if((typeof this.creatingNewFile === 'undefined') || (this.creatingNewFile !== true)){//not from new file flow + if((typeof this.isNewFilePath === 'undefined') || (this.isNewFilePath !== true)){//not from new file flow this.creatingNewFile = false; } + this.isNewFilePath = false;//reset path identifier flag //Sending full response object this.openDocument(response); -- 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 31dc61a626ee9f2b08cb098a51ca0fed5bf30e77 Mon Sep 17 00:00:00 2001 From: Jonathan Duran Date: Wed, 29 Feb 2012 11:21:22 -0800 Subject: Squashed commit of the following: commit 3dbe798285f95dc63ae33739df5daadb8c432f24 Author: Valerio Virgillito Date: Tue Feb 28 16:20:25 2012 -0800 putting the color panel on top when opening ninja Signed-off-by: Valerio Virgillito commit b5ae7f0babb185051242df47634e24ad7a68f60e Merge: 20d4f1d 2bc8343 Author: Valerio Virgillito Date: Tue Feb 28 16:15:44 2012 -0800 Merge branch 'nested-selection' of https://github.com/mencio/ninja-internal into integration-candidate Conflicts: js/ninja.reel/ninja.html Signed-off-by: Valerio Virgillito commit 2bc834334a3197ab7cffacc7332eafd1b52443d1 Author: Valerio Virgillito Date: Tue Feb 28 16:11:42 2012 -0800 revert changes to the timeline Signed-off-by: Valerio Virgillito commit ae96ea66acc4be873fb7fb73fb3f4484b6db3eb8 Author: Valerio Virgillito Date: Tue Feb 28 16:03:32 2012 -0800 adding some margin to the bread crumb buttons Signed-off-by: Valerio Virgillito commit 20d4f1d703c004dd7f869576b6c471b3fb5b5d3e Merge: ee52f19 557c4d3 Author: Valerio Virgillito Date: Tue Feb 28 16:02:37 2012 -0800 Merge pull request #81 from ananyasen/integration-candidate persist selections while switching documents commit 557c4d3100ccde51b925b71f0650b2c783a4a042 Author: Ananya Sen Date: Tue Feb 28 16:02:15 2012 -0800 minor fix for handling selections on switch document Signed-off-by: Ananya Sen commit a230f0cd065613a1bc933e3d6d3f7e77f52bec04 Author: Ananya Sen Date: Tue Feb 28 15:48:55 2012 -0800 selection controller sets _isDocument = true if number of selections are 0, on switch document Signed-off-by: Ananya Sen commit ee52f197d1eb53a5ff30b54b8df1d2b53014eb0e Merge: 8e370cc da83f44 Author: Valerio Virgillito Date: Tue Feb 28 15:16:12 2012 -0800 Merge pull request #80 from joseeight/FileIO-Build-Candidate Adding CSS attributes support to I/O commit 5ab7efb9949e486395659c383064a08821febdae Author: Ananya Sen Date: Tue Feb 28 15:15:27 2012 -0800 persist selections while switching documents Signed-off-by: Ananya Sen commit da83f44b0ecf379b0950a88d1c378fbedb80e386 Merge: b799b7c 676b4e2 Author: Jose Antonio Marquez Date: Tue Feb 28 15:15:12 2012 -0800 Merge branch 'refs/heads/integration-candidate' into FileIO-Build-Candidate commit 8e370cc72aa85de594a5d55ae89947a70af414ca Merge: 8de4002 676b4e2 Author: Valerio Virgillito Date: Tue Feb 28 15:08:48 2012 -0800 Merge branch 'integration-candidate' of github.com:Motorola-Mobility/ninja-internal into integration-candidate commit 8de40029442333114d81ac30a8886a995a3dc56b Merge: b0b4d64 eb27ed3 Author: Valerio Virgillito Date: Tue Feb 28 15:08:18 2012 -0800 Merge branch 'ToolFixes' of https://github.com/mqg734/ninja-internal into integration-candidate commit eb27ed35bf282262843de13b00af89a2bceac53f Merge: ea59626 7c9291a Author: Nivesh Rajbhandari Date: Tue Feb 28 15:04:33 2012 -0800 Merge branch 'refs/heads/ninja-internal' into ToolFixes commit b799b7cf3a422f407045c52a4c6a61756d1ea096 Merge: f7c08fe 2ce9f65 Author: Jose Antonio Marquez Date: Tue Feb 28 15:03:38 2012 -0800 Merge branch 'refs/heads/FileIO' into FileIO-Build-Candidate commit 2ce9f65c3a34937928f08690606962af3085c74f Author: Jose Antonio Marquez Date: Tue Feb 28 15:03:23 2012 -0800 CSS attributes Setting up logic to include attributes in for the