aboutsummaryrefslogtreecommitdiff
path: root/js/lib/geom/brush-stroke.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/lib/geom/brush-stroke.js')
-rwxr-xr-xjs/lib/geom/brush-stroke.js75
1 files changed, 48 insertions, 27 deletions
diff --git a/js/lib/geom/brush-stroke.js b/js/lib/geom/brush-stroke.js
index d9c2ab53..c9224fde 100755
--- a/js/lib/geom/brush-stroke.js
+++ b/js/lib/geom/brush-stroke.js
@@ -31,6 +31,8 @@ var BrushStroke = function GLBrushStroke() {
31 31
32 //the HTML5 canvas that holds this brush stroke 32 //the HTML5 canvas that holds this brush stroke
33 this._canvas = null; 33 this._canvas = null;
34 //flag indicating whether or not to freeze the size and position of canvas
35 this._freezeCanvas = false;
34 36
35 //stroke information 37 //stroke information
36 this._strokeWidth = 1.0; 38 this._strokeWidth = 1.0;
@@ -174,11 +176,15 @@ BrushStroke.prototype.getStrokeWidth = function () {
174}; 176};
175 177
176BrushStroke.prototype.setStrokeWidth = function (w) { 178BrushStroke.prototype.setStrokeWidth = function (w) {
177 this._strokeWidth = w; 179 if (this._strokeWidth!==w) {
178 if (this._strokeWidth<1) { 180 this._strokeWidth = w;
179 this._strokeWidth = 1; 181
182 if (this._strokeWidth<1) {
183 this._strokeWidth = 1;
184 }
185 this._isDirty=true;
186 this._freezeCanvas=false;
180 } 187 }
181 this._isDirty=true;
182}; 188};
183/* 189/*
184BrushStroke.prototype.getStrokeMaterial = function () { 190BrushStroke.prototype.getStrokeMaterial = function () {
@@ -236,6 +242,7 @@ BrushStroke.prototype.setSmoothingAmount = function(a){
236 if (this._strokeAmountSmoothing!==a) { 242 if (this._strokeAmountSmoothing!==a) {
237 this._strokeAmountSmoothing = a; 243 this._strokeAmountSmoothing = a;
238 this._isDirty = true; 244 this._isDirty = true;
245 this._freezeCanvas=false;
239 } 246 }
240}; 247};
241 248
@@ -274,27 +281,32 @@ BrushStroke.prototype.setStrokeStyle = function (s) {
274}; 281};
275 282
276BrushStroke.prototype.setWidth = function (newW) { 283BrushStroke.prototype.setWidth = function (newW) {
277 if (newW<1) { 284 //get the old width from the canvas controller if the canvas is frozen, or from bbox if not frozen.
278 newW=1; //clamp minimum width to 1 285 var oldCanvasWidth = parseInt(CanvasController.getProperty(this._canvas, "width"));
286 if (!this._freezeCanvas){
287 oldCanvasWidth = Math.round(this._BBoxMax[0]-this._BBoxMin[0]);
288 }
289 var minWidth = 1+this._strokeWidth;
290 if (newW<minWidth) {
291 newW=minWidth;
279 } 292 }
280 293
281 //scale the contents of this subpath to lie within this width 294 if (oldCanvasWidth<minWidth) {
282 //determine the scale factor by comparing with the old width 295 oldCanvasWidth=minWidth;
283 var oldWidth = this._BBoxMax[0]-this._BBoxMin[0];
284 if (oldWidth<1) {
285 oldWidth=1;
286 } 296 }
287 297
288 var scaleX = newW/oldWidth; 298 //scale the contents of this subpath to lie within this width
299 //determine the scale factor by comparing with the old width
300 var scaleX = (newW-this._strokeWidth)/(oldCanvasWidth-this._strokeWidth);
289 if (scaleX===1) { 301 if (scaleX===1) {
302 console.log("Ignoring setWidth because scale is "+scaleX);
290 return; //no need to do anything 303 return; //no need to do anything
291 } 304 }
292
293 //scale the local point positions such that the width of the bbox is the newW 305 //scale the local point positions such that the width of the bbox is the newW
294 var origX = this._BBoxMin[0]; 306 var origX = 0.5*this._strokeWidth;//this._BBoxMin[0]; //this represents the left edge
295 var numPoints = this._LocalPoints.length; 307 var numPoints = this._LocalPoints.length;
296 for (var i=0;i<numPoints;i++){ 308 for (var i=0;i<numPoints;i++){
297 //compute the distance from the bboxMin 309 //compute the distance from the left edge
298 var oldW = this._LocalPoints[i][0] - origX; 310 var oldW = this._LocalPoints[i][0] - origX;
299 this._LocalPoints[i] = [(origX + oldW*scaleX),this._LocalPoints[i][1],this._LocalPoints[i][2]]; 311 this._LocalPoints[i] = [(origX + oldW*scaleX),this._LocalPoints[i][1],this._LocalPoints[i][2]];
300 312
@@ -305,24 +317,29 @@ BrushStroke.prototype.setWidth = function (newW) {
305}; 317};
306 318
307BrushStroke.prototype.setHeight = function (newH) { 319BrushStroke.prototype.setHeight = function (newH) {
308 if (newH<1) { 320 var oldCanvasHeight = parseInt(CanvasController.getProperty(this._canvas, "height"));
309 newH=1; //clamp minimum width to 1 321 if (!this._freezeCanvas){
322 oldCanvasHeight = this._BBoxMax[1]-this._BBoxMin[1];
323 }
324 var minHeight = 1 + this._strokeWidth;
325 if (oldCanvasHeight<minHeight) {
326 oldCanvasHeight=minHeight;
310 } 327 }
328 if (newH<minHeight) {
329 newH=minHeight;
330 }
331
311 332
312 //scale the contents of this subpath to lie within this height 333 //scale the contents of this subpath to lie within this height
313 //determine the scale factor by comparing with the old height 334 //determine the scale factor by comparing with the old height
314 var oldHeight = this._BBoxMax[1]-this._BBoxMin[1]; 335 var scaleY = (newH-this._strokeWidth)/(oldCanvasHeight-this._strokeWidth);
315 if (oldHeight<1) {
316 oldHeight=1;
317 }
318
319 var scaleY = newH/oldHeight;
320 if (scaleY===1) { 336 if (scaleY===1) {
337 console.log("Ignoring setHeight because scale is 1");
321 return; //no need to do anything 338 return; //no need to do anything
322 } 339 }
323 340
324 //scale the local point positions such that the width of the bbox is the newW 341 //scale the local point positions such that the width of the bbox is the newW
325 var origY = this._BBoxMin[1]; 342 var origY = 0.5*this._strokeWidth;//this._BBoxMin[1]; //this represents the top edge
326 var numPoints = this._LocalPoints.length; 343 var numPoints = this._LocalPoints.length;
327 for (var i=0;i<numPoints;i++){ 344 for (var i=0;i<numPoints;i++){
328 //compute the distance from the bboxMin 345 //compute the distance from the bboxMin
@@ -611,7 +628,7 @@ BrushStroke.prototype.render = function () {
611 //set the canvas by querying the world 628 //set the canvas by querying the world
612 this._canvas = this.getWorld().getCanvas(); 629 this._canvas = this.getWorld().getCanvas();
613 } 630 }
614 if (this._canvas) { 631 if (this._canvas && !this._freezeCanvas) {
615 var newLeft = Math.round(this._stageWorldCenter[0] - 0.5 * bboxWidth); 632 var newLeft = Math.round(this._stageWorldCenter[0] - 0.5 * bboxWidth);
616 var newTop = Math.round(this._stageWorldCenter[1] - 0.5 * bboxHeight); 633 var newTop = Math.round(this._stageWorldCenter[1] - 0.5 * bboxHeight);
617 //assign the new position, width, and height as the canvas dimensions through the canvas controller 634 //assign the new position, width, and height as the canvas dimensions through the canvas controller
@@ -622,7 +639,7 @@ BrushStroke.prototype.render = function () {
622 CanvasController.setProperty(this._canvas, "height", bboxHeight+"px"); 639 CanvasController.setProperty(this._canvas, "height", bboxHeight+"px");
623 //this._canvas.elementModel.shapeModel.GLWorld.setViewportFromCanvas(this._canvas); 640 //this._canvas.elementModel.shapeModel.GLWorld.setViewportFromCanvas(this._canvas);
624 } 641 }
625 642 this._freezeCanvas=true; //unless this is set to false, we will not update the canvas width and height anymore in the render function
626 643
627 //get the context 644 //get the context
628 var ctx = world.get2DContext(); 645 var ctx = world.get2DContext();
@@ -648,6 +665,7 @@ BrushStroke.prototype.buildColor = function(ctx, //the 2D rendering con
648 if (ipColor.gradientMode){ 665 if (ipColor.gradientMode){
649 var position, gradient, cs, inset; //vars used in gradient calculations 666 var position, gradient, cs, inset; //vars used in gradient calculations
650 inset = Math.ceil( lw ) - 0.5; 667 inset = Math.ceil( lw ) - 0.5;
668 inset = 0;
651 669
652 if(ipColor.gradientMode === "radial") { 670 if(ipColor.gradientMode === "radial") {
653 var ww = w - 2*lw, hh = h - 2*lw; 671 var ww = w - 2*lw, hh = h - 2*lw;
@@ -719,7 +737,10 @@ BrushStroke.prototype.drawToContext = function(ctx, drawStageWorldPts, stageWorl
719 var disp = [brushStamp[t][0], brushStamp[t][1]]; 737 var disp = [brushStamp[t][0], brushStamp[t][1]];
720 var alphaVal = 1.0; 738 var alphaVal = 1.0;
721 var distFromOpaqueRegion = Math.abs(t-halfNumTraces) - opaqueRegionHalfWidth; 739 var distFromOpaqueRegion = Math.abs(t-halfNumTraces) - opaqueRegionHalfWidth;
722 if (distFromOpaqueRegion>0) { 740 if (numTraces === 1){
741 distFromOpaqueRegion = 0;
742 }
743 else if (distFromOpaqueRegion>0) {
723 var transparencyFactor = distFromOpaqueRegion/maxTransparentRegionHalfWidth; 744 var transparencyFactor = distFromOpaqueRegion/maxTransparentRegionHalfWidth;
724 alphaVal = 1.0 - transparencyFactor;//(transparencyFactor*transparencyFactor);//the square term produces nonlinearly varying alpha values 745 alphaVal = 1.0 - transparencyFactor;//(transparencyFactor*transparencyFactor);//the square term produces nonlinearly varying alpha values
725 alphaVal *= 0.5; //factor that accounts for lineWidth == 2 746 alphaVal *= 0.5; //factor that accounts for lineWidth == 2