I have a rectangle where i am using a story board to rotate it up like a needle in a car gauge( mph). What i want to do is be able to pause it. In addition i would also like to get its location when i want to. Like get its current value as its rotating up to the end position that i specified. Can this be done?
What i want to do is use that to calculate the tachometer and move the tachometer needle according to the mph story board.
DoubleAnimation da = new DoubleAnimation();
da.From = 0 * 6;
da.To = 60;
da.Duration = new Duration(TimeSpan.FromSeconds(5));
RotateTransform rt = new RotateTransform();
rt.CenterX = 35;
rt.CenterY = 0;
rec3.RenderTransform = rt;
rt.BeginAnimation(RotateTransform.AngleProperty, da);
DoubleAnimation tack = new DoubleAnimation();
tack.From = 0 * 6;
tack.To = 30;
tack.Duration = new Duration(TimeSpan.FromSeconds(5));
RotateTransform tackneedle = new RotateTransform();
tackneedle.CenterX = 30;
tackneedle.CenterY = 0;
rec4.RenderTransform = tackneedle;
tackneedle.BeginAnimation(RotateTransform.AngleProperty, tack);
You can add your animations to a Storyboard which will allow you to pause and resume the animation. You should also be able to access the rotate transforms and get the value of their centers.
A different way might be more appropriate:
Make a class that calculates/generates the value.
Bind the needle to the value (use a value converter to get from amount to angle if needed)
that way you can control the value more easily and you can always stop the animation by pausing the generation of the value.
You have to think about what you need: do you need to know the value of the animation or should the needle follow/display the value?
Related
hi i want to write a animation where car drivin on a road and waits untill train will pass and then goes again,but i cant find anything on the internet about it , i also want to cars drive in a "row" but now they driving through each other through.
Is it even possible ?
namespace Symulator_ruchu
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Random r = new Random();
IEnumerable<PathFigure> colle;
DispatcherTimer dispatcherTimer = new DispatcherTimer();
DispatcherTimer train = new DispatcherTimer();
public MainWindow()
{
InitializeComponent();
dispatcherTimer.Tick += new EventHandler(dispTimer_tick);
dispatcherTimer.Interval = new TimeSpan(0,0,1);
dispatcherTimer.Start();
train.Tick += new EventHandler(train_tick);
train.Interval = new TimeSpan(0, 0, 10);
train.Start();
}
private void train_tick(object sender, EventArgs e)
{
Path car = new Path
{
Name = "AnimatedMatrixTrain",
Fill = Train.Fill,
Data = new RectangleGeometry
{
Rect = new Rect(0, 0, 55, 270)
},
LayoutTransform = new RotateTransform
{
Angle = 90
},
RenderTransform = new MatrixTransform
{
Matrix = new Matrix
{
OffsetX = 100,
OffsetY = 100
}
}
};
MatrixAnimationUsingPath maup = new MatrixAnimationUsingPath
{
Duration = TimeSpan.FromSeconds(r.Next(5, 10)),
DoesRotateWithTangent = true,
AutoReverse = false,
PathGeometry = new PathGeometry
{
Figures = PathFigureCollection.Parse("M 745,900 L 745,0")
}
};
Storyboard.SetTarget(maup, car);
Storyboard.SetTargetProperty(maup, new PropertyPath("(UIElement.RenderTransform).(MatrixTransform.Matrix)"));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(maup);
//Canvas.SetTop(car, r.Next(1, 500));
//Canvas.SetLeft(car, r.Next(1, 500));
storyboard.Begin(car);
Canv.Children.Add(car);
}
private void dispTimer_tick(object sender, EventArgs e)
{
Path car = new Path
{
Name = "AnimatedMatrixCar",
Fill = Car.Fill,
Data = new RectangleGeometry
{
Rect = new Rect(0,0,60,30)
},
LayoutTransform = new RotateTransform
{
Angle = 180
},
RenderTransform = new MatrixTransform
{
Matrix = new Matrix
{
OffsetX = 100,
OffsetY = 100
}
}
};
MatrixAnimationUsingPath maup = new MatrixAnimationUsingPath
{
Duration = TimeSpan.FromSeconds(r.Next(5,10)),
DoesRotateWithTangent = true,
AutoReverse = false,
PathGeometry = new PathGeometry
{
Figures = PathFigureCollection.Parse("m 10,286 h 800 c 130,10 190, 200 -105, 180 h -450 c -160,10 -200,250 -35,290 H 1200")
}
};
Storyboard.SetTarget(maup, car);
Storyboard.SetTargetProperty(maup, new PropertyPath("(UIElement.RenderTransform).(MatrixTransform.Matrix)"));
Storyboard storyboard = new Storyboard();
storyboard.Children.Add(maup);
//Canvas.SetTop(car, r.Next(1, 500));
//Canvas.SetLeft(car, r.Next(1, 500));
storyboard.Begin(car);
Canv.Children.Add(car);
}
}
Here is how wpf window look like:
enter image description here
I don't think you can use collision detection in an animation. You'd have to write your own code moved the car pixel by pixel. You could then use a distance calculation between some calculated edge point of your rectangle and anything else.
That's all possible but you'd be calculating angle of rotation yourself. Fair bit of fiddly work and it might not even be so smooth once you're finished.
I'd go with storyboard and animations.
Some trial and error will be necessary for this in order for the train to pass just after a car stops.
Use a storyboard and at least two matrix animations within that.
Each animation can have a begin time and duration. The first animation should have no begin time, you want that to start straight away.
You might want one of the easout easing functions so it slows down as it nears the crossing.
The second animation should have a begin time which makes it start up again after the train has passed. This time with an ease in easing function so it accelerates up to speed.
You will need to split your path geometry into two parts. Up to the crossing and then from the crossing to end of road. You could use inkscape or manually find where your crossing is using the points in the geometry.
You will apply this to your first car.
Off it goes.
Use async await to introduce a delay. Then repeat using your storyboard with the second car. It will of course do the same as the first one but start a bit later, giving a gap.
There is a bit of a complication though. Maybe you want your second car to stop behind the first.
That means you need two different geometries with the second ending earlier.
Not sure if you have your geometries.
I would use inkscape to draw the path. It's free. You could import your base picture, add a layer and draw a vectorin the new layer. That has line start and and nodes and curve handle nodes. You can drag the nodes and add more. There's a bit of a learning curve but it'll be fairly easy to do your neat line. Then select your line and save as xaml. You'll get a file with a path in it, and your geometry. Extra nodes for a second and third car stop position.
Are your cars looking ok with the matrix animation? I wrote a facing converter to rotate moving (infantry or cavalry) columns so they face the direction they are moving in.
I have this wheel of fortune application. The wheel is a whole image.
I am able to spin and detect the angle when the wheel stops spinning.
This is the code for that:
private void SpinBtn_Click(object sender, RoutedEventArgs e)
{
var ease = new PowerEase { EasingMode = EasingMode.EaseOut };
Random rng = new Random(Guid.NewGuid().GetHashCode());
//DoubleAnimation(FromValue. ToValue, Duration)
double degree = rng.Next(360, 720);
DoubleAnimation myanimation = new DoubleAnimation
(0, degree, new Duration(TimeSpan.FromSeconds(3)));
double resultAngle = degree - 360;
double num = resultAngle % 45;
double quadrant = num + 1;
data.Content = resultAngle;
//Adding Power ease to the animation
myanimation.EasingFunction = ease;
RotateTransform rotate = new RotateTransform();
img.RenderTransform = rotate;
img.RenderTransformOrigin = new Point(0.5, 0.5);
rotate.BeginAnimation(RotateTransform.AngleProperty, myanimation);
}
However how do I check if the user drags the word to the textbox tallies with the image the pointer is pointing at? My lecturer requires me to store the words (I get from database) into an array and the object number in an array but I have no idea how to do it.
For example, object number 1 will fall in the angle range 0-45, object number 2 in 46-90 and so on. How do I go about with the checking?
I'm not quite sure whether I have completely understood what the problem here is!
But you can simply use a Dictionary to hold string values of each 45-degree slice and check it against the word user drags.
Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1, "Eraser");
dict.Add(2, "Glue");
dict.Add(3, "Pen");
dict.Add(4, "Scissors");
dict.Add(5, "Stapler");
dict.Add(6, "Sharpener");
dict.Add(7, "Ruler");
dict.Add(8, "Pencil");
And change your code to:
double degree = rng.Next(360, 720);
double resultAngle = degree - 360;
int num = (int)Math.Ceiling(resultAngle / 45);
Then, the name of the element the pointer is currently pointing at would be:
string currentElem = dict[num];
I am working to create a Move Animation in windows. I want to move and object from one location to the other. Basically what I am trying to do is to FLIP the selected rectangle and then randomly swap the positions of two Rectangle objects the movement should be shown as an animation.
I have tried and achieved FLIP animation. But now if there are 4 rectangles in a grid, random two rectangles should exchange their positions followed by a move animation. I tried to use the below code. But it is not working.
It just creates a Rectangle in the center of the screen and nothing else.
1) Created a new project
2) Added the below code to the MainPage.xaml.cs file.
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
Loaded += Create_And_Run_Animation;
// Sample code to localize the ApplicationBar
//BuildLocalizedApplicationBar();
}
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.
ContentPanel.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.
ContentPanel.Resources.Add("unique_id", sb);
// Begin the animation.
sb.Begin();
}
}
I haven't added anything in the xaml file. that is just as it is. Is there anything that i need to add to the xaml file for the animation to run properly. ?
Please Help
Better late than never ;-).
Just got the problem myself, you need to add
myDoubleAnimation1.EnableDependentAnimation = true;
myDoubleAnimation2.EnableDependentAnimation = true;
to your code to force WinRT to do execute animation - otherwise it deems your animation to be not worthy due to possible performance issues ... sigh.
Source: https://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.media.animation.doubleanimation.enabledependentanimation.aspx
Why below code doesn't change ScaleY to 1?
var transform = new ScaleTransform { ScaleY = 0 };
var story = new Storyboard();
var animation = new DoubleAnimation {
Duration = new Duration(new TimeSpan(0)), To = 1 };
Storyboard.SetTarget(animation, transform);
Storyboard.SetTargetProperty(animation, new PropertyPath("ScaleY"));
story.Children.Add(animation);
story.Begin();
I use transform indirectly: it use for render some UIElements and kept in their DependencyProperty.
Does it perhaps work if you drop the Storyboard and just call BeginAnimation directly?
var transform = new ScaleTransform { ScaleY = 0 };
var animation = new DoubleAnimation { Duration = TimeSpan.Zero, To = 1 };
transform.BeginAnimation(ScaleTransform.ScalyYProperty, animation);
Note that this will only have any effect if the animation's FillBehavior has a value of HoldEnd. Otherwise the animated property will immediately revert back to its local value (which is 0 here). Fortunately HoldEnd is the default value for FillBehavior.
And of course the transform should be used somewhere.
I've got a method that transforms a number of cylinders. If I run the method a second time it transforms the cylinders from their original position rather than their new position.
Is there anyway of 'applying' the transformation so that it changes the underlying values of the cylinders so that I can re-transform from the new values?
Can anyone assist?
Cheers,
Andy
void TransformCylinders(double angle)
{
var rotateTransform3D = new RotateTransform3D { CenterX = 0, CenterY = 0, CenterZ = 0 };
var axisAngleRotation3D = new AxisAngleRotation3D { Axis = new Vector3D(1, 1, 1), Angle = angle };
rotateTransform3D.Rotation = axisAngleRotation3D;
var myTransform3DGroup = new Transform3DGroup();
myTransform3DGroup.Children.Add(rotateTransform3D);
_cylinders.ForEach(x => x.Transform = myTransform3DGroup);
}
You are remaking the Transform3DGroup every time the method is called:
var myTransform3DGroup = new Transform3DGroup();
Transforms are essentially a stack of matrices that get multiplied together. You are clearing that stack every time you make a new group. You need to add consecutive transforms to the existing group rather than remake it.