How to Add Moving Effects to My Controls in C#

How can I add moving effects to my controls in C#?

Window animation is a built-in feature for Windows. Here's a class that uses it:

using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Runtime.InteropServices;

public static class Util {
public enum Effect { Roll, Slide, Center, Blend }

public static void Animate(Control ctl, Effect effect, int msec, int angle) {
int flags = effmap[(int)effect];
if (ctl.Visible) { flags |= 0x10000; angle += 180; }
else {
if (ctl.TopLevelControl == ctl) flags |= 0x20000;
else if (effect == Effect.Blend) throw new ArgumentException();
}
flags |= dirmap[(angle % 360) / 45];
bool ok = AnimateWindow(ctl.Handle, msec, flags);
if (!ok) throw new Exception("Animation failed");
ctl.Visible = !ctl.Visible;
}

private static int[] dirmap = { 1, 5, 4, 6, 2, 10, 8, 9 };
private static int[] effmap = { 0, 0x40000, 0x10, 0x80000 };

[DllImport("user32.dll")]
private static extern bool AnimateWindow(IntPtr handle, int msec, int flags);
}

Sample usage:

    private void button2_Click(object sender, EventArgs e) {
Util.Animate(button1, Util.Effect.Slide, 150, 180);
}

Animations: Sliding & Fading controls on a C# form (winforms)

Check out the dot-net-transitions project on Google Code. There's now a clone on Github here. It's also available on nuget as dot-net-transitions. It supports a variety of linear/non-linear transitions including composite transitions that can be used for more complex effects such as ripple.

Here is a working sample that demonstrates your desired behavior:

var pictureBox = new PictureBox
{
ImageLocation = "http://icons2.iconarchive.com/icons/klukeart/summer/128/hamburger-icon.png",
SizeMode = PictureBoxSizeMode.AutoSize
};
var textBox = new TextBox
{
Text = "Hello World",
Location = new Point(140, 140)
};
var form = new Form
{
Controls =
{
textBox,
pictureBox
}
};
form.Click += (sender, e) =>
{
// swap the Left and Top properties using a transition
var t = new Transition(new TransitionType_EaseInEaseOut(1000));
t.add(pictureBox, "Left", textBox.Left);
t.add(pictureBox, "Top", textBox.Top);
t.add(textBox, "Left", pictureBox.Left);
t.add(textBox, "Top", pictureBox.Top);
t.run();
};
form.ShowDialog();

How to add animations to windows forms elements?

I have used this APi, its simple and complete documentations is available at
http://code.google.com/p/dot-net-transitions/wiki/CodingWithTransitions

How to add an animation while changing size on control

I think your problem is the following. I assume the panel is already on your screen, and you would like to animate it when some postback happens.

On a postback the complete contents of your page (or an updatepanel, if you use it) is 'refreshed', and to the browser your panel is simply a new DIV, with another height.

What you could do, is manipulate the height with javascript. Then the browser applies the height change to this element, and the transition is triggered.

For example like this:

In the html markup (or via a css class) give your panel a height of 0px, and already apply a transition effect to it:

<asp:Panel id="Top_frame" runat="server" style="height: 0px; transition: height 1s ease 1s;"/>

In your eventhandler send some javascript to the browser:

Page.ClientScript.RegisterStartupScript(this.GetType(), "enlarge", $"<script type=text/javascript>document.getElementById('{Top_frame.ClientID}').style.height = '500px';</script>");

This solution only works if you aren't using UpdatePanels. If you are, you should use a ScriptManager to take care of executing script on postback.

        protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ScriptManager.RegisterClientScriptBlock(Top_frame, Top_frame.GetType(), "enlargefunc", "function enlarge() { document.getElementById('" + Top_frame.ClientID + "').style.height = '500px';}", true);
}
}

protected void Button1_Click(object sender, EventArgs e)
{
ScriptManager.RegisterStartupScript(Top_frame, Top_frame.GetType(), "enlargeexe", $"setTimeout('enlarge()', 50);", true);
}

Also, you should have a ScriptManager element somewhere on your page (probably you have).
Note that 'setTimeout' is used, so the script doesn't execute before the original height (0px) is applied when the UpdatePanel refreshes.

Although this solution works, I recommend that you take another approach: If only the contents in Top_frame is refreshed on postback, put the (or an) UpdatePanel inside Top_frame. In code behind you can update the contents of Top_frame. And you can call 'ScriptManager.RegisterStartupScript' without the setTimeout-trick.

Animated Panel in C#

Okay - here is a really simple example that doesn't depend on the AnimateWindow API:

Add a timer control to your form. On mine, I set the interval to 10 (milliseconds). You can play with this value to smooth out the animation as necessary

I have the button and panel (not visible) on the form

I declared the following private members on the form - they are the start X position of the panel, the end position, and the number of pixels to move per increment - again, tweak to affect speed/smoothness/etc

private int _startLeft = -200;  // start position of the panel
private int _endLeft = 10; // end position of the panel
private int _stepSize = 10; // pixels to move

Then on the button click, I enable the timer:

animationTimer.Enabled = true;

Finally, the code in the timer tick event makes the panel visible, moves it into place, and disables itself when done:

private void animationTimer_Tick(object sender, EventArgs e)
{
// if just starting, move to start location and make visible
if (!photosPanel.Visible)
{
photosPanel.Left = _startLeft;
photosPanel.Visible = true;
}

// incrementally move
photosPanel.Left += _stepSize;
// make sure we didn't over shoot
if (photosPanel.Left > _endLeft) photosPanel.Left = _endLeft;

// have we arrived?
if (photosPanel.Left == _endLeft)
{
animationTimer.Enabled = false;
}
}

Animating a DropShadowEffect on a control

You have to call the BeginAnimation function on the effect and not on the control:

This is the XAML:

<ProgressBar Width="200" Height="30" Name="progressBar1">
<ProgressBar.Effect>
<DropShadowEffect Color="Black" x:Name="effect" >

</DropShadowEffect>
</ProgressBar.Effect>
</ProgressBar>

And here is the Code:

DoubleAnimation da = new DoubleAnimation();
da.From = 10;
da.To = 50;
da.Duration = TimeSpan.FromSeconds(1);
effect.BeginAnimation(DropShadowEffect.BlurRadiusProperty, da);

Animation Effects in WinForms/C#

Don't do it like that.

Create custom control. In custom control, override Paint, and then draw COIN sprite first, then draw mask over it. Be sure that you use double-buffered painting here.

It will work like a charm, trust me!

And, since you are (I gueess) building 5-in-a-row game here, your custom control will be able to paint occupied slots as well.

By designing custom control, you'll be able to hide all the animation and graphics stuff away from your main form.

Simple button animations

So first off, you don't want to do the exact same thing 3 times. Create a single method to add the appropriate handlers for a button, and then just write the code once to handle any given button.

Note that you can go into the expand/contract tick handlers and use the percentComplete value to set the height as well, to move the color along a spectrum (this would involve some mathematics of colors to do though) or to alter any other aspect of the button. If you're really motivated to generalize it you could add a parameter to the method of Action<double> that does something to the object based on the given percent progress.

public void AddAnimation(Button button)
{
var expandTimer = new System.Windows.Forms.Timer();
var contractTimer = new System.Windows.Forms.Timer();

expandTimer.Interval = 10;//can adjust to determine the refresh rate
contractTimer.Interval = 10;

DateTime animationStarted = DateTime.Now;

//TODO update as appropriate or make it a parameter
TimeSpan animationDuration = TimeSpan.FromMilliseconds(250);
int initialWidth = 75;
int endWidth = 130;

button.MouseHover += (_, args) =>
{
contractTimer.Stop();
expandTimer.Start();
animationStarted = DateTime.Now;
button.BackColor = Color.DimGray;
};

button.MouseLeave += (_, args) =>
{
expandTimer.Stop();
contractTimer.Start();
animationStarted = DateTime.Now;
button.BackColor = Color.Red;
};

expandTimer.Tick += (_, args) =>
{
double percentComplete = (DateTime.Now - animationStarted).Ticks
/ (double)animationDuration.Ticks;

if (percentComplete >= 1)
{
expandTimer.Stop();
}
else
{
button.Width = (int)(initialWidth +
(endWidth - initialWidth) * percentComplete);
}
};

contractTimer.Tick += (_, args) =>
{
double percentComplete = (DateTime.Now - animationStarted).Ticks
/ (double)animationDuration.Ticks;

if (percentComplete >= 1)
{
contractTimer.Stop();
}
else
{
button.Width = (int)(endWidth -
(endWidth - initialWidth) * percentComplete);
}
};
}


Related Topics



Leave a reply



Submit