You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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.

使用方法

  1. 将上述单元加入项目,在窗体控件面板中找到TSkLabelWithGradientLine并放置到窗体上。
  2. 双色渐变:直接设置GradientStartColor和GradientEndColor属性即可。
  3. 彩虹渐变:设置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:14:59