首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C# 自定義動態圖像按鈕(二):動畫幀控制與定時器邏輯

     編輯:關於C語言

雙緩衝繪製基礎


private void DynamicImageButton_Paint(object sender, PaintEventArgs e)
{
    g2 = Graphics.FromImage(dblBuffer);
    g2.Clear(BackColor);
    // 計算當前幀矩形
    curX = Width / 6; curY = Height / 6;
    curW = Width * 2 / 3; curH = Height * 2 / 3;
    itvW = (Width - curW) / 2;

    g2.DrawImage(bmp[3], curX, curY, curW, curH); // 繪製最小幀
    g.DrawImageUnscaled(dblBuffer, 0, 0);
}

四幀預生成策略

  • 屬性 Image 設置時,一次性生成 4 種透明度圖片存入 bmp[0..3]。
  • bmp[0] 原圖,bmp[3] 最透明(alpha 180)。
  • 運行時無像素級計算,直接切換預生成幀,極大降低 CPU 佔用。

動畫狀態機


enum MousePosition { Enter, Leave, None }
MousePosition mp = MousePosition.None;

private void Timer_Tick(object sender, EventArgs e)
{
    if (mp == MousePosition.Enter) // 放大、不透明化
    {
        if (curX <= 0 || curY <= 0 || curW >= Width || curH >= Height) { timer.Stop(); return; }

        // 根據 curX 區間選擇對應透明度幀
        if (curX >= itvW - 2) g2.DrawImage(bmp[3], curX - 1, curY - 1, curW + 2, curH + 2);
        else if (curX >= itvW * 2 / 3) g2.DrawImage(bmp[2], curX - 1, curY - 1, curW + 2, curH + 2);
        else if (curX >= itvW / 3) g2.DrawImage(bmp[1], curX - 1, curY - 1, curW + 2, curH + 2);
        else g2.DrawImage(bmp[0], curX - 1, curY - 1, curW + 2, curH + 2);

        g.DrawImageUnscaled(dblBuffer, 0, 0);
        curX--; curY--; curW += 2; curH += 2;
        if (curX <= 0 || curY <= 0 || curW >= Width || curH >= Height) timer.Stop();
    }
    else if (mp == MousePosition.Leave) // 縮小、透明化
    {
        if (curX >= Width / 6 || curY >= Height / 6 || curW <= Width * 2 / 3 || curH <= Height * 2 / 3) { timer.Stop(); return; }

        // 同樣根據區間選幀
        if (curX >= itvW - 2) g2.DrawImage(bmp[3], curX - 1, curY - 1, curW + 2, curH + 2);
        else if (curX >= itvW * 2 / 3) g2.DrawImage(bmp[2], curX - 1, curY - 1, curW + 2, curH + 2);
        else if (curX >= itvW / 3) g2.DrawImage(bmp[1], curX - 1, curY - 1, curW + 2, curH + 2);
        else g2.DrawImage(bmp[0], curX - 1, curY - 1, curW + 2, curH + 2);

        g.DrawImageUnscaled(dblBuffer, 0, 0);
        curX++; curY++; curW -= 2; curH -= 2;
        if (curX >= Width / 6 || curY >= Height / 6 || curW <= Width * 2 / 3 || curH <= Height * 2 / 3) timer.Stop();
    }
}

鼠標事件觸發


protected override void OnMouseEnter(EventArgs e)
{
    mp = MousePosition.Enter;
    timer.Start();
    base.OnMouseEnter(e);
}

protected override void OnMouseLeave(EventArgs e)
{
    mp = MousePosition.Leave;
    timer.Start();
    base.OnMouseLeave(e);
}

關鍵設計總結

  1. 預計算幀:屬性設置時完成透明度渲染,運行時僅切換 DrawImage。
  2. 幾何插值:curX/curY/curW/curH 線性變化,配合區間選幀實現大小與透明度同步動畫。
  3. 雙緩衝:dblBuffer 避免閃爍,DrawImageUnscaled 直接輸出到屏幕。
  4. 邊界檢查:每幀檢查是否到達目標狀態,到達即停止定時器。

環境驗證

Windows XP SP3 + VS2005 C# SP1 編譯調試通過。現代 .NET 同樣適用,建議將 Timer 替換為 System.Windows.Forms.Timer 或 WPF DispatcherTimer。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved