【问题标题】:How to avoid flickering when animating GUI components in Lazarus在 Lazarus 中为 GUI 组件设置动画时如何避免闪烁
【发布时间】:2017-10-03 17:55:28
【问题描述】:

我正在我的 GUI 应用程序中左右移动一个 TMemo 对象。问题是,我的TMemo 中的字母在运动开始时闪烁。

我已经查过了,显然,设置我的主窗体的 DoubleBuffering 属性应该对我有帮助,但它没有。所以我尝试在所有移动的对象上将该属性设置为 true,但仍然存在闪烁。

有没有什么方法可以实现 Lazarus 中 GUI 组件的无闪烁动画?我是拉撒路的新手,所以我现在有点盲目地搜索解决方案。非常感谢您的帮助。

为了提供更多背景信息,以下是我为TMemo 设置动画的方法:我有一个间隔值为10 的TTimer,它的OnTimer 事件连续左右移动我的TMemo。为了让运动稍微平滑一些,我添加了一个简单的余弦插值函数。

最后是代码:

procedure TServerSideForm.ControlPanelHideTimerTimer(Sender: TObject);
begin
  if (hideAnimVal < 1) then
  begin
    hideAnimVal := hideAnimVal + 0.025;
  end
  else
  begin
    MemoHideTimer.Enabled:=false;
  end;


  // hideStart - starting position of my TMemo, hideEnd - end position of my TMemo
  hideCurr := Round(CosineInterpolation(hideStart, hideEnd, hideAnimVal));

  Memo.Left:=hideCurr;
end; 

余弦插值:

function CosineInterpolation(Val1, Val2, Angle: Double): Double;
var
  Percent: Double;
begin
  Percent := (1-Cos(Angle*PI))/2;
  Result := (Val1 * (1 - Percent) + Val2 * Percent);
end;

【问题讨论】:

    标签: user-interface animation lazarus flicker tmemo


    【解决方案1】:

    我会尝试移动图像:

    var
      Memo1dc: hdc;
      Cnv: TCanvas;
      Rct: TRect;
    
    implementation
    
    procedure TForm1.MemoHideTimerTimer(Sender: TObject);
    begin
      if Memo1.Visible then
      begin
        Memo1dc := GetDC(Memo1.Handle);
        Cnv.Handle := Memo1dc;
        Rct.Height := Memo1.Height;
        Rct.Width := Memo1.Width;
        Image1.Left := Memo1.Left;
        Image1.Top := Memo1.Top;
        Image1.Width := Memo1.Width;
        Image1.Height := Memo1.Height;
        Image1.Canvas.CopyRect(Rct, Cnv, Rct);
        Memo1.Visible := False;
        Image1.Visible := True;
      end;
      if (hideAnimVal < 1) then
      begin
        hideAnimVal := hideAnimVal + 0.025;
      end
      else
      begin
        MemoHideTimer.Enabled := False;
      end;
    
      // hideStart - starting position of my TMemo, hideEnd - end position of my TMemo
      hideCurr := Round(CosineInterpolation(hideStart, hideEnd, hideAnimVal));
      Image1.Left := hideCurr;
      if MemoHideTimer.Enabled = False then
      begin
        Memo1.Left := Image1.Left;
        Memo1.Visible := True;
        Image1.Visible := False;
      end;
    end;
    
    procedure TForm1.FormCreate(Sender: TObject);
    begin
       Cnv := TCanvas.Create;
    end; 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多