お世話になります。
Delphi11.3でFMXアプリケーションを作成しています。
TRectAngleにFloatAnimationを配置しまして、TRectAngleの上にマウスが乗った時点でTRectAngleの幅を広くするアニメーションはビジュアルにできました。
なのですが、TRectAngleが複数ありまして同じ設定を幾つも行うのは大変なので、動的に割当られないかと次のコードを書いてみました。
::::割愛致します:::
var
ChildRect: array[0..CST_RECT_COUNT-1] of TRectAngle;
WidthAni: array[0..CST_RECT_COUNT-1] of TFloatAnimation;
procedure TFrmMenu.FormCreate(Sender: TObject);
begin
for var i := 0 to High(ChildRect) do
begin
ChildRect[i] := TRectAngle(FindComponent('RectBtn' + IntToStr(i)));
WidthAni[i] := TFloatAnimation.Create(ChildRect[i]);
WidthAni[i].Parent := ChildRect[i];
WidthAni[i].AnimationType := TAnimationType.In;
WidthAni[i].Duration := 0.1;
WidthAni[i].PropertyName := 'Size.Width';
WidthAni[i].StartValue := ChildRect[i].Width;
WidthAni[i].StopValue := WidthAni[i].StartValue + 20;
WidthAni[i].Trigger := 'IsMouseOver=true';
WidthAni[i].TriggerInverse := 'IsMouseOver=false';
WidthAni[i].Enabled := True;
end;
end;
上記を実行してTRectAngleの上にマウスを乗せても無反応です。
ビジュアルに配置/設定すると上手く行くので、その差が何かを見てみたところ少しだけヒントが分かりました。
TRectAngleのSizeプロパティ(ここでは、さらにWidthですね)にFloatAnimationが関連していることに。。。合ってますかね(汗)。
恐らくこれが原因ではないかと思うのですが、これを記述する方法が分からず、すみませんがどなたか教えて頂けると助かります。
自己レスです。
TRectAngleのOnMouseMoveイベントで次の様に書くことでアニメーションできました。
TAnimator.AnimateFloat(RctMenu10, 'Width', 279, 0.1,
TAnimationType.&In, TInterpolationType.Linear);
何とか、解決方法は見つける事ができましたが、これ以外の方法がありましたら、引き続き情報お待ちしております。
これ以外の方法ではありませんが、
そこは、OnMouseMoveイベントではなく、OnMouseEnterイベントに記述した方が良いと思います。
・OnMouseMoveイベントに記述した場合、コンポーネント上でマウスを移動させる度に、毎回イベントが走ってしまいます。
・OnMouseEnterイベントに記述した場合、コンポーネント上にマウスが乗った時、1度だけイベントが走ります。
Moeさんのコードでサンプルを作成してみました。
「FMXコード」
unit Unit1;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects, FMX.Ani;
type
TForm1 = class(TForm)
Rectangle1: TRectangle;
Rectangle2: TRectangle;
Rectangle3: TRectangle;
procedure FormCreate(Sender: TObject);
procedure RectangleMouseEnter(Sender: TObject);
procedure RectangleMouseLeave(Sender: TObject);
private
{ private 宣言 }
public
{ public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.fmx}
const
LENGTH_DEF = 50; // 通常の大きさ
LENGTH_MAX = 70; // 引き延ばした大きさ
procedure TForm1.FormCreate(Sender: TObject);
begin
// ここはオブジェクトインスペクタで設定しても良い
Rectangle1.OnMouseEnter := RectangleMouseEnter;
Rectangle1.OnMouseLeave := RectangleMouseLeave;
Rectangle2.OnMouseEnter := RectangleMouseEnter;
Rectangle2.OnMouseLeave := RectangleMouseLeave;
Rectangle3.OnMouseEnter := RectangleMouseEnter;
Rectangle3.OnMouseLeave := RectangleMouseLeave;
end;
procedure TForm1.RectangleMouseEnter(Sender: TObject);
begin
TAnimator.AnimateFloat(TRectangle(Sender), 'Width', LENGTH_MAX, 0.1, TAnimationType.In, TInterpolationType.Linear);
end;
procedure TForm1.RectangleMouseLeave(Sender: TObject);
begin
TAnimator.AnimateFloat(TRectangle(Sender), 'Width', LENGTH_DEF, 0.1, TAnimationType.In, TInterpolationType.Linear);
end;
end.
アニメーションを終了させる値に、TRectangle(Sender).Width + 20 等と行わず、定数値で指定している理由は、
素早くマウスを動かすと、TRectangle の幅が徐々に変わって行ってしまうからです。
KONNOYAさん
ありがとうございます。
確かにOnMouseMoveよりもOnMouseEnterが良いですよね。
また、仰る通り横幅は固定に修正しないと、動かす度に増幅されて大変な事になりました(汗。
お蔭様で少し動きが良くなりました。
本件をクローズさせて頂きます。
ありがとうございました。
ツイート | ![]() |