How to achieve a background image continuous move in wpf - c#

I have a background image in my wpf application, I want to achieve a effect of the background image continuous move. The following code can achieve a simple effect, but when the time of the end of the picture moves over again, I want to make this picture the effect of the movement has been the phenomenon does not come to a halt.
void StartBackgroudMove()
{
Storyboard sb = new Storyboard();
DoubleAnimation TranslateXExtendAnimation = new DoubleAnimation() { From = 0, To = -100, Duration = TimeSpan.FromMilliseconds(2500) };
Storyboard.SetTarget(TranslateXExtendAnimation, BackgroundImage);
Storyboard.SetTargetProperty(TranslateXExtendAnimation, new PropertyPath("(FrameworkElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"));
sb.Children.Add(TranslateXExtendAnimation);
sb.FillBehavior = FillBehavior.Stop;
sb.Completed += (s, args) =>
{
this.StartBackgroudMove();
};
sb.Begin();
}

You may use an ImageBrush with TileMode set to Tile and animate its Viewport property:
<Grid>
<Grid.Background>
<ImageBrush ImageSource="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"
Stretch="Fill" TileMode="Tile"
ViewportUnits="Absolute" Viewport="0,0,1024,768"/>
</Grid.Background>
<Grid.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<RectAnimation Storyboard.TargetProperty="Background.Viewport"
To="-1024,0,1024,768" Duration="0:0:10"
RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
</Grid>
The following alternative solution places two adjacent images in a Canvas and animates the Canvas' RenderTransform property.
<Grid>
<Canvas>
<Canvas.RenderTransform>
<TranslateTransform x:Name="translation"/>
</Canvas.RenderTransform>
<Image Stretch="None"
Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"/>
<Image Canvas.Left="1024" Stretch="None"
Source="C:\Users\Public\Pictures\Sample Pictures\Desert.jpg"/>
</Canvas>
<Grid.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="X"
Storyboard.TargetName="translation"
To="-1024" Duration="0:0:10"
RepeatBehavior="Forever"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
</Grid>

You can set the Storyboard.RepeatBehavior to RepeatBehavior.Forever
Example:
void StartBackgroudMove()
{
Storyboard sb = new Storyboard();
DoubleAnimation TranslateXExtendAnimation = new DoubleAnimation() { From = 0, To = -100, Duration = TimeSpan.FromMilliseconds(2500) };
Storyboard.SetTarget(TranslateXExtendAnimation, BackgroundImage);
Storyboard.SetTargetProperty(TranslateXExtendAnimation, new PropertyPath("(FrameworkElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"));
sb.Children.Add(TranslateXExtendAnimation);
sb.FillBehavior = FillBehavior.Stop;
sb.RepeatBehavior = RepeatBehavior.Forever;
sb.Begin();
}

Related

Is it doable to create motion path by cloning object alongside the path while moving in WPF?

I can create animation to create an object to move along the motion path. But I wonder, is it doable to have multiple object/path like moving by cloning itself?
Assume this is my map:-
I want to go from current location to the playground. I have a path and assign it to be motion path for my object(navigation arrow) to move alongside the line path. And for the curiosity, I want it to be like below:-
Currently, using the motion path, the arrow can moving in single object:-
UPDATED
Code:
<Grid>
<Path x:Name="SuperPath" Stroke="Black">
<Path.Data>
<PathGeometry Figures="M277,66 C277,66 427,87 447,153 466,219 396,241 397,297 399,352 439,376 439,376" />
</Path.Data>
</Path>
<Path
x:Name="Arrowhead"
Width="23"
Height="19.5"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Data="M94,29 L117,39 95,49 99,38 z"
Fill="#ff387cc0"
Stretch="Fill">
<Path.RenderTransform>
<TransformGroup>
<TranslateTransform X="-10" Y="-10" />
<MatrixTransform x:Name="rectangleTransform">
<MatrixTransform.Matrix>
<Matrix />
</MatrixTransform.Matrix>
</MatrixTransform>
</TransformGroup>
</Path.RenderTransform>
<Path.Triggers>
<EventTrigger RoutedEvent="Path.Loaded">
<BeginStoryboard>
<Storyboard>
<MatrixAnimationUsingPath
DoesRotateWithTangent="True"
RepeatBehavior="Forever"
Storyboard.TargetName="rectangleTransform"
Storyboard.TargetProperty="Matrix"
Duration="00:00:3">
<MatrixAnimationUsingPath.PathGeometry>
<PathGeometry PresentationOptions:Freeze="True" Figures="M277,66 C277,66 427,87 447,153 466,219 396,241 397,297 399,352 439,376 439,376" />
</MatrixAnimationUsingPath.PathGeometry>
</MatrixAnimationUsingPath>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Path.Triggers>
</Path>
</Grid>
How do each time arrowhead moving through path, it can leave a copy of the arrow trail like a navigation trail so it will be something for example 30 arrowhead with distance between it along the trail path.
First of all, simplify the XAML a bit:
<Canvas x:Name="canvas">
<Canvas.Resources>
<PathGeometry
x:Key="pathToFollow"
Figures="M73.517,48.931 C73.517,48.931 253.690,80.828 245.931,161.000 C238.172,241.172 114.897,261.000 221.793,350.655"/>
<Storyboard x:Key="arrowheadAnimation">
<MatrixAnimationUsingPath
Storyboard.TargetName="arrowhead"
Storyboard.TargetProperty="RenderTransform.Matrix"
PathGeometry="{StaticResource pathToFollow}"
DoesRotateWithTangent="True"
Duration="0:0:5"/>
</Storyboard>
</Canvas.Resources>
<Path Data="{StaticResource pathToFollow}"
Stroke="#ff818181" StrokeThickness="6.0" StrokeDashArray="4.33"
StrokeStartLineCap="Round" StrokeEndLineCap="Round"/>
<Path x:Name="arrowhead"
Data="M0,0 L-10,-10 30,0 -10,10 Z"
Fill="#ff387cc0">
<Path.RenderTransform>
<MatrixTransform/>
</Path.RenderTransform>
</Path>
</Canvas>
Now there may be the following code behind that starts the animation in a Loaded event handler. In addition, it creates a timer that creates copies of the arrow head at certain times.
private readonly Storyboard storyboard;
private readonly DispatcherTimer timer;
public MainWindow()
{
InitializeComponent();
storyboard = (Storyboard)canvas.Resources["arrowheadAnimation"];
timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.5) };
timer.Tick += OnTimerTick;
Loaded += OnWindowLoaded;
}
private void OnWindowLoaded(object sender, RoutedEventArgs e)
{
storyboard = (Storyboard)Resources["arrowheadAnimation"];
storyboard.Begin();
timer.Start();
}
private void OnTimerTick(object sender, EventArgs e)
{
if (storyboard.GetCurrentState() != ClockState.Active)
{
timer.Stop();
return;
}
var transform = (MatrixTransform)arrowhead.RenderTransform;
var arrowheadCopy = new Path
{
Data = arrowhead.Data,
Fill = arrowhead.Fill,
RenderTransform = new MatrixTransform(transform.Matrix)
};
canvas.Children.Add(arrowheadCopy);
}

Stop and start animation in WPF

I can't get my animation to start and stop, with code behind (c #)
I have tried MyStoryboard.stop() and change duration for the animation and it stops, but only when I change content and go back.
When I start it again my animations run at strange speeds and again only if I change content
when I change content there is a new speed and if I keep doing it, it bugs
Xaml:
<Image Grid.Row="0" MaxHeight="50" Source="..\Images\Propeller.png"
RenderTransformOrigin=".5,.5">
<Image.RenderTransform>
<RotateTransform x:Name="MyAnimation" Angle="0" />
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard x:Name="MyStoryboard">
<DoubleAnimation x:Name="Prope11"
Storyboard.TargetName="MyAnimation"
To="360"
Duration="0:0:0.6"
RepeatBehavior="Forever"
FillBehavior="Stop" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>
Code behind:
TimeSpan ts = TimeSpan.FromMilliseconds(600);
MyStoryboard.Stop();
Prope11.Duration = ts;
MyStoryboard.Bigin();
You had not assigned the TargetName Property of the Storyboard to start the animation.
Well, there are two problems in your xaml to make the animation start.
1) Storyboard.TargetName="MyAnimation", Target name must be controls name. In your case, you have provided but you have given or assigned it to RotateTransform, which comes under the Image control, but not the image.
<Image x:Name="ImageControl" Grid.Row="0" MaxHeight="50" Source="C:\Users\Public\Pictures\Sample Pictures\Chrysanthemum.jpg"
RenderTransformOrigin=".5,.5" >
and in DoubleAnimation provide TargetName as the Image control's name
Storyboard.TargetName="ImageControl"
2) Another problem is you have not provided the Target Property on which your double animation is dependent.
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
Your stop code didn't work because, it was not started. Adding this below xaml will solve your problem.
Change in the speed is because you have given 600, for 6 Seconds it must be 6000 and not 600.
This is the change i have done. On Mouse Down event I have given to Stop StoryBoard.
<Image.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard x:Name="BeginImageRotateAni" >
<Storyboard x:Name="MyStoryboard">
<DoubleAnimation x:Name="Prope11"
Storyboard.TargetName="ImageControl"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
To="360"
Duration="0:0:6"
RepeatBehavior="Forever"
FillBehavior="Stop"
>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseDown">
<EventTrigger.Actions>
<StopStoryboard BeginStoryboardName="BeginImageRotateAni"/>
</EventTrigger.Actions>
</EventTrigger>
</Image.Triggers>
and subscribed for MouseDownEvent in Constructor
ImageControl.MouseDown += ImageControl_MouseDown;
and write the below code inside the event.
bool IsAnimationstarted = true;
private void ImageControl_MouseDown(object sender, MouseButtonEventArgs e)
{
if (IsAnimationstarted)
{
MyStoryboard.Stop();
IsAnimationstarted = false;
}
else
{
TimeSpan ts = TimeSpan.FromMilliseconds(6000);
Prope11.Duration = ts;
MyStoryboard.Begin();
IsAnimationstarted = true;
}
}
}
Alternate solution:- by creating the animation in the resource and then utilizing it in the codebehind.
<Window.Resources>
<Storyboard x:Name="MyStoryboard" x:Key="Animation1" >
<DoubleAnimation x:Name="Prope11"
Storyboard.TargetName="ImageControl"
Storyboard.TargetProperty="(UIElement.RenderTransform).(RotateTransform.Angle)"
To="360"
Duration="0:0:6"
RepeatBehavior="Forever"
FillBehavior="Stop"
>
</DoubleAnimation>
</Storyboard>
</Window.Resources>
In Code Behind:-
bool IsAnimationstarted = true;
private void ImageControl_MouseDown(object sender, MouseButtonEventArgs e)
{
Storyboard board = (Storyboard)this.FindResource("Animation1");
if (IsAnimationstarted)
{
IsAnimationstarted = false;
board.Begin();
}
else
{
IsAnimationstarted = true;
board.Pause();
}
}
I don't know why are changing the speed or not sure about your intention. What I have done here is when the user clicks on the image control, it will start the animation and pause again clicked and this goes on.

WPF - Create a floating animated clickable control (image or...)

I want create a floating animated clickable control like a helium balloon that moves sometimes to right or left too in my WPF application.
The helium balloons likes go up! but also they moves right or left if
we tap on them or by wind.
In advance cases, sometimes they turn to right or left
....................................................................
So i searched the web but i didn't find any usefull sample project or library or styles.
How i can create style and animation in WPF to show an image or
control buoyant or suspended in air.?
Have you any suggestions to implement this idea simply...?
Edit:
What is your suggestion for a random and infinite smooth turns to right and left. for example 51degrees to left then 163degree to right and.... i want keep my balloon in my window and often top of the window.
Edit:
I created an animation base on these answers but more complex by manipulating them and adding multiple parallel animation on balloon image and its container. ;)
Thanks all...
Now my primary result is like this:
You can achieve this with a DoubleAnimation and a RotateTransform like #Ega mentioned. To answer your "random and infinite" turns to right and left, here's how you could do it (it's very basic but does the job).
private async void Button_Click(object sender, RoutedEventArgs e)
{
var rnd = new Random();
var direction = -1;
while (true)
{
var percent = rnd.Next(0, 100);
direction *= -1; // Direction changes every iteration
var rotation = (int)((percent / 100d) * 45 * direction); // Max 45 degree rotation
var duration = (int)(750 * (percent / 100d)); // Max 750ms rotation
var da = new DoubleAnimation
{
To = rotation,
Duration = new Duration(TimeSpan.FromMilliseconds(duration)),
AutoReverse = true // makes the balloon come back to its original position
};
var rt = new RotateTransform();
Balloon.RenderTransform = rt; // Your balloon object
rt.BeginAnimation(RotateTransform.AngleProperty, da);
await Task.Delay(duration * 2); // Waiting for animation to finish, not blocking the UI thread
}
}
edit for .NET 3.5
private void Button_Click(object sender, RoutedEventArgs e)
{
var thread = new Thread(this.AnimateBalloon);
thread.Start();
}
public void AnimateBalloon()
{
var rnd = new Random();
var direction = -1;
while (true)
{
var percent = rnd.Next(0, 100);
direction *= -1; // Direction changes every iteration
var rotation = (int)((percent / 100d) * 45 * direction); // Max 45 degree rotation
var duration = (int)(750 * (percent / 100d)); // Max 750ms rotation
Balloon.Dispatcher.BeginInvoke(
(Action)(() =>
{
var da = new DoubleAnimation
{
To = rotation,
Duration = new Duration(TimeSpan.FromMilliseconds(duration)),
AutoReverse = true // makes the balloon come back to its original position
};
var rt = new RotateTransform();
Balloon.RenderTransform = rt; // Your balloon object
rt.BeginAnimation(RotateTransform.AngleProperty, da);
}));
Thread.Sleep(duration * 2);
}
}
Farseer Physics Engine for C# will allow you to create a real world simulation. You can control gravity, inertia, force and even other physical stuff.
World world = new World(new Vector2(0f, 9.82f));
//We create a body object and make it dynamic (movable)
Body myBody = world.CreateBody();
myBody.BodyType = BodyType.Dynamic;
//We create a circle shape with a radius of 0.5 meters
CircleShape circleShape = new CircleShape(0.5f);
//We fix the body and shape together using a Fixture object
Fixture fixture = myBody.CreateFixture(circleShape);
For this scenario you may need to create a world with less gravity and objects will fly. You can apply force from either side of the object to move it.
in C# DoubleAnimationis a powerful Class Support Animation inside System.Windows.Media.Animation; NameSpace so this class have some Methods and Properties let me to tell you it
DoubleAnimation ANobj = new DoubleAnimation();//make object from DoubleAnimation
ANobj.From=0 //the 0 is point you want to star animation
ANobj.To=270//the end pont of moving
// that values is dependent on your self as you want
ANobj.Duration = new Duration(TimeSpan.FromSeconds(60)); //specify the duration of moving
ANobj.RepeatBehavior = RepeatBehavior.Forever;//RepeatBehavior as you want
also use RotateTransform class to Rotate C# Componets in WPF
RotateTransform RTobj=new RotateTransform();//make object from RotateTransform
RTobj.CenterX = 277;//X point of your Element(Componet)
RTobj.CenterY = 245;//Y point of your Element(Componet)
RTobj.Angle = 360;//angle between
RTobj.BeginAnimation(RotateTransform.AngleProperty,ANobj);
also after doing that configures set this obj to RenderTransform property from your Element like it
yourElementName.RenderTransform=RTobj
if you want read more at MSDN about System.Windows.Media.Animation
May This help You Here,I take polygon and One image to left to right you can set by Your choice :)
<Window x:Class="Animation.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="XAML Animation - Spinning Stars" Height="300" Width="355"
>
<Grid Name="myGrid">
<Canvas Margin="15,18,18,26" MinHeight="50" MinWidth="50" Name="canvas1">
<!-- Invisible element just to host composite transform -->
<Polygon
Name ="mypolygon1"
Stroke="Blue"
StrokeThickness="1.0"
Points="176.5,50 189.2,155.003 286.485,113.5 201.9,177 286.485,240.5
189.2,198.997 176.5,304 163.8,198.997 66.5148,240.5 151.1,177
66.5148,113.5 163.8,155.003">
<Polygon.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="xformRotate" CenterX="176" CenterY="145" />
<TranslateTransform x:Name="xformTranslate" X ="-50" Y="-50" />
<ScaleTransform x:Name ="xformScale" ScaleX=".25" ScaleY=".25" />
</TransformGroup>
</Polygon.RenderTransform>
<Polygon.Fill>
<SolidColorBrush Color="Blue">
<!--<ColorAnimation From="Yellow" To="Blue" Duration="7"
RepeatCount="500" AutoReverse="True"/>-->
</SolidColorBrush>
</Polygon.Fill>
<Polygon.Triggers>
<EventTrigger RoutedEvent="Polygon.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<!-- RotateTransform angle from 0 to 360, repeated -->
<DoubleAnimation Storyboard.TargetName="xformRotate"
Storyboard.TargetProperty="Angle"
From="0" To="360" Duration="0:0:01"
RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetName="xformTranslate"
Storyboard.TargetProperty="X"
From="1" To="750" Duration="0:0:14"
AutoReverse ="True" RepeatBehavior="Forever" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Polygon.Triggers>
</Polygon>
<Polygon
Name ="mypolygon2"
Stroke="Red"
StrokeThickness="1.0"
Points="176.5,50 189.2,155.003 286.485,113.5 201.9,177 286.485,240.5
189.2,198.997 176.5,304 163.8,198.997 66.5148,240.5 151.1,177
66.5148,113.5 163.8,155.003">
<Polygon.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="xformRotateIt" CenterX="176" CenterY="145" />
<ScaleTransform ScaleX=".25" ScaleY=".25" />
<TranslateTransform x:Name="xformTranslateIt" X="0" Y="100" />
</TransformGroup>
</Polygon.RenderTransform>
<Polygon.Fill>
<SolidColorBrush x:Name ="mybrush" Color="Red" />
</Polygon.Fill>
<Polygon.Triggers>
<EventTrigger RoutedEvent="Polygon.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard x:Name="myStoryBoard" Completed="OnCompletedAnimation">
<!-- RotateTransform angle from 0 to 360, repeated -->
<DoubleAnimation Storyboard.TargetName="xformRotateIt"
Storyboard.TargetProperty="Angle"
From="0" To="360" Duration="0:0:01"
RepeatBehavior="Forever" />
<DoubleAnimation Storyboard.TargetName="xformTranslateIt"
Storyboard.TargetProperty="X"
From="1" To="100" Duration="0:0:14"
AutoReverse ="True" RepeatBehavior="Forever" />
<ColorAnimation Storyboard.TargetName="mybrush" Storyboard.TargetProperty="Color" From="Red" To="Blue" Duration="0:0:7"
RepeatBehavior="Forever" AutoReverse="True"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Polygon.Triggers>
</Polygon>
<Image Margin="75,61,0,119" Name="image1" Source="Images\KENNY.bmp" HorizontalAlignment="Left" Width="72">
<Image.RenderTransform>
<TransformGroup>
<RotateTransform x:Name="KennyRotateIt" CenterX="50" CenterY="50" Angle="45" />
<ScaleTransform x:Name="KennyScaleIt" ScaleX=".75" ScaleY=".75" />
<TranslateTransform x:Name="KennyTranslateIt" X="0" Y="100" />
</TransformGroup>
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="Image.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard x:Name="myStoryBoard1" Completed="OnCompletedAnimation">
<!-- RotateTransform angle from 0 to 360, repeated -->
<DoubleAnimation Storyboard.TargetName="KennyRotateIt"
Storyboard.TargetProperty="Angle"
From="0" To="360" Duration="0:0:01"
RepeatBehavior="Forever" />
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="KennyTranslateIt"
Storyboard.TargetProperty="X"
Duration="0:0:10" AutoReverse="True" RepeatBehavior="Forever">
<!-- These KeyTime properties are specified as TimeSpan values
which are in the form of "hours:minutes:seconds". -->
<LinearDoubleKeyFrame Value="10" KeyTime="0:0:3" />
<LinearDoubleKeyFrame Value="100" KeyTime="0:0:5" />
<LinearDoubleKeyFrame Value="200" KeyTime="0:0:10" />
</DoubleAnimationUsingKeyFrames>
<!-- DoubleAnimation Storyboard.TargetName="KennyTranslateIt"
Storyboard.TargetProperty="X"
From="-50" To="100" Duration="0:0:14"
AutoReverse ="True" RepeatBehavior="Forever" / -->
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Image.Triggers>
</Image>
</Canvas>
</Grid>
</Window>
Here is one I did in high school. Probably very outdated now but just for interest sake.
//the animation thread
System.Threading.Thread thr;
thr = new System.Threading.Thread(annimate);
thr.Start();
the animation method
void annimate()
{
try
{
double angleToAnimateTo = 20;
double CurrentAngle = 0;
bool increment = false;
while (IsAnimating)
{
if (increment)
CurrentAngle++;
else
CurrentAngle--;
if (CurrentAngle == angleToAnimateTo )
increment = false;
if (CurrentAngle == (angleToAnimateTo * -1))
increment = true;
this.Dispatcher.Invoke((Action)(() =>
{
this.imgBallon.RenderTransform = new RotateTransform(CurrentAngle);
}));
System.Threading.Thread.Sleep(100);
}
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
imgBalloon is a simple image in wpf. Here is the xaml..
<Image x:Name="imgBallon"
Source="/img/balloon_blue.png" Width="50"> </Image>

How to restrict storyboard to begin automatically in Windows 8 store app?

I am using two storyboards to move balls(image) left and right directions, on tap event of left button I want to move balls in left direction and on tap event of right button , balls should move in right direction. It's working correctly on taping left and right button, but on loading application storyboards begins automatically and balls move one step without tapping buttons. How do I restrict storyboard to begin automatically?
This is my first storyboard to move balls 40 pixels in left direction:
<EventTrigger>
<BeginStoryboard>
<Storyboard x:Name="ballstoryleft">
<DoubleAnimation Storyboard.TargetName="balltrans" Storyboard.TargetProperty="TranslateX"
Duration="0:0:0.5" By="-40" FillBehavior="HoldEnd">
<DoubleAnimation.EasingFunction>
<ElasticEase Oscillations="0" Springiness="1" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
This is my second storyboard to move balls 40 pixels in right direction:
<EventTrigger>
<BeginStoryboard>
<Storyboard x:Name="ballstoryright">
<DoubleAnimation Storyboard.TargetName="balltrans" Storyboard.TargetProperty="TranslateX"
Duration="0:0:0.5" By="40" FillBehavior="HoldEnd">
<DoubleAnimation.EasingFunction>
<ElasticEase Oscillations="0" Springiness="1" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
I have written this code in code behind:
private void imgleft_Tapped(object sender, TappedRoutedEventArgs e)
{
ballstoryleft.Begin();
}
private void imgright_Tapped(object sender, TappedRoutedEventArgs e)
{
ballstoryright.Begin();
}
Where did you put your Storyboards? I see they are inside EventTriggers. They might be the ones triggering the storyboards when the application loads.
You should just put both Storyboards in a Resources collection:
<Page.Resources>
<Storyboard x:Name="ballstoryleft">
<DoubleAnimation Storyboard.TargetName="balltrans" Storyboard.TargetProperty="TranslateX"
Duration="0:0:0.5" By="-40" FillBehavior="HoldEnd">
<DoubleAnimation.EasingFunction>
<ElasticEase Oscillations="0" Springiness="1" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
<Storyboard x:Name="ballstoryright">
<DoubleAnimation Storyboard.TargetName="balltrans" Storyboard.TargetProperty="TranslateX"
Duration="0:0:0.5" By="40" FillBehavior="HoldEnd">
<DoubleAnimation.EasingFunction>
<ElasticEase Oscillations="0" Springiness="1" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</Page.Resources>
Now there should be no reason for them to trigger automatically while your code which triggers them on tap should still work just like it does now.
You can define whole story board from code behind also
Try this example:
void OnButtonClick(object sender, RoutedEventArgs args)
{
DoubleAnimation anima = new DoubleAnimation
{
EnableDependentAnimation = true,
To = 96,
Duration = new Duration(new TimeSpan(0, 0, 1)),
AutoReverse = true,
RepeatBehavior = new RepeatBehavior(3) };
Storyboard.SetTarget(anima, sender as Button);
Storyboard.SetTargetProperty(anima, "FontSize");
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(anima);
storyboard.Begin();
}

Is there a way to increase width of a control in a animated way in silverlight

I am a beginner in Silverlight. I took a border control, on mouse over of which I want to increase its width, but slowly in an animated way, and on mouse out back to normal
<Border BorderBrush="#528CC1" Background="#164A7A" MouseEnter="bHome_MouseEnter"
MouseLeave="bHome_MouseLeave" Opacity="0.75" BorderThickness="1" Height="75" Width="110"
Grid.Column="1" x:Name="bProduct" Margin="0,0,0,0" Cursor="Hand" VerticalAlignment="Top">
private void bHome_MouseEnter(object sender, MouseEventArgs e)
{
Border border = (Border)sender;
border.Width = 160;
border.Opacity = 100;
}
private void bHome_MouseLeave(object sender, MouseEventArgs e)
{
Border border = (Border)sender;
border.Width = 110;
border.Opacity = 0.75;
}
If you really want to do it with code (it's way way easier to do with visual states, even the mouse over / out is handled for you out of the box, just have to set starting and ending parameters in XAML, however if the values are dynamic, it's not possible, you can't do binding in the VisualStateManager markup as it's not part of the visual tree), here's an example (from http://msdn.microsoft.com/en-us/library/cc189069(VS.95).aspx#procedural_code ):
The following example shows how to create an animation that animates Canvas.Top and Canvas.Left attached properties of a rectangle.
private void Create_And_Run_Animation(object sender, EventArgs e)
{
// Create a red rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 200;
myRectangle.Height = 200;
Color myColor = Color.FromArgb(255, 255, 0, 0);
SolidColorBrush myBrush = new SolidColorBrush();
myBrush.Color = myColor;
myRectangle.Fill = myBrush;
// Add the rectangle to the tree.
LayoutRoot.Children.Add(myRectangle);
// Create a duration of 2 seconds.
Duration duration = new Duration(TimeSpan.FromSeconds(2));
// Create two DoubleAnimations and set their properties.
DoubleAnimation myDoubleAnimation1 = new DoubleAnimation();
DoubleAnimation myDoubleAnimation2 = new DoubleAnimation();
myDoubleAnimation1.Duration = duration;
myDoubleAnimation2.Duration = duration;
Storyboard sb = new Storyboard();
sb.Duration = duration;
sb.Children.Add(myDoubleAnimation1);
sb.Children.Add(myDoubleAnimation2);
Storyboard.SetTarget(myDoubleAnimation1, myRectangle);
Storyboard.SetTarget(myDoubleAnimation2, myRectangle);
// Set the attached properties of Canvas.Left and Canvas.Top
// to be the target properties of the two respective DoubleAnimations.
Storyboard.SetTargetProperty(myDoubleAnimation1, new PropertyPath("(Canvas.Left)"));
Storyboard.SetTargetProperty(myDoubleAnimation2, new PropertyPath("(Canvas.Top)"));
myDoubleAnimation1.To = 200;
myDoubleAnimation2.To = 200;
// Make the Storyboard a resource.
LayoutRoot.Resources.Add("unique_id", sb);
// Begin the animation.
sb.Begin();
}
EDIT See comment below - this is the WPF way not the Silverlight way, so you might want to disregard this answer!!
Don't do it through code; that's not the Silverlight / WPF way. Instead use the XAML eg:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<!-- Defines a Button style. -->
<Style TargetType="{x:Type Button}" x:Key="MyButtonStyle">
<Style.Triggers>
<!-- Animate the button width on mouse over. -->
<EventTrigger RoutedEvent="Button.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Button.Width)"
To="200" Duration="0:0:0.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<!-- Returns the button's width to 50 when the mouse leaves. -->
<EventTrigger RoutedEvent="Button.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="(Button.Width)"
To="50" Duration="0:0:0.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Page.Resources>
<StackPanel Margin="20">
<Button Style="{StaticResource MyButtonStyle}" Width="50" >Click Me</Button>
</StackPanel>
</Page>
For more info see here: Animation and Timing How-to Topics

Categories