是否可以使用Delphi和VCL进行过渡(例如,单击时红色按钮变为绿色)?类似于CSS过渡...
答案 0 :(得分:2)
标准TButton
不支持您的要求。默认情况下,它是从操作系统而不是VCL获取颜色的。
您需要一个所有者绘制的按钮来更改颜色,例如TBitBtn
或TSpeedBtn
,否则您可以继承TButton
来手动启用BS_OWNERDRAW
窗口样式和处理WM_DRAWITEM
通知。或使用第三者皮肤框架。或者,如果您的IDE支持VCL样式,则使用它们。
无论哪种方式,一旦有了一个可以改变颜色的按钮,就可以简单地使用TTimer
来根据需要为从一种颜色到另一种颜色的动画设置动画。
答案 1 :(得分:2)
这是我进行的快速研究的结果
然后将所有这些结合起来就可以了
并且您可以看到我对Java答案的翻译不是那么好,但这将是一个不同的问题。您问如何转换按钮,这就是您的答案
unit NCRSpeedButton;
interface
uses
Winapi.Windows, Vcl.Controls, Winapi.Messages, Vcl.Graphics, System.Classes, AnimateEasing;
type
TButtonState = (bs_Down, bs_Normal, bs_Active);
TNCRSpeedButton = class(TGraphicControl)
private
FEasingAnimation: TAnimateEasing;
FColor: TColor;
FFromColor : TColor;
FToColor : TColor;
FBorderColor: TColor;
procedure CMMouseDown(var Message: TMessage); message WM_LBUTTONDOWN;
procedure CMMouseUp(var Message: TMessage); message WM_LBUTTONUP;
procedure SetBorderColor(aBorderColor: TColor);
procedure SetFromColor(const Value: TColor);
procedure SetToColor(const Value: TColor);
procedure AnimateTickEvent(Sender: TObject; Value: Extended);
procedure ANotifyEvent(Sender: TObject);
protected
procedure Paint; override;
public
Constructor Create(Owner: TComponent); override;
Destructor Destroy; override;
published
property FromColor: TColor read FFromColor write SetFromColor;
property ToColor: TColor read FToColor write SetToColor;
property BorderColor: TColor read FBorderColor write SetBorderColor;
property ParentShowHint;
property ParentBiDiMode;
property PopupMenu;
property ShowHint;
property Visible;
property OnClick;
property OnDblClick;
property OnMouseActivate;
property OnMouseDown;
property OnMouseEnter;
property OnMouseLeave;
property OnMouseMove;
property OnMouseUp;
end;
implementation
Uses
System.Math,
System.UITypes;
{ TNCRSpeedButton }
Constructor TNCRSpeedButton.Create(Owner: TComponent);
begin
inherited Create(Owner);
FColor := clBtnFace;
FBorderColor := clBlue;
SetBounds(0, 0, 200, 50);
FEasingAnimation := TAnimateEasing.Create;
FEasingAnimation.OnTick := AnimateTickEvent;
FEasingAnimation.OnFinish := ANotifyEvent;
end;
Destructor TNCRSpeedButton.Destroy;
begin
FEasingAnimation.Free;
inherited;
end;
procedure TNCRSpeedButton.Paint;
begin
Canvas.Brush.Color := FColor;
Canvas.FillRect(ClientRect);
// Drawing Borders
Canvas.Pen.Color := FBorderColor;
Canvas.MoveTo(0, 0);
Canvas.LineTo(Width-1, 0);
Canvas.LineTo(Width-1, Height-1);
Canvas.LineTo(0, Height-1);
Canvas.LineTo(0, 0);
end;
procedure TNCRSpeedButton.AnimateTickEvent(Sender: TObject; Value: Extended);
var
Ratio: Integer;
begin
Ratio := 1 - Floor(Value);
TColorRec(FColor).R := Floor((Ratio * TColorRec(FToColor).R) + ((1 - Ratio) * TColorRec(FFromColor).R));
TColorRec(FColor).G := Floor((Ratio * TColorRec(FToColor).G) + ((1 - Ratio) * TColorRec(FFromColor).G));
TColorRec(FColor).B := Floor((Ratio * TColorRec(FToColor).B) + ((1 - Ratio) * TColorRec(FFromColor).B));
Invalidate;
end;
procedure TNCRSpeedButton.ANotifyEvent(Sender: TObject);
begin
FColor := FToColor;
Invalidate;
end;
procedure TNCRSpeedButton.CMMouseDown(var Message: TMessage);
begin
inherited;
Invalidate;
end;
procedure TNCRSpeedButton.CMMouseUp(var Message: TMessage);
begin
inherited;
Invalidate;
FColor := FFromColor;
FEasingAnimation.Animating(0, 500, 2000, TEasingType.etBackEaseIn);
end;
procedure TNCRSpeedButton.SetBorderColor(aBorderColor: TColor);
begin
FBorderColor := aBorderColor;
Invalidate;
end;
procedure TNCRSpeedButton.SetFromColor(const Value: TColor);
begin
FColor := Value;
FFromColor := Value;
Invalidate;
end;
procedure TNCRSpeedButton.SetToColor(const Value: TColor);
begin
FToColor := Value;
Invalidate;
end;
end.
在转换过程中,我将保留如何解决黑色的问题:)。