Re: Circular Ring Gradient
Olaf Schmidt <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <[email protected]> |
Am 11.05.2017 um 01:08 schrieb [email protected]: > Still stuck with the problem of starting and stopping a gradient in an arc at discrete points in the arc. I haven't figured out how to "sweep" a gradient color through a ring arc in a smooth fashion. That would make a gauge widget a little more adjustable wirh a standardized scale. FWIW, ... what I'm using for years (for "conical stuff") is based on cairo-functionality, which existed already before the mesh-patterns were introduced. It's a short and simple function, which allows (in the arguments StartDeg, and DistDeg), to specify also a Start-Angle and an Angle-Distance (in degrees). '---- VBScript-Code, based on the cairo-COM-wrapper for Windows ---- Function CreateRingSrf(Size, Radius1, Radius2, StartDeg, DistDeg, SpArr) Dim Steps, Pat, i Steps = Size * DistDeg / 360 * Cairo.PI * 2 Set Pat = Cairo.CreateLinearPattern(1, 0, 2 * Steps - 1, 0) For i = 0 To UBound(SpArr) Pat.AddColorStop i / UBound(SpArr), SpArr(i) Next With Cairo.CreateSurface(Size, Size).CreateContext .SetLineCap 1 '<- 1 = CAIRO_LINE_CAP_ROUND .SetLineWidth 1.35 .TranslateDrawings Size / 2, Size / 2 .RotateDrawingsDeg StartDeg + DistDeg / Steps * 0.5 - 90 Set Pat.Matrix = Pat.Matrix.TranslateCoords(1, 0) For i = 1 To Steps .MoveTo 0, Radius1 + .GetLineWidth .LineTo 0, Radius2 - .GetLineWidth .Stroke 0, (Pat) '<- Stroke with a shifted Source-Pattern .RotateDrawingsDeg DistDeg / Steps Set Pat.Matrix = Pat.Matrix.TranslateCoords(2, 0) Next Set CreateRingSrf = .Surface 'return the Surface to the caller End With End Function Dim Cairo: Set Cairo = CreateObject("vbRichClient5.cConstructor").Cairo Dim SpArr: SpArr=Array(vbRed, vbYellow, vbGreen, vbCyan, vbBlue, _ vbYellow, vbGreen, vbCyan, vbRed) CreateRingSrf(300,60,120,0,360,SpArr).WriteContentToPngFile "RingCon.png" '---- end of VBScript-Code ---- The above will produce basically the same thing as the other examples: http://vbRichClient.com/Downloads/RingCon.png ... and it should be translatable to the C-Flat-API quite easily. When I use this stuff in a gauge-widget, I'm calculating the Conical-Surface once for the given WidgetSize - and then use it as the SourceSurface, doing a simple Arc + Stroke on that (unchanging) Source with a proper LineWidth. So, to calculate a "Cold-to-Hot" Gauge-Scale, which range-wise covers two/thirds of the full-circle when at 100%, you would use the above function with the following Parameters: Const StartDeg = 60 + 90, DistDeg = 240 '<- 2/3 of a full circle SpectArr = Array(vbCyan, vbBlue, vbMagenta, vbRed, vbYellow) Set RingSrf = CreateRingSrf(240, 70, 90, StartDeg, DistDeg, SpectArr) RingSrf.WriteContentToPngFile "GaugeScale.png" Producing: http://vbRichClient.com/Downloads/GaugeScale.png HTH Olaf -- cairo mailing list [email protected] https://lists.cairographics.org/mailman/listinfo/cairo