Visual Blend Annimating Image Background - c#

If the user starts the app there should be a annimated background. The Background of the Maingrid is that picture above. The background should be moved. How can I do this in Visual Blend? I'm aware of how to create annimations in blend but I don't know how to do this kind of annimation.

I believe you are looking for something along the lines of this:
<Canvas.Resources>
<Storyboard x:Name="myStoryboard">
<!-- The PointAnimation has a name so it can be accessed
from code. The To property is left out of the XAML
because the value of To is determined in code. -->
<PointAnimation
x:Name="clockAnimation"
Storyboard.TargetProperty="Center"
Storyboard.TargetName="clockImage"
Duration="0:0:20"/>
</Storyboard>
</Canvas.Resources>
And this C# which can be done on a timer or on initialisation:
double newX = 'Where you want the new X coordinate of the clock';
double newY = 'Where you want the new Y coordinate of the clock';
Point myPoint = new Point();
myPoint.X = newX;
myPoint.Y = newY;
clockAnimation.To = myPoint;
myStoryboard.Begin();
I hope this works for you!

What you are asking to do (as i understand it) is impossible without modifying the image you've shown fundamentally.
From the sounds of it what you're looking to do is animate the hands in this static two-dimensional image. You can no more move the hands on the clock of this static image as you could if you were to print it out onto a sheet of paper and attempt the same.
One solution would be to use an image-editing tool such as photoshop to erase the hands in question leaving you with an empty clock-face.
From there you can use it as the background as you intend, but create assets on the layer(s) above the now modified image that replicate what the old clock-hands used to look like and animate them accordingly.
(For example; something that should be as simple as making 3 separate animations that have each hand turn 360 degrees, only with the second-hand's animation taking 60seconds to complete, the minute-hand taking 1hour to complete and of course the hour hand taking 12hours to complete its spin (but you said you're competent with animation so i'll leave this part to you).)

Related

Creating different brush patterns in c#

I'm trying to make something similar to paint. I'm trying to figure out how make different brush styles. Like in Paint 3D you get a certain line fills when using the pen tool vs using the paint brush tool.
I have no idea where to even start. I've spent a good portion of the day looking through documentations, and watching YouTube videos. I'm more lost than when I started. The closest thing I came across was line caps, but that's definitely not what I'm looking for.
!!See the UPDATE below!!
Hans' link should point you in the right direction, namely toward TextureBrushes.
To help you further here a few points to observe:
TextureBrush is a brush, not a pen. So you can't follow a path, like the mouse movements to draw along that curve. Instead, you need to find an area to fill with the brush.
This also implies that you need to decide how and when to trigger the drawing; basic options are by time and/or by distance. Usually, the user can set parameters for these often called 'flow' and 'distance'..
Instead of filling a simple shape and drawing many of those, you can keep adding the shapes to a GraphicsPath and fill that path.
To create a TextureBrush you need a pattern file that has transparency. You can either make some or download them from the web where loads of them are around, many for free.
Most are in the Photoshop Brush format 'abr'; if they are not too recent (<=CS5) you can use abrMate to convert them to png files.
You can load a set of brushes to an ImageList, set up for large enough size (max 256x256) and 32bpp to allow alpha.
Most patterns are black with alpha, so if you want color you need to create a colored version of the current brush image (maybe using a ColorMatrix).
You may also want to change its transparency (best also with the ColorMatrix).
And you will want to change the size to the current brush size.
Update
After doing a few tests I have to retract the original assumption that a TextureBrush is a suitable tool for drawing with textured tips.
It is OK for filling areas, but for drawing free-hand style it will not work properly. There are several reasons..:
one is that the TextureBrush will always tile the pattern in some way, flipped or not and this will always look like you are revealing one big underlying pattern instead of piling paint with several strokes.
Another is that finding the area to fill is rather problematic.
Also, tips may or may not be square but unless you fill with a rectangle there will be gaps.
See here for an example of what you don't want at work.
The solution is really simple and much of the above still applies:
What you do is pretty much regular drawing but in the end, you do a DrawImage with the prepared 'brush' pattern.
Regular drawing involves:
A List<List<Point>> curves that hold all the finished mouse paths
A List<Point> curentCurve for the current path
In the Paint event you draw all the curves and, if it has any points, also the current path.
For drawing with a pattern, it is necessary to also know when to draw which pattern version.
If we make sure not to leak them we can cache the brush patterns..:
Bitmap brushPattern = null;
List<Tuple<Bitmap,List<Point>>> curves = new List<Tuple<Bitmap,List<Point>>>();
Tuple<Bitmap, List<Point>> curCurve = null;
This is a simple/simplistic caching method. For better efficiency you could use a Dictionary<string, Bitmap> with a naming scheme that produces a string from the pattern index, size, color, alpha and maybe a rotation angle; this way each pattern would be stored only once.
Here is an example at work:
A few notes:
In the MouseDown we create a new current curve:
curCurve = new Tuple<Bitmap, List<Point>>(brushPattern, new List<Point>());
curCurve.Item2.Add(e.Location);
In the MouseUp I add the current curve to the curves list:
curves.Add(new Tuple<Bitmap, List<Point>>(curCurve.Item1, curCurve.Item2.ToList()));
Since we want to clear the current curve, we need to copy its points list; this is achieved by the ToList() call!
In the MouseMove we simply add a new point to it:
if (e.Button == MouseButtons.Left)
{
curCurve.Item2.Add(e.Location);
panel1.Invalidate();
}
The Paint goes over all curves including the current one:
for (int c = 0; c < curves.Count; c++)
{
e.Graphics.TranslateTransform(-curves[c].Item1.Width / 2, -curves[c].Item1.Height / 2);
foreach (var p in curves[c].Item2)
e.Graphics.DrawImage(curves[c].Item1, p);
e.Graphics.ResetTransform();
}
if (curCurve != null && curCurve.Item2.Count > 0)
{
e.Graphics.TranslateTransform(-curCurve.Item1.Width / 2, -curCurve.Item1.Height / 2);
foreach (var p in curCurve.Item2)
e.Graphics.DrawImage(curCurve.Item1, p);
e.Graphics.ResetTransform();
}
It makes sure the patterns are drawn centered.
The ListView is set to SmallIcons and its SmallImageList points to a smaller copy of the original ImageList.
It is important to make the Panel Doublebuffered! to avoid flicker!
Update: Instead of a Panel, which is a Container control and not really meant to draw onto you can use a Picturebox or a Label (with Autosize=false); both have the DoubleBuffered property turned on out of the box and support drawing better than Panels do.
Btw: The above quick and dirty example has only 200 (uncommented) lines. Adding brush rotation, preview, a stepping distance, a save button and implementing the brushes cache takes it to 300 lines.

How can I prevent WinForms Chart from resizing as data is added?

How can I prevent a WinForms Chart object from autosizing on the X axis when a new tickmark comes up?
A picture, or in this case a gif, is worth a thousand words:
See the little jump when a new gridline, tick, and label show up? Super annoying.
I'm pretty sure that the setting is somewhere in chart1.ChartAreas[0].AxisX but I haven't been able to find anything that prevents this from happening.
Where should I look?
When adding points at some point a new axis label must be added at each new interval. Since it is drawn centered at the value the chart needs to make room for it to both sides. The extra room to the right side then takes a while to be filled with data. This results in the jumps..
In my test the most straightforward solution was to simply omit the last axis label:
Axis ax = chart1.ChartAreas[0].AxisX;
ax.LabelStyle.IsEndLabelVisible = false;
Of course turning it back on when no more points are being added is a good idea.
Another, much more involved solution might be to disable the axis labels altogether and draw them in a xxxPaint event..

Silverlight different behaviour when being run from website

I am working on a simple Silverlight application. The point of application is to display data loaded from XML file. Data consists of String "password" and Integer "passwordCount". Each loaded position is displayed as a coloured square and whenever user moves mouse over this square it is resized to "passwordCount/10" pixel width or height and the "password" string is displayed on it. Here is an example:
On Mouseover:
Everything works fine if I run it via VisualStudio Run button. The problem is that when I place the script on website, tiles resize in the wrong direction (they become smaller instead of bigger). The text is not displayed either. I don't have the faintest idea why. Silverlight on website opens in a separate window and it looks like that on mouseover:
(source: screenshu.com)
Here is the function I use to animate tiles:
public void rectangle_MouseEnter(object sender, MouseEventArgs e)
{
sbMouseON = new Storyboard();
DoubleAnimation sizeAnimation = new DoubleAnimation();
sizeAnimation.To = passwordCount/10; //passwordCount is always greater than 1000
sizeAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(300));
Storyboard.SetTarget(sizeAnimation, (Rectangle)sender);
Storyboard.SetTargetProperty(sizeAnimation, new PropertyPath(direction));
sbMouseON.Children.Add(sizeAnimation);
Canvas.SetZIndex(rect, 2); //move rectangle up to make animation visible
DrawTextBlock();
sbMouseON.Begin();
}
Mods: Can't Add Comment so posting as answer
Here I am assuming that the "direction" you are passing in the TargetProperty is "(FrameworkElement.Width)" to increase the width of the rectangle.
If so only Logical Reason a Object can reduce in size is "sizeAnimation.To" property you are setting is setting the value which is smaller than the actual width of the object.
What is this DrawTextBlock() doing ? is there any code in there which can change the behavior of animation ?
The problem solved itself. I've just copied all files onto server and it works great. Looks like it was some Windows problem. Thank you for your interest #Abhinav.

Transparency of ModelVisual3D with DiffuseMaterial

I come across a problem which seems a bug for me. I'm making an app that visualizes atoms in a crystal. That problem is that it draws a transparent object and hides the object behind.
Here is the code:
foreach (var atom in filteredAtoms)
{
var color = new Color();
color.ScR = (float)atom.AluminiumProbability;
//color.G = 50;
color.ScB = (float)atom.MagnesiumProbability;
//setting alpha channel but Opacity doens't work as well
color.ScA = (float)(1.0 - atom.VacancyProbability); //(float)1.0;//
DiffuseMaterial material = new DiffuseMaterial(new SolidColorBrush(color));
//material.Brush.Opacity = 1.0 - atom.VacancyProbability;
// make visuals and add them to
atomBuldier.Add(new Point3D(atom.X * Atom.ToAngstrom, atom.Y * Atom.ToAngstrom, atom.Z * Atom.ToAngstrom), material);
}
When I change the material to e.g. EmissiveMaterial there are no "cut" atoms. I googled this post, but the advices given don't apply to this case.
Is this a bug with 2D brush applied to 3D?
The full source code can be found here http://alloysvisualisation.codeplex.com the dll and a test file http://alloysvisualisation.codeplex.com/releases beta link.
Steps to reproduce:
Lunch app
Click Open file button
Open test file (xyzT2000.chmc)
Click Mask button
Check 11 (series of atoms are almost transparent)
Ckick Redraw
For the transparent atoms, you must disable z-buffer-writing. I'm unfamiliar with WPF, but you can probably set this in an Appearance or Material object or so.
The problem occurs because of the following:
When a transparent atom is rendered, it writes its depth to the z-buffer. Subsequent non-transparent atoms that are rendered and should appear, do not get written to the frame buffer, because their z-values fail the z-test, because of the z-values already in the z-buffer of the transparent atom.
In short, the graphics card treats the transparent atom as opaque and hides anything behind it.
Edit: Upon looking into WPF it seems pretty high-level, without direct control of z-buffer behavior.
According to this link, the emissive and specular materials do not write to the z-buffer, so using those is your solution when working with transparent objects.

Partially shaded circle timer in WPF

Where can I get started drawing animated geometry in C#? I would like to draw a sort of countdown timer by drawing a partially shaded circle. At start the circle would be fully shaded, at 75% 3/4 of the circle would be shaded and at 0 completely unshaded. I really don't know where to begin with something like this.
If you still don't understand what I need, a lot of games use this sort of animation to represent a "cooldown" on an item or skill. Like a second hand going around a clock, revealing what is beneath it.
WPF is my target application but I imagine I will need to use some sort of GDI api.
You could start out with the drawing examples here, for how to make your pie-like graphic:
http://www.codeproject.com/KB/WPF/PieChartDataBinding.aspx
It looks like they use StreamGeometryContext, along with LineTo and ArcTo.
You could then work on applying an animation to the properties on that graphic, so the "slice" gets bigger over time, by changing the arc length:
http://msdn.microsoft.com/en-us/library/ms752312.aspx#applyanimationstoproperty
You could then wrap this all up nicely in a UserControl, with custom dependency properties, so you can reuse this throughout your app.
Edit: I was thinking you meant the shaded pie like in World of Warcraft. What you want is actually simpler. See can poyrazoğlu's answer for the graphical approach to take (although you really only need the top black circle, if you're going with an opacity approach).
Yes, it's really easy with WPF.
Just create another circle on top of the circle, make that one black, and let a timer update the opacity of the top circle from 1 to 0 by time (or whatever you want).
This is the "easy" way. A more "convenient", or "WPF-style" approach would include Bindings and possibly value conversions, you'll be binding the opacity of the circle to a custom value with a value converter (or decrementing that value, anyway there are lots of ways).
Choose whatever you want. They'll both work.

Categories

Resources