如何用Skia4Delphi在TSkLabel下方绘制渐变线条?
使用Skia为TSkLabel添加渐变分隔线
要在TSkLabel下方绘制支持双色过渡或多色彩虹效果的渐变线条,你可以通过两种方式实现:自定义扩展TSkLabel控件,或使用TSkPaintBox配合绘制逻辑。以下是具体实现方案:
方案一:自定义带渐变线的TSkLabel控件
这种方式适合需要重复使用该效果的场景,控件会自动跟随Label的尺寸变化调整线条。
实现代码
unit SkiaLabelWithGradientLine; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, FMX.Types, FMX.Skia, FMX.Controls, FMX.StdCtrls; type TSkLabelWithGradientLine = class(TSkLabel) private FGradientStartColor: TAlphaColor; FGradientEndColor: TAlphaColor; FGradientColors: TAlphaColorArray; FLineHeight: Single; FLineOffset: Single; procedure SetGradientStartColor(const Value: TAlphaColor); procedure SetGradientEndColor(const Value: TAlphaColor); procedure SetGradientColors(const Value: TAlphaColorArray); procedure SetLineHeight(const Value: Single); procedure SetLineOffset(const Value: Single); protected procedure Paint; override; public constructor Create(AOwner: TComponent); override; published property GradientStartColor: TAlphaColor read FGradientStartColor write SetGradientStartColor default TAlphaColors.Blue; property GradientEndColor: TAlphaColor read FGradientEndColor write SetGradientEndColor default TAlphaColors.Cyan; property GradientColors: TAlphaColorArray read FGradientColors write SetGradientColors; property LineHeight: Single read FLineHeight write SetLineHeight default 2; property LineOffset: Single read FLineOffset write SetLineOffset default 4; end; implementation { TSkLabelWithGradientLine } constructor TSkLabelWithGradientLine.Create(AOwner: TComponent); begin inherited; FGradientStartColor := TAlphaColors.Blue; FGradientEndColor := TAlphaColors.Cyan; FLineHeight := 2; FLineOffset := 4; end; procedure TSkLabelWithGradientLine.Paint; var LCanvas: ISkCanvas; LRect: TRectF; LGradient: ISkShader; LPaint: ISkPaint; begin inherited; // 先绘制Label原有文本 // 计算渐变线条的位置与尺寸 LRect := TRectF.Create(0, Height + FLineOffset, Width, Height + FLineOffset + FLineHeight); LCanvas := Canvas; LPaint := TSkPaint.Create; LPaint.Style := TSkPaintStyle.Fill; if Length(FGradientColors) > 0 then begin // 多色渐变模式(如彩虹效果) LGradient := TSkShader.CreateLinearGradient( TPointF.Create(LRect.Left, LRect.Top), TPointF.Create(LRect.Right, LRect.Top), FGradientColors, nil, TSkTileMode.Clamp ); end else begin // 双色渐变模式 LGradient := TSkShader.CreateLinearGradient( TPointF.Create(LRect.Left, LRect.Top), TPointF.Create(LRect.Right, LRect.Top), [FGradientStartColor, FGradientEndColor], nil, TSkTileMode.Clamp ); end; LPaint.Shader := LGradient; LCanvas.DrawRect(LRect, LPaint); end; procedure TSkLabelWithGradientLine.SetGradientEndColor(const Value: TAlphaColor); begin if FGradientEndColor <> Value then begin FGradientEndColor := Value; Repaint; end; end; procedure TSkLabelWithGradientLine.SetGradientStartColor(const Value: TAlphaColor); begin if FGradientStartColor <> Value then begin FGradientStartColor := Value; Repaint; end; end; procedure TSkLabelWithGradientLine.SetGradientColors(const Value: TAlphaColorArray); begin if not CompareMem(@FGradientColors, @Value, Length(Value)*SizeOf(TAlphaColor)) then begin FGradientColors := Value; Repaint; end; end; procedure TSkLabelWithGradientLine.SetLineHeight(const Value: Single); begin if FLineHeight <> Value then begin FLineHeight := Value; Repaint; end; end; procedure TSkLabelWithGradientLine.SetLineOffset(const Value: Single); begin if FLineOffset <> Value then begin FLineOffset := Value; Repaint; end; end; end.
使用方法
- 将上述单元加入项目,在窗体控件面板中找到
TSkLabelWithGradientLine并放置到窗体上。 - 双色渐变:直接设置
GradientStartColor和GradientEndColor属性即可。 - 彩虹渐变:设置
GradientColors为颜色数组,例如:SkLabelWithGradientLine1.GradientColors := [ TAlphaColors.Red, TAlphaColors.Orange, TAlphaColors.Yellow, TAlphaColors.Green, TAlphaColors.Blue, TAlphaColors.Indigo, TAlphaColors.Violet ];
方案二:使用TSkPaintBox快速实现
如果只是临时需求,可在TSkLabel下方放置一个TSkPaintBox,通过其OnPaint事件绘制渐变线。
实现代码
procedure TForm1.SkPaintBox1Paint(Sender: TObject; const ACanvas: ISkCanvas); var LRect: TRectF; LGradient: ISkShader; LPaint: ISkPaint; LRainbowColors: TAlphaColorArray; begin // 同步PaintBox与Label的宽度,设置线条位置 SkPaintBox1.Width := SkLabel1.Width; SkPaintBox1.Position.Y := SkLabel1.Position.Y + SkLabel1.Height + 4; LRect := TRectF.Create(0, 0, SkPaintBox1.Width, 2); LPaint := TSkPaint.Create; LPaint.Style := TSkPaintStyle.Fill; // 可选:双色渐变 { LGradient := TSkShader.CreateLinearGradient( TPointF.Create(LRect.Left, LRect.Top), TPointF.Create(LRect.Right, LRect.Top), [TAlphaColors.Blue, TAlphaColors.Cyan], nil, TSkTileMode.Clamp ); } // 彩虹渐变示例 LRainbowColors := [ TAlphaColors.Red, TAlphaColors.Orange, TAlphaColors.Yellow, TAlphaColors.Green, TAlphaColors.Blue, TAlphaColors.Indigo, TAlphaColors.Violet ]; LGradient := TSkShader.CreateLinearGradient( TPointF.Create(LRect.Left, LRect.Top), TPointF.Create(LRect.Right, LRect.Top), LRainbowColors, nil, TSkTileMode.Clamp ); LPaint.Shader := LGradient; ACanvas.DrawRect(LRect, LPaint); end;
关键知识点
- 线性渐变创建:通过
TSkShader.CreateLinearGradient生成渐变效果,参数支持自定义渐变方向(修改起始/结束点坐标可实现垂直/斜向渐变)。 - 颜色控制:颜色数组可自定义任意数量的颜色,默认均匀分布;若需要指定颜色位置,可传入对应的浮点数组(范围0-1)。
- 线条绘制:将渐变填充到一个高度极小的矩形,模拟线条效果,比直接绘制线条更易控制渐变范围。
内容的提问来源于stack exchange,提问作者Martin Kakhuis
相关产品推荐
相关产品推荐

