(pos, size=vec2(1), colorInner=WHITE, colorOuter=CLEAR_WHITE, angle=0, useWebGL=glEnable, screenSpace=false, context)
| 749 | * @memberof Draw */ |
| 750 | let drawEllipseGradientOffset = 0; |
| 751 | function drawEllipseGradient(pos, size=vec2(1), colorInner=WHITE, colorOuter=CLEAR_WHITE, angle=0, useWebGL=glEnable, screenSpace=false, context) |
| 752 | { |
| 753 | ASSERT(isVector2(pos), 'pos must be a vec2'); |
| 754 | ASSERT(isVector2(size), 'size must be a vec2'); |
| 755 | ASSERT(isColor(colorInner) && isColor(colorOuter), 'color is invalid'); |
| 756 | ASSERT(isNumber(angle), 'angle must be a number'); |
| 757 | ASSERT(!context || !useWebGL, 'context only supported in canvas 2D mode'); |
| 758 | |
| 759 | if (headlessMode) return; |
| 760 | |
| 761 | if (useWebGL && glEnable) |
| 762 | { |
| 763 | ASSERT(!!glContext, 'WebGL is not enabled!'); |
| 764 | if (screenSpace) |
| 765 | { |
| 766 | // convert to world space |
| 767 | pos = screenToWorld(pos); |
| 768 | size = size.scale(1/cameraScale); |
| 769 | angle += cameraAngle; |
| 770 | } |
| 771 | // fan as tristrip; rotate the boundary vertex by one slice per call |
| 772 | // so back-to-back gradients at the same position have their hole |
| 773 | // (from gpu edge-rule on the boundary line-degen) at different rim |
| 774 | // verts and don't visibly stack |
| 775 | const sides = glCircleSides; |
| 776 | const radiusX = size.x/2, radiusY = size.y/2; |
| 777 | const innerInt = colorInner.rgbaInt(); |
| 778 | const outerInt = colorOuter.rgbaInt(); |
| 779 | const offset = drawEllipseGradientOffset++; |
| 780 | const c = cos(-angle), s = sin(-angle); |
| 781 | const rim = (a) => |
| 782 | { |
| 783 | const lx = sin(a)*radiusX, ly = cos(a)*radiusY; |
| 784 | return vec2(pos.x + lx*c - ly*s, pos.y + lx*s + ly*c); |
| 785 | }; |
| 786 | const startA = (offset%sides)/sides*PI*2; |
| 787 | const points = [rim(startA)]; |
| 788 | const colors = [outerInt]; |
| 789 | for (let i=sides; i--;) |
| 790 | { |
| 791 | const a = ((i+offset)%sides)/sides*PI*2; |
| 792 | points.push(pos); |
| 793 | colors.push(innerInt); |
| 794 | points.push(rim(a)); |
| 795 | colors.push(outerInt); |
| 796 | } |
| 797 | glDrawColoredPoints(points, colors); |
| 798 | } |
| 799 | else |
| 800 | { |
| 801 | // normal canvas 2D rendering method (slower) |
| 802 | ++drawCount; |
| 803 | ++primitiveCount; |
| 804 | drawCanvas2D(pos, size, angle, false, (context)=> |
| 805 | { |
| 806 | const gradient = context.createRadialGradient(0, 0, 0, 0, 0, .5); |
| 807 | gradient.addColorStop(0, colorInner.toString()); |
| 808 | gradient.addColorStop(1, colorOuter.toString()); |
no test coverage detected