C# WPF How to handle animation reaching a certain point? - c#

I'm kinda new to WPF and just started looking into animations, and just for fun i started creating the old-school game Frogger (the one with a frog that has to cross a river/road while not getting hit by cars etc).
I made the animation for the log of wood moving across the screen in the river:
<Canvas>
<Rectangle Name="shape_WaterBackground" Fill="#1E90FF" Height="20" Width="260" Canvas.Top="240"/>
<Rectangle Name="shape_Lumber" Width="40" Canvas.Top="240" Fill="Brown" Height="16" Margin="0,2,0,0" />
<Image Name="Froggy" Height="20" Width="20" Canvas.Top="300" Canvas.Left="120" Source="Froggy.jpg" />
</Canvas>
And the code-behind for this particular animation:
DoubleAnimation Animate_Lumber_Movement = new DoubleAnimation(-40, 280, TimeSpan.Parse("0:0:7"));
Animate_Lumber_Movement.RepeatBehavior = RepeatBehavior.Forever;
shape_Lumber.BeginAnimation(Canvas.LeftProperty, Animate_Lumber_Movement);
Now my question is, how do I handle when the log reaches a certain point. The reason is (like you've probably already guessed) that I would like to know how to execute an action mid-way through the animation (a different point or time in the animation, and not a static) ofc without stopping the animation.
Its somewhat the same problem I have as described in here:How to determine when an animated sprite reaches a point?, but for C# WPF.
As an example in the code above, i want the frog to survive if it jumps towards the river and its Canvas.Leftproperty matches the animated logs, or otherwise drown.
Any suggestion is greatly appreciated (but bear in mind that I'm a newbie)
Sorry for the not-so-well-explained question :)
Thank you and best regards
Lodal

Since you're just animating the Canvas.Left property, you could always just set up a DispatcherTimer and read it (Canvas.GetLeft or Canvas.GetTop).
Although, maybe this is just me, but conceptually, WPF animations are more for short spurts, sort of like screen transitions and the like - not really for handling entire game animations. If that's your aim, you're probably just better off handling the animation yourself (set up a DispatcherTimer, and then on each tick you would update your game state).

Related

How are the semi-transparent blur windows in OSX and W10 Start Menu created?

I'm currently working on a window that focuses on some elements on screen while blurring the rest of the area.
Using common methods like the WindowCompositionAttribute and the others are not suitable for this situation as there are limitations to it and it doesn't meet the standards regarding the intensity of the blur, contrast and colors which should be strict.
What i have managed to solve my problem was building an image stream with a light image encoder to enhance performance but then that wasn't enough. So, i thought of writing a motion detection algorithm to only steam when there's motion, but it still didn't change the performance drops.
What i need is something like those of the native OSX windows and Windows 10 Start Menu, so how are they created and run efficiently without any heavy load on the performance?
To create a new Window from scratch you have to set WindowsStyle to none (AllowTransparency="True" can be set only along with WindowsStyle="None") and from there build the style of the window.
However, you will face several issues if you follow this approach:
-no buttons (minimize, close)
-no support for fullscreen (taskbar issues)
I would suggest you to have a base view and include the other views inside the main view(which has the blur effect).
The blur effect could be obtained easily by doing something like below:
<Grid>
<Grid Margin="5" Background="#FF3782DC">
<!--<Grid.Background>
<Image Source="test.png"></Image>
</Grid.Background>-->
<Grid.Effect>
<BlurEffect Radius="100" />
</Grid.Effect>
</Grid>
<TextBlock
x:Name="textBlock"
Height="61"
Margin="136,82,211,0"
VerticalAlignment="Top"
Text="test"
TextWrapping="Wrap" />
</Grid>
I've set a color for the background, but you could set an image as background and by default it would be blurred (here you should set a binding and every time the view changes, you have to take a snapshot of the screen and set the source of the Image). However you will probably have some performance issues, but with a good encoder (JPEGencoder) it will be fast enough.
Hope that helps you!

How does this DrawingBrush Geometry graph grid work?

I just started using Geomectry Drawing in xaml and I came across this interesting article https://msdn.microsoft.com/en-us/library/aa480159.aspx. Here, I find out that the following drawingbrush gives a graph diagram as an output.
<DrawingBrush x:Name="gridBackgroundBrush"
Viewport="0,0,10,10"
ViewportUnits="Absolute"
TileMode="Tile">
<DrawingBrush.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Geometry="M0,0 L1,0 1,0.1, 0,0.1Z" Brush="Green" />
<GeometryDrawing Geometry="M0,0 L0,1 0.1,1, 0.1,0Z" Brush="Green" />
</DrawingGroup.Children>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
From further reading, I figure out that M means starting point or move to, L means line and Z means close but could not figure out how this will give me two lines - one horizontal and one vertical? Any help understanding this will be highly appreciated. Thanks.
So here's a quick break down for you.
Your example is a DrawingBrush which is explicitly set to TileMode="Tile" which is the equivalent of repeat-x/repeat-y if you're more familiar with CSS as example. So it's instructed to repeat itself up-down/left-right repeating.
Your two bits of your Geometry Drawing if translated individually are two squares with one stretching vertical, one stretching horizontal. While your explicitly set ViewportUnits is dictating the size and position effectively making repeated columns and rows.
Your Path Geometry uses Path Markup Syntax to draw these lines as you pointed out. For a more visual explanation replace your Brush on each.
<GeometryDrawing Geometry="M0,0 L1,0 1,0.1, 0,0.1Z" Brush="Red" />
<GeometryDrawing Geometry="M0,0 L0,1 0.1,1, 0.1,0Z" Brush="Blue" />
...and voila! You have yourself a repeated line background with effective vertical/horizontal columns creating your grid. See links for more detail and hope this helps. Cheers!
Oh, and the question you got that from also had a link that would have shed a little light on it but not as much as you'd like so I didn't mark this duplicate.
ADDENDUM:
A little more clarification. Though if you want to learn more I'd follow the documentation link someone spent a lot of time writing to answer this already. Think if you have an x,y grid you're drawing points on.
Say you're using the pen tool in something like Adobe Illustrator, or Blend. Your first click is setting your M as your start point based on the relative size of the container. Then you click in another spot...well now you effectively have a L line.
So when we see: M0,0 L1,0 that's our first starting Line. In this case it's the top corner stretching to the right corner since there's not another anchor in the line between the two points. The next set acts as the anchor to tell that line to change it's direction to make the side, and so on, and so fourth until you hit the end at Z. Hope this helps but I would encourage the documentation first.
Here they are individually if you feel like tinkering with numbers and learning:
<Path Data="M0,0 L1,0 1,0.1, 0,0.1Z"
Height="150" Width="150" Stroke="Red" />
<Path Data="M0,0 L0,1 0.1,1, 0.1,0Z"
Height="150" Width="150" Stroke="Blue" />
I came cross the same thing when I used GMaps V3. It is an SVG path notation path that allows you to draw on WPF and on browsers too. You can find the complete documentation in the link.

Circular CaptureElement camera stream in Windows 10

Wherever you look in Windows 10, there are circles. It's fairly easy to make images circular, but camera is a bit different. Is there a simple XAML way to clip the camera stream in a CaptureElement to make it a circle?
I tried putting it in a border, but CaptureElement doesn't care about its borders. I also tried using the Clip property, but it can only clip to RectangleGeometry.
One way would certainly be to grab CaptureElement frames, transforming them to images (frame by frame) and applying to Image element, and then clipping the image, but it seems like that would have awful performance.
Is there something in the framework to make this really simple, but I'm not seeing it?
Well after seeing that might be the background is always black of the Canvas DirectX the only way I see is:
1.- Clip a rectangle with an ellipse in Inkscape for instance.
2.- Copy to Expression Design and Ctrl-Shift-C (to copy XAML)
3.- Place inside a ViewBox only the path generated
<Grid Width="300" Height="300">
<CaptureElement Name="PreviewControl" Stretch="Uniform" Width="280" Height="280" />
<Viewbox Width="280" Height="280">
<Path Width="813.701" Height="813.701" Canvas.Left="-33.3503" Canvas.Top="-45.3503" Stretch="Fill" Fill="#FF800080" Data="F1 M -33.3503,-45.3503L -33.3503,768.35L 780.35,768.35L 780.35,-45.3503L -33.3503,-45.3503 Z M 373.54,158.095C 485.863,158.095 576.985,249.137 576.985,361.54C 576.985,473.863 485.863,564.985 373.54,564.985C 261.137,564.985 170.095,473.863 170.095,361.54C 170.095,249.137 261.137,158.095 373.54,158.095 Z "/>
</Viewbox>
</Grid>
With that you can place an image in the path or a solid color, that's the only way I see to do it. Hope it helps

c# WPF Change the check color of a CheckBox

<CheckBox Background="White" IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
I need to change the color of the check. I figured Forground did this since Background changed the background color but to no avail.
Any ideas? Surly there is a way to directly change the check color. I tried googling this but the only solution I found was to make my own checkbox class.
Where is the property to change the CheckBox Check color?
I found one answer with
<Path Visibility="Collapsed"
Width="7"
Height="7"
x:Name="CheckMark"
SnapsToDevicePixels="False"
StrokeThickness="2"
Data="M 0 0 L 7 7 M 0 7 L 7 0">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path>
But that does not work since I cannot add that as a child element. Even if it worked, it would change too much. All I want is a white background with a black checkmark. Grey on Grey is terrible looking. Isn't there a built in way to change the color?
Unfortunately, the WPF folks decided to make the checkbox a BEAST to deal with. The check itself is actually a "BulletChrome" control, if you study the template. Now, the problem is that the BulletChrome control is all written in C# and not customizable at all from the outside, not via XAML, so all the pens and brushes are hard-coded. You'll find with Reflector or IlSpy, that you are after the GlyphStroke and GlyphFill properties and those two properties clone internal hardcoded brushes.
I had to do the same thing you did, and I ended up just copying the entire class out using ILSpy and modifying it just to tweak a few things.
Not the answer you'd hoped for, but there isn't a way to override this control easily.
EDIT: well, you could modify the two brushes with reflection if you want. That's easier then copying the whole class out :).
Its a beast of a class, so... BulletChrome.cs = 2262 lines!
EDIT #2: btw, doing a quick 1 or 2 line hack will break the animations, so you need to go the correct route if you care about those :).
EDIT #3: don't forget there are quite a few states for the check mark. Hover, pressed, disabled, etc. and lots of animations and transitions. So anybody who gives you a quick answer doesn't understand how this control is put together.
This is as annoying as SledgeHammer said with the Bullet bs. basically, the brushes are hardcoded, so there isn't an easy solution.
That being said, Here is a quick 1 line hack. This doesn't break animations on my machine.
Though, as SledgeHammer pointed out, there are several different states. I'll leave it up to you to override which ones you need. This will do the basic check.
typeof(BulletChrome).GetRuntimeFields().Where(f => f.Name == "_commonCheckMarkFill").First().SetValue(null, new SolidColorBrush(Colors.Yellow));
You're also going to have to reference PresentationFramework.Aero and include using Microsoft.Windows.Themes;
Its worth pointing out, this will affect every CheckBox, and potentially (depending on which brushes you overwrite) RadioButton, so depending on your needs, YMMV. But it does what you asked for.

Proper way to perform camera preview mirroring mode

Currently, when tested using Media capture using capture device sample, I realize the camera is not something I want. I wish it to be in mirroring mode. Currently, it is not.
For a camera preview to be in mirroring mode, may I know is it hardware dependent or hardware independent. Possible that if I run the same code with different hardware, the camera preview will be in mirroring mode? If it is hardware dependent, how can I check whether my camera preview is in mirroring/non-mirroring mode?
To make it in mirroring mode, I try to follow this thread. I try MediaCapture.SetPreviewMirroring(true). No effect as all. The camera preview is still in non-mirroring mode.
I try captureElement.RenderTransform = new ScaleTransform() { ScaleX = -1 };. The whole camera preview become plain grey color.
The last approach I would like to try, is try to perform flipping in C++ code through MediaCapture.AddEffectAsync(). However, that need to go back to my first question. Can I just simply perform flipping, or do I first need to check whether the incoming buffer is in mirroring/non-mirroring mode? If yes, how do I check?
For those looking for a more updated answer since this question was asked, the proper way on UWP and WinUI is to set the FlowDirection="RightToLeft" on the CaptureElement.
<CaptureElement x:Name="previewElement" FlowDirection="RightToLeft"/>
Use
<CaptureElement x:Name="previewElement" Margin="0" Stretch="UniformToFill" RenderTransformOrigin="0.5,0.5">
<CaptureElement.RenderTransform>
<CompositeTransform ScaleX="-1"/>
</CaptureElement.RenderTransform>
</CaptureElement>
The key lied on RenderTransformOrigin="0.5,0.5". We need to flip from center of preview.

Categories