diff options
author | Pushkar Joshi | 2012-03-06 17:03:06 -0800 |
---|---|---|
committer | Pushkar Joshi | 2012-03-06 17:03:06 -0800 |
commit | 264e3d8e6d3624083d2fab9fe2560234553bb2ad (patch) | |
tree | 6212594da55c7461bb6379c7714bdaaf7a2cd23b /js/helper-classes | |
parent | db82be91f767a07b7cb8c97ca3d9f4c4d75bc9ae (diff) | |
download | ninja-264e3d8e6d3624083d2fab9fe2560234553bb2ad.tar.gz |
draw brush stroke as concentric paths overlaid on top of each other...allows us to simulate softness for circular brushes
Diffstat (limited to 'js/helper-classes')
-rwxr-xr-x | js/helper-classes/RDGE/GLBrushStroke.js | 135 |
1 files changed, 98 insertions, 37 deletions
diff --git a/js/helper-classes/RDGE/GLBrushStroke.js b/js/helper-classes/RDGE/GLBrushStroke.js index c1469977..26c922a3 100755 --- a/js/helper-classes/RDGE/GLBrushStroke.js +++ b/js/helper-classes/RDGE/GLBrushStroke.js | |||
@@ -81,7 +81,7 @@ function GLBrushStroke() { | |||
81 | //add the point only if it is some epsilon away from the previous point | 81 | //add the point only if it is some epsilon away from the previous point |
82 | var numPoints = this._Points.length; | 82 | var numPoints = this._Points.length; |
83 | if (numPoints>0) { | 83 | if (numPoints>0) { |
84 | var threshold = this._WETNESS_FACTOR*this._strokeWidth; | 84 | var threshold = 1;//this._WETNESS_FACTOR*this._strokeWidth; |
85 | var prevPt = this._Points[numPoints-1]; | 85 | var prevPt = this._Points[numPoints-1]; |
86 | var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; | 86 | var diffPt = [prevPt[0]-pt[0], prevPt[1]-pt[1]]; |
87 | var diffPtMag = Math.sqrt(diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]); | 87 | var diffPtMag = Math.sqrt(diffPt[0]*diffPt[0] + diffPt[1]*diffPt[1]); |
@@ -375,46 +375,58 @@ function GLBrushStroke() { | |||
375 | */ | 375 | */ |
376 | 376 | ||
377 | /* | 377 | /* |
378 | var R2 = this._strokeWidth; | 378 | //build the stamp for the brush stroke |
379 | var R = R2*0.5; | 379 | //todo get this directly from the UI |
380 | var hardness = 0; //for a pencil, this is always 1 //TODO get hardness parameter from user interface | 380 | var t=0; |
381 | var innerRadius = (hardness*R)-1; | ||
382 | if (innerRadius<1) | ||
383 | innerRadius=1; | ||
384 | |||
385 | var r = ctx.createRadialGradient(0,0,innerRadius, 0,0,R); | ||
386 | var midColor = "rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+",1)"; | ||
387 | r.addColorStop(0, midColor); | ||
388 | var endColor = "rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+",0.0)"; | ||
389 | r.addColorStop(1, endColor); | ||
390 | ctx.fillStyle = r; | ||
391 | |||
392 | for (var i = 0; i < numPoints; i++) { | ||
393 | var pt = this._Points[i]; | ||
394 | ctx.globalCompositeOperation = 'source-over'; | ||
395 | var x = pt[0]-bboxMin[0]; | ||
396 | var y = pt[1]-bboxMin[1]; | ||
397 | ctx.save(); | ||
398 | ctx.translate(x,y); | ||
399 | ctx.arc(0, 0, R, 0, 2 * Math.PI, false); | ||
400 | ctx.fill(); | ||
401 | ctx.restore(); | ||
402 | //ctx.globalCompositeOperation = 'source-in'; | ||
403 | //ctx.rect(x-R, y-R, R2, R2); | ||
404 | } | ||
405 | */ | ||
406 | |||
407 | var numTraces = this._strokeWidth; | 381 | var numTraces = this._strokeWidth; |
408 | var halfNumTraces = numTraces/2; | 382 | var halfNumTraces = numTraces/2; |
409 | var deltaDisplacement = [1,0];//[this._strokeWidth/numTraces, 0]; //a horizontal line brush | ||
410 | var startPos = [-this._strokeWidth/2,0]; | 383 | var startPos = [-this._strokeWidth/2,0]; |
411 | for (var t=0;t<numTraces;t++){ | 384 | var brushStamp = []; |
412 | var disp = [startPos[0]+t*deltaDisplacement[0], startPos[1]+t*deltaDisplacement[1]]; | 385 | |
386 | //build an angled (calligraphic) brush stamp | ||
387 | var deltaDisplacement = [1,1];//[this._strokeWidth/numTraces, 0]; //a horizontal line brush | ||
388 | for (t=0;t<numTraces;t++){ | ||
389 | var brushPt = [startPos[0]+t*deltaDisplacement[0], startPos[1]+t*deltaDisplacement[1]]; | ||
390 | brushStamp.push(brushPt); | ||
391 | } | ||
392 | |||
393 | |||
394 | //make a circular brush stamp | ||
395 | brushStamp=[]; | ||
396 | numTraces = this._strokeWidth*Math.PI; //figure out how to | ||
397 | var radius = this._strokeWidth/2; | ||
398 | for (t=0;t<numTraces;t++) | ||
399 | { | ||
400 | var angle = Math.PI*(360*t/numTraces)/180; | ||
401 | var brushPt = [radius*Math.cos(angle), radius*Math.sin(angle)]; | ||
402 | brushStamp.push(brushPt); | ||
403 | } | ||
404 | |||
405 | // //make a square brush stamp | ||
406 | // STOPPED HERE | ||
407 | // brushStamp = []; | ||
408 | // numTraces = 4*strokeWidth; | ||
409 | // for (t=0;t<numTraces;t++){ | ||
410 | // if (t<numTraces*0.25){ | ||
411 | // var brushPt = [startPos[0]+t*deltaDisplacement[0], startPos[1]+t*deltaDisplacement[1]]; | ||
412 | // } else if (t<numTraces*0.5){ | ||
413 | // | ||
414 | // } else if (t<numTraces*0.75){ | ||
415 | // | ||
416 | // } else { | ||
417 | // | ||
418 | // } | ||
419 | // brushStamp.push(brushPt); | ||
420 | // } | ||
421 | |||
422 | for (t=0;t<numTraces;t++){ | ||
423 | var disp = [brushStamp[t][0], brushStamp[t][1]]; | ||
413 | //ctx.globalCompositeOperation = 'source-over'; | 424 | //ctx.globalCompositeOperation = 'source-over'; |
414 | var distFromMiddle = Math.abs(halfNumTraces-t); | 425 | var distFromMiddle = Math.abs(halfNumTraces-t); |
415 | var alphaVal = 1.0 - (100-this._strokeHardness)*(distFromMiddle/halfNumTraces)/100; | 426 | var alphaVal = 1.0 - (100-this._strokeHardness)*(distFromMiddle/halfNumTraces)/100; |
427 | alphaVal = 0.2; | ||
416 | ctx.save(); | 428 | ctx.save(); |
417 | ctx.lineWidth=this._strokeWidth/10;//4; | 429 | ctx.lineWidth=this._strokeWidth/10;//todo figure out the correct formula for the line width |
418 | if (ctx.lineWidth<2) | 430 | if (ctx.lineWidth<2) |
419 | ctx.lineWidth=2; | 431 | ctx.lineWidth=2; |
420 | if (t===numTraces-1){ | 432 | if (t===numTraces-1){ |
@@ -422,10 +434,10 @@ function GLBrushStroke() { | |||
422 | } | 434 | } |
423 | ctx.lineJoin="bevel"; | 435 | ctx.lineJoin="bevel"; |
424 | ctx.lineCap="butt"; | 436 | ctx.lineCap="butt"; |
425 | if (t<numTraces/2) | 437 | //if (t<numTraces/2) |
426 | ctx.strokeStyle="rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+","+alphaVal+")"; | 438 | ctx.strokeStyle="rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+","+alphaVal+")"; |
427 | else | 439 | //else |
428 | ctx.strokeStyle="rgba("+parseInt(255*this._secondStrokeColor[0])+","+parseInt(255*this._secondStrokeColor[1])+","+parseInt(255*this._secondStrokeColor[2])+","+alphaVal+")"; | 440 | // ctx.strokeStyle="rgba("+parseInt(255*this._secondStrokeColor[0])+","+parseInt(255*this._secondStrokeColor[1])+","+parseInt(255*this._secondStrokeColor[2])+","+alphaVal+")"; |
429 | ctx.translate(disp[0],disp[1]); | 441 | ctx.translate(disp[0],disp[1]); |
430 | ctx.beginPath(); | 442 | ctx.beginPath(); |
431 | ctx.moveTo(this._Points[0][0]-bboxMin[0], this._Points[0][1]-bboxMin[1]); | 443 | ctx.moveTo(this._Points[0][0]-bboxMin[0], this._Points[0][1]-bboxMin[1]); |
@@ -435,8 +447,10 @@ function GLBrushStroke() { | |||
435 | ctx.stroke(); | 447 | ctx.stroke(); |
436 | ctx.restore(); | 448 | ctx.restore(); |
437 | } | 449 | } |
450 | */ | ||
438 | 451 | ||
439 | /* | 452 | /* |
453 | //debugging path | ||
440 | ctx.beginPath(); | 454 | ctx.beginPath(); |
441 | ctx.moveTo(this._Points[0][0]-bboxMin[0], this._Points[0][1]-bboxMin[1]); | 455 | ctx.moveTo(this._Points[0][0]-bboxMin[0], this._Points[0][1]-bboxMin[1]); |
442 | for (var i=1;i<numPoints;i++){ | 456 | for (var i=1;i<numPoints;i++){ |
@@ -447,6 +461,53 @@ function GLBrushStroke() { | |||
447 | ctx.stroke(); | 461 | ctx.stroke(); |
448 | */ | 462 | */ |
449 | 463 | ||
464 | var numlayers = this._strokeWidth/2; | ||
465 | var alphaVal = 1.0/(numlayers-1); | ||
466 | for (var l=0;l<numlayers;l++){ | ||
467 | ctx.beginPath(); | ||
468 | ctx.moveTo(this._Points[0][0]-bboxMin[0], this._Points[0][1]-bboxMin[1]); | ||
469 | for (var i=1;i<numPoints;i++){ | ||
470 | ctx.lineTo(this._Points[i][0]-bboxMin[0], this._Points[i][1]-bboxMin[1]); | ||
471 | } | ||
472 | ctx.lineCap = "round"; | ||
473 | ctx.lineJoin="round"; | ||
474 | ctx.lineWidth=l+1; | ||
475 | ctx.strokeStyle="rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+","+alphaVal+")"; | ||
476 | ctx.stroke(); | ||
477 | } | ||
478 | |||
479 | /* | ||
480 | var R2 = this._strokeWidth; | ||
481 | var R = R2*0.5; | ||
482 | var hardness = 0; //for a pencil, this is always 1 //TODO get hardness parameter from user interface | ||
483 | var innerRadius = (hardness*R)-1; | ||
484 | if (innerRadius<1) | ||
485 | innerRadius=1; | ||
486 | |||
487 | var r = ctx.createRadialGradient(0,0,innerRadius, 0,0,R); | ||
488 | var midColor = "rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+",1)"; | ||
489 | r.addColorStop(0, midColor); | ||
490 | var endColor = "rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+",0.0)"; | ||
491 | r.addColorStop(1, endColor); | ||
492 | ctx.fillStyle = r; | ||
493 | |||
494 | for (var i = 0; i < numPoints; i++) { | ||
495 | var pt = this._Points[i]; | ||
496 | ctx.globalCompositeOperation = 'source-over'; | ||
497 | var x = pt[0]-bboxMin[0]; | ||
498 | var y = pt[1]-bboxMin[1]; | ||
499 | ctx.save(); | ||
500 | ctx.translate(x,y); | ||
501 | ctx.arc(0, 0, R, 0, 2 * Math.PI, false); | ||
502 | ctx.fill(); | ||
503 | ctx.restore(); | ||
504 | break; | ||
505 | //ctx.globalCompositeOperation = 'source-in'; | ||
506 | //ctx.rect(x-R, y-R, R2, R2); | ||
507 | } | ||
508 | */ | ||
509 | |||
510 | |||
450 | ctx.restore(); | 511 | ctx.restore(); |
451 | } //render() | 512 | } //render() |
452 | 513 | ||