WPF Rotate object before main animation loop - c#

I'm trying to understand rules of WPF animation usying code from this site:
https://www.codeproject.com/Articles/23257/Beginner-s-WPF-Animation-Tutorial
Now I have a code to rotate element around x, y point:
RotateTransform rt = new RotateTransform();
DoubleAnimation da = new DoubleAnimation();
da.From = 0;
da.To = 360;
da.Duration = new Duration(TimeSpan.FromSeconds(10));
da.RepeatBehavior = RepeatBehavior.Forever;
image.RenderTransformOrigin = new Point(x, y);
image.RenderTransform = rt;
rt.BeginAnimation(RotateTransform.AngleProperty, da);
This is GIF image like "^", so I want to rotate it 90 deg BEFORE animation to rotate image like ">".
Tried RotateTransform rt = new RotateTransform(90); but no success.
Any suggestions?

Besides setting the Angle property of rt to 90, you should also change the From property of da to 90 to start animating from this value:
RotateTransform rt = new RotateTransform(90);
...
da.From = 90;

Related

WPF. Animation of window transparency

I need a smooth animation of window transparency. I added this code to the "LOADED" event of the window.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 100.0;
myDoubleAnimation.To = 0.1;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(1));
Storyboard.SetTargetName(myDoubleAnimation, Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(UIElement.OpacityProperty));
Storyboard myStoryboard = new Storyboard();
myStoryboard.Children.Add(myDoubleAnimation);
myStoryboard.Begin(this);
There is a sharp jump of transparency. Animation is missing. Where there has been a mistake?
Opacity is a relative value in the range 0 .. 1. Use
myDoubleAnimation.From = 1.0;
or don't set it at all.
Instead of using a Storyboard, you may also just write
BeginAnimation(OpacityProperty, new DoubleAnimation
{
To = 0.1,
Duration = TimeSpan.FromSeconds(1)
});

WPF Maintain LinearGradientBrush Rotation As Shape Rotates

I'm trying to create a line with a 'barber shop pole' gradient effect in C# (WPF). The code below works, but when I move the line the gradient becomes distorted. Is there a way to move/rotate the line object and have the gradient's angle remain stationary relative to the line itself.
// Create a linear gradient brush
LinearGradientBrush redWhiteStripes = new LinearGradientBrush();
redWhiteStripes.StartPoint = new Point(0, 0);
redWhiteStripes.EndPoint = new Point(1, 1);
redWhiteStripes.SpreadMethod = GradientSpreadMethod.Reflect;
ScaleTransform s = new ScaleTransform();
s.ScaleX = 0.125;
s.ScaleY = 0.125;
RotateTransform rot = new RotateTransform();
rot.Angle = 20;
rot.CenterX = 0.0625;
rot.CenterY = 0.0625;
TransformGroup tgroup = new TransformGroup();
tgroup.Children.Add(s);
tgroup.Children.Add(rot);
redWhiteStripes.RelativeTransform = tgroup;
// Create and add Gradient stops
GradientStop point1 = new GradientStop();
point1.Color = Colors.DarkRed;
point1.Offset = 0.0;
redWhiteStripes.GradientStops.Add(point1);
// Create and add Gradient stops
GradientStop point2 = new GradientStop();
point2.Color = Colors.DarkRed;
point2.Offset = 0.5;
redWhiteStripes.GradientStops.Add(point2);
// Create and add Gradient stops
GradientStop point3 = new GradientStop();
point3.Color = Colors.White;
point3.Offset = 0.5;
redWhiteStripes.GradientStops.Add(point3);
// Create and add Gradient stops
GradientStop point4 = new GradientStop();
point4.Color = Colors.White;
point4.Offset = 1.0;
redWhiteStripes.GradientStops.Add(point4);
Line l = new Line();
l.Stroke = redWhiteStripes;
l.StrokeThickness = 8;

Simultaneous Animation For Same Element in WPF

I have an image in a canvas. What I want to do is code an animation which both rotates the image 90 degrees and move the image from the top left corner of canvas to the bottom right corner at the same time to create an action looks like projectile motion. However, I could only manage to do one part of the animation so far.
DoubleAnimation rotateAnimation = new DoubleAnimation(0, 90, new Duration(TimeSpan.FromSeconds(1)));
RotateTransform rt = new RotateTransform();
image.RenderTransform = rt;
rt.BeginAnimation(RotateTransform.AngleProperty, rotateAnimation);
TranslateTransform tt = new TranslateTransform();
image.RenderTransform = tt;
DoubleAnimation moveXAnimation = new DoubleAnimation(0, 300, TimeSpan.FromSeconds(1));
DoubleAnimation moveYAnimation = new DoubleAnimation(0, 300, TimeSpan.FromSeconds(1));
tt.BeginAnimation(TranslateTransform.XProperty, moveXAnimation);
tt.BeginAnimation(TranslateTransform.YProperty, moveYAnimation);
These two blocks works very well separately, but do not work together(consequently). The latter one works only. Anyone can tell me why?
UPDATE (Complete answer of Clemens):
RotateTransform rt = new RotateTransform();
DoubleAnimation rotateAnimation = new DoubleAnimation(0, 90, new Duration(TimeSpan.FromSeconds(5)));
TranslateTransform tt = new TranslateTransform();
DoubleAnimation moveXAnimation = new DoubleAnimation(0, 300, TimeSpan.FromSeconds(5));
DoubleAnimation moveYAnimation = new DoubleAnimation(0, 300, TimeSpan.FromSeconds(5));
TransformGroup transform = new TransformGroup();
transform.Children.Add(rt);
transform.Children.Add(tt);
image.RenderTransformOrigin = new Point(0.5, 0.5);
image.RenderTransform = transform;
rt.BeginAnimation(RotateTransform.AngleProperty, rotateAnimation);
tt.BeginAnimation(TranslateTransform.XProperty, moveXAnimation);
tt.BeginAnimation(TranslateTransform.YProperty, moveYAnimation);
Put both transforms in a TransformGroup, and assign that to the image's RenderTransform:
var rt = new RotateTransform();
var tt = new TranslateTransform();
var transform = new TransformGroup();
transform.Children.Add(rt);
transform.Children.Add(tt);
image.RenderTransform = transform;
// run animations
You may also want to take a look at how to use a Path Animation for a more realistic look. The projectile might follow a parabolic curve.

How to scale image from center? Windows 8.1 C#

How to scale dynamic image control from the center programmatically in c# for Windows 8.1. This code scales image from left upper corner:
Image img=new Image(){Width=150,Height=150};
img.RenderTransform = new CompositeTransform();
Storyboard story = new Storyboard();
DoubleAnimation xAnim = new DoubleAnimation();
DoubleAnimation yAnim = new DoubleAnimation();
xAnim.From = 0;
yAnim.From = 0;
xAnim.To = 1;
yAnim.To = 0.5;
xAnim.Duration = TimeSpan.FromMilliseconds(1000);
yAnim.Duration = TimeSpan.FromMilliseconds(1500);
story.Children.Add(xAnim);
story.Children.Add(yAnim);
Storyboard.SetTarget(xAnim, img);
Storyboard.SetTarget(yAnim, img);
Storyboard.SetTargetProperty(xAnim, "(UIElement.RenderTransform).(CompositeTransform.ScaleX)");
Storyboard.SetTargetProperty(yAnim, "(UIElement.RenderTransform).(CompositeTransform.ScaleY)");
story.Begin();
You want
img.RenderTransformOrigin = new Point(0.5, 0.5);
That will mean that all of your transforms will be relative to the center of your image. See the RenderTransformOrigin documentation for more details.

Rotate and scale ImageBrush

I can rotate an image by:
RotateTransform aRotateTransform = new RotateTransform();
aRotateTransform.CenterX = 0.5;
aRotateTransform.CenterY = 0.5;
tateTransform.Angle = rotationAngle;
ImageBrush bgbrush = new ImageBrush();
bgbrush.RelativeTransform = aRotateTransform;
ScaleTransform s = new ScaleTransform();
s.ScaleX = -1; // how to set without overriding the rotation?
...
How can I scale it in addition? I tried using matrices without success.
You could use a TransformGroup like so:
TransformGroup tg = new Transformgroup();
tg.Children.Add(rotateTransform);
tg.Children.Add(scaleTransform);
bgbrush.RelativeTransform = tg;
You could use a CompositeTransform, it combines translation, rotation and scaling in a single matrix.
Just for completeness. Using Matrix transformations, you would get the expected result by this:
var transform = Matrix.Identity;
transform.RotateAt(rotationAngle, 0.5, 0.5);
transform.Scale(-1, 1);
bgbrush.RelativeTransform = new MatrixTransform(transform);
However, I guess that actually you want to keep the image centered, so you might use ScaleAt instead of Scale:
var transform = Matrix.Identity;
transform.RotateAt(rotationAngle, 0.5, 0.5);
transform.ScaleAt(-1, 1, 0.5, 0.5);
bgBrush.RelativeTransform = new MatrixTransform(transform);
If you just need to rotate the Brush it self and put it into a rectangle later without having to adjust anything else, this worked for me:
// Get the image from somewhere...
ib = new ImageBrush(bmp);
// Here I get it from a larger texture picture.
ib.Viewbox = this.GetVBRect(1728, 634);
ib.Transform = new RotateTransform()
{
CenterX = 0.5,
CenterY = 0.5,
Angle = 180,
};
ib.TileMode = TileMode.Tile;

Categories