diff options
author | hwc487 | 2012-05-15 16:02:27 -0700 |
---|---|---|
committer | hwc487 | 2012-05-15 16:02:27 -0700 |
commit | cb37bee07085690d72e69a82e76cae9166e5f0f1 (patch) | |
tree | 75949f7b4ebf7c107b4d0ae007e36626fb2aaa67 /js/lib/geom | |
parent | 02e5fbb819f02d26a8a7179cf04021a0f6c6ddf6 (diff) | |
download | ninja-cb37bee07085690d72e69a82e76cae9166e5f0f1.tar.gz |
Gradient matching between WebGL and Canvas2D
Diffstat (limited to 'js/lib/geom')
-rwxr-xr-x | js/lib/geom/circle.js | 119 | ||||
-rwxr-xr-x | js/lib/geom/rectangle.js | 183 |
2 files changed, 134 insertions, 168 deletions
diff --git a/js/lib/geom/circle.js b/js/lib/geom/circle.js index b60ad58f..2ca4c1f5 100755 --- a/js/lib/geom/circle.js +++ b/js/lib/geom/circle.js | |||
@@ -505,9 +505,9 @@ exports.Circle = Object.create(GeomObj, { | |||
505 | if(this._fillColor.gradientMode) { | 505 | if(this._fillColor.gradientMode) { |
506 | if(this._fillColor.gradientMode === "radial") { | 506 | if(this._fillColor.gradientMode === "radial") { |
507 | gradient = ctx.createRadialGradient(xCtr, yCtr, 0, | 507 | gradient = ctx.createRadialGradient(xCtr, yCtr, 0, |
508 | xCtr, yCtr, Math.max(this._width, this._height)/2); | 508 | xCtr, yCtr, Math.max(this._width, this._height)/2 - lineWidth); |
509 | } else { | 509 | } else { |
510 | gradient = ctx.createLinearGradient(lineWidth/2, this._height/2, this._width-lineWidth, this._height/2); | 510 | gradient = ctx.createLinearGradient(lineWidth, this._height/2, this._width-lineWidth, this._height/2); |
511 | } | 511 | } |
512 | colors = this._fillColor.color; | 512 | colors = this._fillColor.color; |
513 | 513 | ||
@@ -804,79 +804,44 @@ exports.Circle = Object.create(GeomObj, { | |||
804 | } | 804 | } |
805 | }, | 805 | }, |
806 | 806 | ||
807 | /* | 807 | recalcTexMapCoords: { |
808 | this.getNearPoint = function( pt, dir ) { | 808 | value: function(vrts, uvs) { |
809 | var world = this.getWorld(); | 809 | var n = vrts.length/3; |
810 | if (!world) throw( "null world in getNearPoint" ); | 810 | if (n === 0) return; |
811 | 811 | var ivrt = 0, iuv = 0; | |
812 | // get a point on the plane of the circle | 812 | var uMin = 1.e8, uMax = -1.e8, |
813 | // the point is in NDC, as is the input parameters | 813 | vMin = 1.e8, vMax = -1.e8; |
814 | var mat = this.getMatrix(); | 814 | |
815 | var plane = [0,0,1,0]; | 815 | var i, index = 3; |
816 | plane = MathUtils.transformPlane( plane, mat ); | 816 | var xMin = vrts[0], xMax = vrts[0], |
817 | var projPt = MathUtils.vecIntersectPlane ( pt, dir, plane ); | 817 | yMin = vrts[1], yMax = vrts[1]; |
818 | 818 | for (i=1; i<n; i++) | |
819 | // transform the projected point back to the XY plane | 819 | { |
820 | //var invMat = mat.inverse(); | 820 | if (vrts[index] < xMin) xMin = vrts[index]; |
821 | var invMat = glmat4.inverse( mat, [] ); | 821 | else if (vrts[index] > xMax) xMax = vrts[index]; |
822 | var planePt = MathUtils.transformPoint( projPt, invMat ); | 822 | |
823 | 823 | if (vrts[index+1] < yMin) yMin = vrts[index+1]; | |
824 | // get the normalized device coordinates (NDC) for | 824 | else if (vrts[index+1] > yMax) yMax = vrts[index+1]; |
825 | // the position and radii. | 825 | |
826 | var vpw = world.getViewportWidth(), vph = world.getViewportHeight(); | 826 | index += 3; |
827 | var xNDC = 2*this._xOffset/vpw, yNDC = -2*this._yOffset/vph, | 827 | } |
828 | xRadNDC = this._width/vpw, yRadNDC = this._height/vph; | 828 | var ovalWidth = xMax - xMin, |
829 | var projMat = world.makePerspectiveMatrix(); | 829 | ovalHeight = yMax - yMin; |
830 | var z = -world.getViewDistance(); | 830 | for (i=0; i<n; i++) { |
831 | var planePtNDC = planePt.slice(0); | 831 | uvs[iuv] = (vrts[ivrt]-xMin)/ovalWidth; |
832 | planePtNDC[2] = z; | 832 | if (uvs[iuv] < uMin) uMin = uvs[iuv]; |
833 | planePtNDC = MathUtils.transformHomogeneousPoint( planePtNDC, projMat ); | 833 | if (uvs[iuv] > uMax) uMax = uvs[iuv]; |
834 | planePtNDC = MathUtils.applyHomogeneousCoordinate( planePtNDC ); | 834 | |
835 | 835 | iuv++; ivrt++; | |
836 | // get the gl coordinates | 836 | uvs[iuv] = (vrts[ivrt]-yMin)/ovalHeight; |
837 | var aspect = world.getAspect(); | 837 | if (uvs[iuv] < vMin) vMin = uvs[iuv]; |
838 | var zn = world.getZNear(), zf = world.getZFar(); | 838 | if (uvs[iuv] > vMax) vMax = uvs[iuv]; |
839 | var t = zn * Math.tan(world.getFOV() * Math.PI / 360.0), | 839 | iuv++; ivrt += 2; |
840 | b = -t, | 840 | } |
841 | r = aspect*t, | 841 | |
842 | l = -r; | 842 | //console.log( "remap" ); |
843 | 843 | //console.log( "uRange: " + uMin + " => " + uMax ); | |
844 | var angle = Math.atan2( planePtNDC[1] - yNDC, planePtNDC[0] - xNDC ); | 844 | //console.log( "vRange: " + vMin + " => " + vMax ); |
845 | var degrees = angle*180.0/Math.PI; | 845 | } |
846 | var objPt = [Math.cos(angle)*xRadNDC + xNDC, Math.sin(angle)*yRadNDC + yNDC, 0]; | 846 | } |
847 | |||
848 | // convert to GL coordinates | ||
849 | objPt[0] = -z*(r-l)/(2.0*zn)*objPt[0]; | ||
850 | objPt[1] = -z*(t-b)/(2.0*zn)*objPt[1]; | ||
851 | |||
852 | // re-apply the transform | ||
853 | objPt = MathUtils.transformPoint( objPt, mat ); | ||
854 | |||
855 | return objPt; | ||
856 | }; | ||
857 | */ | ||
858 | recalcTexMapCoords: { | ||
859 | value: function(vrts, uvs) { | ||
860 | var n = vrts.length/3; | ||
861 | var ivrt = 0, iuv = 0; | ||
862 | var uMin = 1.e8, uMax = -1.e8, | ||
863 | vMin = 1.e8, vMax = -1.e8; | ||
864 | |||
865 | for (var i=0; i<n; i++) { | ||
866 | uvs[iuv] = 0.5*(vrts[ivrt]/this._ovalWidth + 1); | ||
867 | if (uvs[iuv] < uMin) uMin = uvs[iuv]; | ||
868 | if (uvs[iuv] > uMax) uMax = uvs[iuv]; | ||
869 | |||
870 | iuv++; ivrt++; | ||
871 | uvs[iuv] = 0.5*(vrts[ivrt]/this._ovalHeight + 1); | ||
872 | if (uvs[iuv] < vMin) vMin = uvs[iuv]; | ||
873 | if (uvs[iuv] > vMax) vMax = uvs[iuv]; | ||
874 | iuv++; ivrt += 2; | ||
875 | } | ||
876 | |||
877 | //console.log( "remap: " + uvs ); | ||
878 | //console.log( "uRange: " + uMin + " => " + uMax ); | ||
879 | //console.log( "vRange: " + vMin + " => " + vMax ); | ||
880 | } | ||
881 | } | ||
882 | }); \ No newline at end of file | 847 | }); \ No newline at end of file |
diff --git a/js/lib/geom/rectangle.js b/js/lib/geom/rectangle.js index 4415af43..8fc80c60 100755 --- a/js/lib/geom/rectangle.js +++ b/js/lib/geom/rectangle.js | |||
@@ -508,98 +508,99 @@ exports.Rectangle = Object.create(GeomObj, { | |||
508 | }, | 508 | }, |
509 | 509 | ||
510 | render: { | 510 | render: { |
511 | value: function() { | 511 | value: function() { |
512 | // get the world | 512 | // get the world |
513 | var world = this.getWorld(); | 513 | var world = this.getWorld(); |
514 | if (!world) throw( "null world in rectangle render" ); | 514 | if (!world) throw( "null world in rectangle render" ); |
515 | 515 | ||
516 | // get the context | 516 | // get the context |
517 | var ctx = world.get2DContext(); | 517 | var ctx = world.get2DContext(); |
518 | if (!ctx) return; | 518 | if (!ctx) return; |
519 | 519 | ||
520 | // get some dimensions | 520 | // get some dimensions |
521 | var lw = this._strokeWidth; | 521 | var lw = this._strokeWidth; |
522 | var w = world.getViewportWidth(), | 522 | var w = world.getViewportWidth(), |
523 | h = world.getViewportHeight(); | 523 | h = world.getViewportHeight(); |
524 | 524 | ||
525 | var c, | 525 | var c, |
526 | inset, | 526 | inset, |
527 | gradient, | 527 | gradient, |
528 | colors, | 528 | colors, |
529 | len, | 529 | len, |
530 | n, | 530 | n, |
531 | position, | 531 | position, |
532 | cs; | 532 | cs; |
533 | // render the fill | 533 | // render the fill |
534 | ctx.beginPath(); | 534 | ctx.beginPath(); |
535 | if (this._fillColor) { | 535 | if (this._fillColor) { |
536 | inset = Math.ceil( lw ) - 0.5; | 536 | inset = Math.ceil( lw ) - 0.5; |
537 | 537 | ||
538 | if(this._fillColor.gradientMode) { | 538 | if(this._fillColor.gradientMode) { |
539 | if(this._fillColor.gradientMode === "radial") { | 539 | if(this._fillColor.gradientMode === "radial") { |
540 | var ww = w - 2*lw, hh = h - 2*lw; | 540 | var ww = w - 2*lw, hh = h - 2*lw; |
541 | gradient = ctx.createRadialGradient(w/2, h/2, 0, w/2-this._strokeWidth, h/2, Math.max(ww, hh)/2); | 541 | //gradient = ctx.createRadialGradient(w/2, h/2, 0, w/2-this._strokeWidth, h/2, Math.max(ww, hh)/2); |
542 | } else { | 542 | gradient = ctx.createRadialGradient(w/2, h/2, 0, w/2, h/2, Math.max(ww, hh)/2); |
543 | gradient = ctx.createLinearGradient(inset/2, h/2, w-inset, h/2); | 543 | } else { |
544 | } | 544 | gradient = ctx.createLinearGradient(inset/2, h/2, w-inset, h/2); |
545 | colors = this._fillColor.color; | 545 | } |
546 | 546 | colors = this._fillColor.color; | |
547 | len = colors.length; | 547 | |
548 | 548 | len = colors.length; | |
549 | for(n=0; n<len; n++) { | 549 | |
550 | position = colors[n].position/100; | 550 | for(n=0; n<len; n++) { |
551 | cs = colors[n].value; | 551 | position = colors[n].position/100; |
552 | gradient.addColorStop(position, "rgba(" + cs.r + "," + cs.g + "," + cs.b + "," + cs.a + ")"); | 552 | cs = colors[n].value; |
553 | } | 553 | gradient.addColorStop(position, "rgba(" + cs.r + "," + cs.g + "," + cs.b + "," + cs.a + ")"); |
554 | 554 | } | |
555 | ctx.fillStyle = gradient; | 555 | |
556 | 556 | ctx.fillStyle = gradient; | |
557 | } else { | 557 | |
558 | c = "rgba(" + 255*this._fillColor[0] + "," + 255*this._fillColor[1] + "," + 255*this._fillColor[2] + "," + this._fillColor[3] + ")"; | 558 | } else { |
559 | ctx.fillStyle = c; | 559 | c = "rgba(" + 255*this._fillColor[0] + "," + 255*this._fillColor[1] + "," + 255*this._fillColor[2] + "," + this._fillColor[3] + ")"; |
560 | } | 560 | ctx.fillStyle = c; |
561 | 561 | } | |
562 | ctx.lineWidth = lw; | 562 | |
563 | this.renderPath( inset, ctx ); | 563 | ctx.lineWidth = lw; |
564 | ctx.fill(); | 564 | this.renderPath( inset, ctx ); |
565 | ctx.closePath(); | 565 | ctx.fill(); |
566 | } | 566 | ctx.closePath(); |
567 | 567 | } | |
568 | // render the stroke | 568 | |
569 | ctx.beginPath(); | 569 | // render the stroke |
570 | if (this._strokeColor) { | 570 | ctx.beginPath(); |
571 | inset = Math.ceil( 0.5*lw ) - 0.5; | 571 | if (this._strokeColor) { |
572 | 572 | inset = Math.ceil( 0.5*lw ) - 0.5; | |
573 | if(this._strokeColor.gradientMode) { | 573 | |
574 | if(this._strokeColor.gradientMode === "radial") { | 574 | if(this._strokeColor.gradientMode) { |
575 | gradient = ctx.crea |