mirror of
https://github.com/kwsch/PKHeX
synced 2024-11-23 20:43:07 +00:00
92 lines
2.9 KiB
C#
92 lines
2.9 KiB
C#
|
using System;
|
||
|
using System.Drawing;
|
||
|
using System.Timers;
|
||
|
using System.Windows.Forms;
|
||
|
using Timer = System.Timers.Timer;
|
||
|
|
||
|
namespace PKHeX.WinForms.Controls
|
||
|
{
|
||
|
public sealed class BitmapAnimator : Timer
|
||
|
{
|
||
|
public BitmapAnimator(Bitmap baseImage, Bitmap extraLayer = null)
|
||
|
{
|
||
|
GlowBase = baseImage;
|
||
|
ExtraLayer = extraLayer;
|
||
|
Elapsed += TimerElapsed;
|
||
|
}
|
||
|
|
||
|
private readonly Bitmap GlowBase;
|
||
|
private readonly Bitmap ExtraLayer;
|
||
|
private Bitmap[] GlowCache;
|
||
|
private int GlowInterval;
|
||
|
private int GlowCounter;
|
||
|
|
||
|
public int GlowFps { get; set; } = 60;
|
||
|
public Color GlowToColor { get; set; } = Color.LightSkyBlue;
|
||
|
public Color GlowFromColor { get; set; } = Color.White;
|
||
|
private readonly object Lock = new object();
|
||
|
|
||
|
public new void Start() => throw new ArgumentException();
|
||
|
|
||
|
public new void Stop()
|
||
|
{
|
||
|
lock (Lock)
|
||
|
StopTimer();
|
||
|
}
|
||
|
|
||
|
private void StopTimer()
|
||
|
{
|
||
|
Enabled = false;
|
||
|
pb.BackgroundImage = OriginalBackground;
|
||
|
GlowBase.Dispose();
|
||
|
}
|
||
|
|
||
|
private PictureBox pb;
|
||
|
public Image OriginalBackground;
|
||
|
public void Start(PictureBox pbox, Image original)
|
||
|
{
|
||
|
pb = pbox;
|
||
|
OriginalBackground = original;
|
||
|
GlowCache = new Bitmap[GlowFps];
|
||
|
GlowInterval = 1000 / GlowFps;
|
||
|
Interval = GlowInterval;
|
||
|
Enabled = true;
|
||
|
}
|
||
|
|
||
|
private void TimerElapsed(object sender, ElapsedEventArgs elapsedEventArgs)
|
||
|
{
|
||
|
lock (Lock)
|
||
|
{
|
||
|
if (!Enabled)
|
||
|
return; // timer canceled, was waiting to proceed
|
||
|
GlowCounter = (GlowCounter + 1) % (GlowInterval * 2); // loop backwards
|
||
|
int frameIndex = GlowCounter >= GlowInterval ? (GlowInterval * 2) - GlowCounter : GlowCounter;
|
||
|
try
|
||
|
{
|
||
|
var frame = GetFrame(frameIndex);
|
||
|
pb.BackgroundImage = ImageUtil.LayerImage(OriginalBackground, frame, 0, 0, 1);
|
||
|
}
|
||
|
catch
|
||
|
{
|
||
|
StopTimer();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private Bitmap GetFrame(int frameIndex)
|
||
|
{
|
||
|
var frame = GlowCache[frameIndex];
|
||
|
if (frame != null)
|
||
|
return frame;
|
||
|
|
||
|
var elapsedFraction = (double)frameIndex / GlowInterval;
|
||
|
var frameColor = GetFrameColor(elapsedFraction);
|
||
|
frame = ImageUtil.ChangeAllColorTo(GlowBase, frameColor);
|
||
|
if (ExtraLayer != null)
|
||
|
frame = ImageUtil.LayerImage(frame, ExtraLayer, 0, 0, 1);
|
||
|
return GlowCache[frameIndex] = frame;
|
||
|
}
|
||
|
|
||
|
private Color GetFrameColor(double elapsedFraction) => ImageUtil.Blend(GlowToColor, GlowFromColor, elapsedFraction);
|
||
|
}
|
||
|
}
|