[cairo] Circular Ring Gradient
Olaf Schmidt
ng at vbRichClient.com
Sun May 14 00:03:19 UTC 2017
Am 11.05.2017 um 01:08 schrieb cecashon at aol.com:
> 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
More information about the cairo
mailing list