I simply have an Image, and I set its width and height by assigning some numbers. For example, First Height and Width: 400 x 800. Second Height and Width: 200 x 400.
So if you do such a mainstreamed thing, there won't be any transition when resizing it, it just gets smaller immediately in a blink of eye. But I want it to resize between those "specific" measurements by transition (or animating) in 1 or 2 seconds.
I know Microsoft Expression Blend do some storyboards, but I could not do this by data binding. I databinded this image with a value, when the value changes, image resizes also. But I could not record any storyboard to create a transition.
What do you suggest me to do?
Thanks
I think something along the lines of this might work...
private void buttonStart_Click(object sender, RoutedEventArgs e)
{
CreateAnimation(400, 200).Begin();
}
private Storyboard CreateAnimation(double from, double to)
{
Storyboard sb = new Storyboard();
DoubleAnimation Animation = new DoubleAnimation();
Animation.From = from;
Animation.To = to;
Animation.Duration = new Duration(TimeSpan.FromSeconds(1.0));
Storyboard.SetTarget(Animation, ITEMNAME);
Storyboard.SetTargetProperty(Animation, new PropertyPath("(Width)"));
sb.Children.Add(Animation);
return sb;
}
Just create two double animations for the height and width to use simultaneously.
Related
I'm looking for a solution to my WPF project.
I've an User Control with 2 different widget inside.
The first one animates the second with this function and the animation works fine:
private void expandTable(UIElement expandleft)
{
DoubleAnimation da = new DoubleAnimation(0, 700, TimeSpan.FromSeconds(0.5));
da.AutoReverse = false;
expandleft.BeginAnimation(Button.WidthProperty, da);
}
The point is: this user control is into a StackPanel on another page and what I want to do is animate the width of this StackPanel with the same animation.
But the above animation doesn't work as I want because the width of my StackPanel has to change according to the Width of the UserControl which in turn depends on the animation of the first Widget.
My answer is: how can I do something like that?:
private void expandStack(UIElement expand)
{
DoubleAnimation db = new DoubleAnimation(0, **auto**, TimeSpan.FromSeconds(0.5));
db.AutoReverse = false;
expan.BeginAnimation(StackPAnel.WidthProperty, db);
}
Hope I was clear.
Thanks to everyone!
I am trying to use some animations to make my application feel good. But I could not help the choppy animation that no matter what I do, it is always end up stuttering.
Take a look:
DoubleAnimation anim = new DoubleAnimation()
{
//ht is height of DockPanel, I wanted to start from 200 less than Actual DockPanel Height
From = ht - 200,
To = ht,
Duration = TimeSpan.FromSeconds(1),
AccelerationRatio = 0.5,
DecelerationRatio = 0.5
};
x.BeginAnimation(HeightProperty, anim);
//x is the UserControl
Also, what I need to animate is a custom UserControl, which contains some text like 100 words and bunch of Images. I just want to make it grow in to the height of the current DockPanel as soon it is loaded.
What I saw by searching for the solution is this,
Timeline.SetDesiredFrameRate(anim, 10);
Even trying any value in there nothing really happens.
Framerate is like the frame rate of a film.
A low frame rate will give you a choppy film or a choppy animation.
Using a dockpanel is probably a bad idea for some content you are going to animate, because it will try and adjust things every time your height changes.
I suggest you go with a grid instead.
You should use a scaletransform. Partly because as you animate height you will find all the content of your usercontrol have their measures invalidated and they will want to start off the whole measure arrange cycle many times.
If you're thinking measure arrange? Then read up on how the wpf layout system works.
I would also advise you to use xaml rather than code.
Here's some code to think about:
private void StartAnimate_Click(object sender, RoutedEventArgs e)
{
var tran = testRectangle.RenderTransform = new ScaleTransform(1d, 1d)
{
CenterX = 0.5d,
CenterY = 0.5d
};
var anim = new DoubleAnimation
{
To = 1.0,
From=0,
Duration = TimeSpan.FromSeconds(0.5d),
DecelerationRatio = 0.5d,
FillBehavior = FillBehavior.Stop
};
tran.BeginAnimation(
ScaleTransform.ScaleYProperty,
anim,
HandoffBehavior.Compose);
}
I put a rectangle and my button in a dockpanel to prove this works.
<DockPanel>
<Rectangle Fill="Blue" Name="testRectangle"
Width="500"
/>
<Button Content="Animate"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Name="StartAnimate"
Click="StartAnimate_Click" />
</DockPanel>
A rectangle is pretty simple but it animates smoothly.
I am trying to do a basic animation using the DoubleAnimation class in WPF. On a button click the rectangle spins. The cs code is
DoubleAnimation da = new DoubleAnimation();
da.From = 0; // start from 0 to 360, full circle
da.To = 360;
da.Duration = new Duration(TimeSpan.FromSeconds(0.5));
da.RepeatBehavior = RepeatBehavior.Forever;
RotateTransform rt = new RotateTransform();
rectangle1.RenderTransform = rt;
rt.BeginAnimation(RotateTransform.AngleProperty, da);
What i am trying to do is to update the da.Duration = new Duration(TimeSpan.FromSeconds(0.5)) value with the slider value.
Tried with slider value binding, but not able to get this correctly.
Changing the Duration is not enough. How fast the animation is controlled by the inner AnimationClock. This clock is initialized just once after you call BeginAnimation(). So you have to update the inner AnimationClock by using ApplyAnimationClock() method.
Also note that you should also set the From property to the currently animated value, so that when changing the Slider's Value, the Angle will be animated smoothly (without restarting from 0):
//The ValueChanged handler for your Slider
private void slider_ValueChanged(object sender,
RoutedPropertyChangedEventArgs e){
da.Duration = new Duration(TimeSpan.FromMilliseconds(yourSlider.Value));
da.From = rt.Angle;
rt.ApplyAnimationClock(RotateTransform.AngleProperty, da.CreateClock());
}
Note that I suppose the slider's Value corresponds to the number of milliseconds, so the Maximum value of the Slider should be large enough (about several thousands) if you don't want your Rectangle to be rotated super fast. Also all the variables you declared should be able to access inside the ValueChanged handler.
One more important note is you should use By property here instead of To, like this:
da.By = 360;
That way you can just update the From without caring about the To (it is always 360 degrees rotated).
I have a method that enables me to animate objects that have to do with a DoubleAnimation:
public void animDouble(DependencyObject target, DependencyProperty property, double to, TimeSpan duration, double? from = null, TimeSpan? beginTime = null, IEasingFunction e = null)
{
DoubleAnimation animation = new DoubleAnimation();
animation.To = to;
if (beginTime == null)
beginTime = TimeSpan.FromSeconds(0);
if (from != null)
animation.From = from;
animation.BeginTime = beginTime;
animation.Duration = duration;
if (e != null)
animation.EasingFunction = e;
//start animating
Storyboard.SetTarget(animation, target); // what object will be animated?
Storyboard.SetTargetProperty(animation, new PropertyPath(property)); // what property will be animated
Storyboard sb = new Storyboard();
sb.Children.Add(animation);
sb.Begin();
}
so if I have a boarder called br1 for example and I want to animate it's height I will call the method as:
animDouble(br1, FrameworkElement.HeightProperty, 150, TimeSpan.FromSeconds(5));
if I want to animate it's width I will do:
animDouble(br1, FrameworkElement.WidthProperty, 150, TimeSpan.FromSeconds(5));
I could also animate it's visibility with the same method.
for some reason I am not able to animate its x property in order to translate it along the x axis or y-axis. When I call the method as:
a.animDouble(br1, TranslateTransform.XProperty, 150, TimeSpan.FromSeconds(5));
the boarder does not animates. I don't get any errors aether.
Somehow i would have expected an error, well, anyway, the Border owns no such property, if you want to move your control you need to set the RenderTransform or LayoutTransform of the border to a TranslateTransform, then you can pass the transform itself into the method as target.
(The whole storyboard is awfully redundant as you only have one animation, you can just call BeginAnimation on the target itself)
It had to do with registering the name. I found a link in here
I don't know what the method registerName does but I guess I needed it. from the page I managed to get the basic animations. I where not able to animate two things at once SOMETIMES. if you are interested in seeing the method take a look tat this question. I think it is a prety nice class that will enable to create animations with code. copy the namespace to visual studio and copy the first example that I posted so that you can see how it works.
I'm learning WPF and have a specific goal.
Imagine you have a grid (3 rows by 3 columns), and a control, say a simple blue rectangle fills the middle cell. When I click on the cell I want the square to rotate smoothly through 180 degrees.
The specific issue I have at the moment is; as the rectangle rotates, it won't change its dimensions, so it will extend beyond the boundary of the cell. I don't want it to clip, i want it to appear on top, partially obscuring surrounding cells.
The second part of this is, if there is one cell that fills the entire window, and I click on the blue rectangle in that cell, can I make the rectangle rotate and extend beyond the sides of the form?
If that doesn't make sense, please ask. I'm finding it hard to google because I don't know the exact terms I should be using.
Thank you
The first part can be acomplished by using the attached property Panel.ZIndex, set it to a high value when you start the animation and a lower value when the animation is complete. The second part (having a control outside of the window) is more complicated. I tried a few things and this method seemed to be the best. It uses a full screen window instead of a Popup as I encountered cliping issues. A copy of the element is made using RenderTargetBitmap this is then placed in the same position. The original element is hidden whilst the copy is animated.
public void PopupAnimation(UIElement element)
{
double w = element.RenderSize.Width,h = element.RenderSize.Height;
var screen = new Canvas();
var pos = element.PointToScreen(new Point(0, 0));
var rtb = new RenderTargetBitmap((int)w,(int)h, 96, 96, PixelFormats.Pbgra32);
rtb.Render(element);
Image i = new Image { Source = rtb, Width = w, Height = h,Stretch=Stretch.Fill};
Canvas.SetLeft(i, pos.X);
Canvas.SetTop(i, pos.Y);
screen.Children.Add(i);
var window = new Window() {
Content = screen, AllowsTransparency = true,
Width=SystemParameters.PrimaryScreenWidth,Height=SystemParameters.PrimaryScreenHeight,
WindowStyle=WindowStyle.None,ShowInTaskbar=false,Topmost=true,
Background=Brushes.Transparent,ShowActivated=false,Left=0,Top=0
};
var transform = new RotateTransform();
i.RenderTransformOrigin = new Point(0.5, 0.5);
i.RenderTransform = transform;
var anim = new DoubleAnimation { To = 360 };
anim.Completed += (s,e) =>
{
element.Visibility = Visibility.Visible;
var delay = new Storyboard { Duration = TimeSpan.FromSeconds(0.1) };
delay.Completed += (s2, e2) => window.Close();
delay.Begin();
};
window.ContentRendered += (s, e) =>
{
transform.BeginAnimation(RotateTransform.AngleProperty, anim);
element.Visibility = Visibility.Hidden;
};
window.Show();
}