I have created a TransformGroup with multiple Transforms and assigned this to an Image's RenderTransform property:
TransformGroup group = new TransformGroup();
ScaleTransform st = new ScaleTransform();
group.Children.Add(st);
TranslateTransform tt = new TranslateTransform();
group.Children.Add(tt);
image.RenderTransform = group;
If I want to get an individual transform from this group in WPF, I can do this:
TranslateTransform tt = (TranslateTransform)((TransformGroup)image.RenderTransform).Children.First(tr => tr is TranslateTransform);
However, in Silverlight, this TransformGroup is apparently implicitly converted to a MatrixTransform, because running the above code gives the error:
Unable to cast object of type 'System.Windows.Media.MatrixTransform' to type 'System.Windows.Media.TransformGroup'.
Is there any way to avoid the conversion from TransformGroup to MatrixTransform? If not, how can I recover the individual Transforms from the MatrixTransform?
D'oh! I had accidentally tried to use the TransformGroup before assigning it, so image.RenderTransform was still set to the default of MatrixTransform.
In case anyone needed to use a MatrixTransform to perform a ScaleTransform followed by a TranslateTransform, given these transforms:
ScaleTransform st = new ScaleTransform();
TranslateTransform tt = new TranslateTransform();
The following two options should provide equivalent results:
Using TransformGroup:
TransformGroup group = new TransformGroup();
group.Children.Add(st);
group.Children.Add(tt);
image.RenderTransform = group;
Using MatrixTransform:
MatrixTransform mt = new MatrixTransform
{
Matrix = new Matrix
{
M11 = st.ScaleX,
M22 = st.ScaleY,
OffsetX = tt.X,
OffsetY = tt.Y
}
};
image.RenderTransform = mt;
Related
I have rotated a line based using Transform Group in UWP. Once after rotation I need to get the new bounds of line using the transform matrix value .Whether it is possible to get the current points of line using the matrix value? Can anyone help me out on this ?
RotateTransform rotate = new RotateTransform();
rotate.Angle = -angle;
var translate = new TranslateTransform
{
X = offset,
Y = offset
};
var group = new TransformGroup
{
Children = { (Transform)translate.Inverse, rotate,translate }
};
line.RenderTransform = group;
var matrix = ((line.RenderTransform as TransformGroup).Value);
if you know and access the Parent of the Line, then I think you can do this:
var line_bound = line.TransformToVisual(parent).TransformBounds(new Rect(0, 0, Math.Abs(line.X2 - line.X1), Math.Abs(line.Y2 - line.Y1)));
Here the parent may be a Grid or a Canvas that you attach the line to.
Read more about TransformBounds(Rect) Method here.
I am using MSDN example to setup the animation of Width of a Rectangle in C3 UWP.
Here is the code of the sample:
private void Create_And_Run_Animation()
{
// Create a red rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 0;
myRectangle.Height = 20;
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myRectangle.Fill = myBrush;
// Create the transform
TranslateTransform stretchTransform = new TranslateTransform();
stretchTransform.X = 0;
stretchTransform.Y = 0;
myRectangle.RenderTransform = stretchTransform;
// Add the rectangle to the tree.
DefaultLayout.Children.Add(myRectangle);
myRectangle.Name = "myWidthAnimatedRectangle";
// Create a duration of 2 seconds.
Duration duration = new Duration(TimeSpan.FromSeconds(2));
// Create two DoubleAnimations and set their properties.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 0.0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(3000));
Storyboard justintimeStoryboard = new Storyboard();
justintimeStoryboard.Duration = duration;
justintimeStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTarget(myDoubleAnimation, stretchTransform);
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
// Set the X property of the Transform to be the target property
Storyboard.SetTargetProperty(myDoubleAnimation, "X");
myDoubleAnimation.To = 300.0;
// Make the Storyboard a resource.
DefaultLayout.Resources.Add("justintimeStoryboard", justintimeStoryboard);
// Begin the animation.
justintimeStoryboard.Begin();
}
However, on Build, what it does is move the object and not change its width.
I need to animate width change.
However, on Build, what it does is move the object and not change its width. I need to animate width change.
Your code was used to animate the Rectangle's position, not its width. You could specify a default value for its width and animate its ScaleTransform.
If you have to use DoubleAnimation to animate its width, you need to set EnableDependentAnimation to true. Please check the following code sample:
private void Create_And_Run_Animation()
{
// Create a red rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 10;
myRectangle.Height = 20;
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myRectangle.Fill = myBrush;
// Add the rectangle to the tree.
DefaultLayout.Children.Add(myRectangle);
myRectangle.Name = "myWidthAnimatedRectangle";
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 0.0;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(3000));
Storyboard justintimeStoryboard = new Storyboard();
Storyboard.SetTargetProperty(myDoubleAnimation, "(Rectangle.Width)");
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
myDoubleAnimation.To = 300.0;
myDoubleAnimation.EnableDependentAnimation = true;
justintimeStoryboard.Children.Add(myDoubleAnimation);
// Make the Storyboard a resource.
DefaultLayout.Resources.Add("justintimeStoryboard", justintimeStoryboard);
// Begin the animation.
justintimeStoryboard.Begin();
}
I am testing the Storyboard.SetTarget Method. I need to animate rectangle's width and height change.
I found Microsoft example, but when I include the code in my program, the Solution does not build and deploy.
I get error like this:
IDE0006 Error encountered while loading the project. Some project
features, such as full solution analysis for the failed project and
projects that depend on it, have been disabled.
error CS0246: The type or namespace name 'Color' could not be found (are you missing a using directive or an assembly reference?)
When I add namespace like:
System.Windows.Media.Animation
I get error:
error CS0234: The type or namespace name 'Media' does not exist in the
namespace 'System.Windows' (are you missing an assembly reference?)
Am I using example not for UWP??
Here is the code from example that I used:
private void Create_And_Run_Animation(object sender, EventArgs e)
{
// Create a yellow rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 200;
myRectangle.Height = 20;
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 = 40;
// Make the Storyboard a resource.
LayoutRoot.Resources.Add("unique_id", sb);
// Begin the animation.
sb.Begin();
Ok, I was using the example for Silverlight.
I found C# UWP sample here:
Storyboard Class
and it works now, but it changes the position of rectangle and not the Width.
How can I change the transition to be applied to the Width property of Rectangle?
New code is like this:
private void Create_And_Run_Animation()
{
// Create a red rectangle that will be the target
// of the animation.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 20;
myRectangle.Height = 20;
SolidColorBrush myBrush = new SolidColorBrush(Colors.Yellow);
myRectangle.Fill = myBrush;
// Create the transform
TranslateTransform stretchTransform = new TranslateTransform();
stretchTransform.X = 0;
stretchTransform.Y = 0;
myRectangle.RenderTransform = stretchTransform;
// Add the rectangle to the tree.
InfoGrid.Children.Add(myRectangle);
myRectangle.Name = "myWidthAnimatedRectangle";
// Create a duration of 2 seconds.
Duration duration = new Duration(TimeSpan.FromSeconds(2));
// Create two DoubleAnimations and set their properties.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 200;
myDoubleAnimation.To = 300;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(3000));
Storyboard justintimeStoryboard = new Storyboard();
justintimeStoryboard.Duration = duration;
justintimeStoryboard.Children.Add(myDoubleAnimation);
Storyboard.SetTarget(myDoubleAnimation, stretchTransform);
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
Storyboard.SetTargetProperty(myDoubleAnimation, new PropertyPath(Rectangle.WidthProperty));
// Set the X and Y properties of the Transform to be the target properties
// of the two respective DoubleAnimations.
Storyboard.SetTargetProperty(myDoubleAnimation, "X");
myDoubleAnimation.To = 200;
// Make the Storyboard a resource.
InfoGrid.Resources.Add("justintimeStoryboard", justintimeStoryboard);
// Begin the animation.
justintimeStoryboard.Begin();
}
But I cannot get the Rectangle.WidthProperty right in UWP.
Intelli says:
cannot convert from 'Windows.UI.Xaml.DependencyProperty' to 'string'
I can't find the resources on MSDN.
cannot convert from 'Windows.UI.Xaml.DependencyProperty' to 'string'
The problem is the Path parameter of SetTargetProperty method is string value. You could not pass PropertyPath to it. You just need to pass the Width string value.
DoubleAnimation myDoubleAnimation = new DoubleAnimation();
myDoubleAnimation.From = 20;
myDoubleAnimation.To = 300;
myDoubleAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(3000));
Storyboard.SetTarget(myDoubleAnimation, myRectangle);
Storyboard.SetTargetProperty(myDoubleAnimation, "Width");
Storyboard.SetTargetName(myDoubleAnimation, myRectangle.Name);
If you use the below code to animate with property, you will not see any effects. Because you have made a dependent animation. By default, the animation system won't run a dependent animation. You can still use this animation, but you must specifically enable each such dependent animation. To enable your animation, set the EnableDependentAnimation property of the animation object to true.
myDoubleAnimation.EnableDependentAnimation = true;
For more please refer Storyboarded animations official document.
I'm trying to animate an image to move to a certain point then turn and come back to the startign point,I searched this site for answers but i still can't seem to understand how the RenderTransform works.
This is my current code for anyone interested in helping me:
public static void MoveTo(this Image target, double newX, double newY,int s)
{
Vector offset = VisualTreeHelper.GetOffset(target);
DoubleAnimation animay = new DoubleAnimation(0, newY - offset.Y, TimeSpan.FromSeconds(s));
DoubleAnimation animax = new DoubleAnimation(0, newX - offset.X, TimeSpan.FromSeconds(s));
TransformGroup transformGroup = new TransformGroup();
TranslateTransform translatetransform = new TranslateTransform();
ScaleTransform scaletransform = new ScaleTransform();
transformGroup.Children.Add(translatetransform);
transformGroup.Children.Add(scaletransform);
target.RenderTransform = transformGroup;
target.RenderTransform.BeginAnimation(TranslateTransform.YProperty, animay);
target.RenderTransform.BeginAnimation(TranslateTransform.XProperty, animax);
}
Edit:
Just to be clear I should add that I know how to animate the object to move and flip separately,but can't make them work in succession with a Transform Group.
UPDATE
I want to add an image to my canvas programmatically. I want to bind X, Y coords and Angle of the Image. X and Y binding works fine, but the Angle doesn't. Here is the code:
public void AddNewImage()
{
Image newImage = new Image
{
Source = new BitmapImage(new Uri(imagePath))
};
These two work fine
Binding binding1 = new Binding("X");
binding1.Mode = BindingMode.TwoWay;
binding1.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(newImage, Canvas.LeftProperty, binding1);
Binding binding2 = new Binding("Y");
binding2.Mode = BindingMode.TwoWay;
binding2.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(newImage, Canvas.TopProperty, binding2);
That's why I use a group
TransformGroup tg = new TransformGroup();
tg.Children.Add(new TranslateTransform(xTranslate,yTranslate));
tg.Children.Add(new RotateTransform());
newImage.RenderTransform = tg;
This one doesn't work
Binding binding3 = new Binding("Angle");
binding3.Mode = BindingMode.TwoWay;
binding3.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(tg, RotateTransform.AngleProperty, binding3);
MainCanvas.Children.Add(newImage);
}
When I change X and Y - image moves, but when I change angle - nothing happens.
What do I do wrong?
You're setting the binding on the TransformGroup, which has no Angle property. Instead of that you should set the binding directly on the RotateTransform.
var rotateTransform = new RotateTransform();
var tg = new TransformGroup();
tg.Children.Add(rotateTransform);
newImage.RenderTransform = tg;
var binding3 = new Binding("Angle");
...
BindingOperations.SetBinding(rotateTransform, RotateTransform.AngleProperty, binding3);