Reputation: 359
I want to apply animation to my button when pressing button. In WPF I can use Storyboard
with triggers to create animation. Here is an example:
<Storyboard x:Key="AniOpacityDelay">
<DoubleAnimation
Storyboard.TargetName="background"
Storyboard.TargetProperty="Opacity"
AutoReverse="True"
To="0.65"
Duration="0:0:0.2"/>
</Storyboard>
and:
<ColorAnimationUsingKeyFrames
Storyboard.TargetName="Itemcont"
Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="0" Value="#EEEEEE"/>
</ColorAnimationUsingKeyFrames>
Windows Forms doesn't have Storyboard
and triggers. How to make smooth animation in Windows Forms?
Here's my code for Windows Forms:
void DelayTime()
{
timer = new Timer();
timer.Interval = (int)System.TimeSpan.FromSeconds(this.DelayTime).TotalMilliseconds;
timer.Tick += (s, es) =>
{
this.mouseover = false;
this.Cursor = Cursors.Hand;
this.Enabled = true;
};
timer.Start();
}
protected override void OnMouseDown(MouseEventArgs mevent)
{
base.OnMouseDown(mevent);
mouseover = true;
this.Enabled = false;
DelayTime();
}
protected override void OnPaint(PaintEventArgs e)
{
Color bg = this._Background;
bg = mouseover ? this._HoverColor : this._Background;
e.Graphics.FillRectangle(new SolidBrush(bg), this.ClientRectangle);
}
Upvotes: 6
Views: 5031
Reputation: 125322
The basic idea is using a Timer
and alpha-blending the glow color with original background color.
For example you can set FlatStyle
of the button to Flat
and override OnMouseEnter
and OnMouseLeave
. In OnMouseEnter
start the timer and in and OnMouseLeave
stop the timer. In timer Tick
event you can set the MouseOverBackColor
of FlatAppearance
of button to a color which you increase it's alpha channel in Tick
event.
Glow Button Code
using System;
using System.Drawing;
using System.Windows.Forms;
public class GlowButton : Button
{
Timer timer;
int alpha = 0;
public Color GlowColor { get; set; }
public GlowButton()
{
this.DoubleBuffered = true;
timer = new Timer() { Interval = 50 };
timer.Tick += timer_Tick;
this.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.GlowColor = Color.Gold;
this.FlatAppearance.MouseDownBackColor = Color.Gold;
}
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
this.FlatAppearance.MouseOverBackColor = CalculateColor();
timer.Start();
}
protected override void OnMouseLeave(EventArgs e)
{
base.OnMouseLeave(e);
timer.Stop();
alpha = 0;
this.FlatAppearance.MouseOverBackColor = CalculateColor();
}
void timer_Tick(object sender, EventArgs e)
{
int increament = 25;
if (alpha + increament < 255) { alpha += increament; }
else { timer.Stop(); alpha = 255; }
this.FlatAppearance.MouseOverBackColor = CalculateColor();
}
protected override void Dispose(bool disposing)
{
if (disposing) timer.Dispose();
base.Dispose(disposing);
}
private Color CalculateColor()
{
return AlphaBlend(Color.FromArgb(alpha, GlowColor), this.BackColor);
}
public Color AlphaBlend(Color A, Color B)
{
var r = (A.R * A.A / 255) + (B.R * B.A * (255 - A.A) / (255 * 255));
var g = (A.G * A.A / 255) + (B.G * B.A * (255 - A.A) / (255 * 255));
var b = (A.B * A.A / 255) + (B.B * B.A * (255 - A.A) / (255 * 255));
var a = A.A + (B.A * (255 - A.A) / 255);
return Color.FromArgb(a, r, g, b);
}
}
Upvotes: 8
Reputation: 175
The nearest you will get with winforms is probably making it DoubleBuffered. WinForms isn't very good for animations.
If you're using a custom control, add this under Initialize();
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
Otherwise, make the form DoubleBuffered in the properties, or by code:
DoubleBuffered = true;
Then to create the animation(if you haven't already figured that out), do a loop checking if the animation is completed(in the timer event).
Upvotes: 1