Can I shake a users desktop using WPF? - wpf

I'm writing an application for personal use that will track how often I reach for the mouse, and will keep a counter of how long I've gone mouseless. When I use the mouse, I would like it to shake my desktop workspace for a second as a negative reinforcement action.
The application is going to be called WristSlap and will be on github as soon as I have a version 0.1 ready.

Danny is onto something with the transparent window idea. But it doesn't have to be transparent. You would have to accept some certain limitations though.
You would want to grab a screen shot of the desktop and apply it to a full screen WPF window. (Check out my blog for a handy FullScreenBehavior for WPF Window). Then you would just apply some epilepsy-inducing animation to a translate layout transform on the root element. This would give the effect of shaking. At the end the window could just close.
Since during the animation the coordinates of everything will be all over the place, you probably don't want to be bothered with trying to translate mouse clicks on the moving desktop to the underlying control. If the animation is short enough it won't matter because you won't have time to try to click anything while it is shaking.
For more realism you could look into using the DWM (Desktop Window Manager) to project a "live" view of the desktop but that's probably not worth it especially if you keep the animation very short.
I almost want to try this myself for fun.
I came up with this using a static image for now. It's ok but it could be improved.
<Image Source="Slide1.png" Stretch="UniformToFill">
<Image.Effect>
<BlurEffect Radius="5" />
</Image.Effect>
<Image.RenderTransform>
<TranslateTransform Y="0" X="0"/>
</Image.RenderTransform>
<Image.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard RepeatBehavior="00:00:01" SpeedRatio="15">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="-10"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="0"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="10"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.7000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)">
<SplineDoubleKeyFrame KeyTime="00:00:00.1000000" Value="-10"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="-10"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="10"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.7000000" Value="10"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.9000000" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Image.Triggers>
</Image>

You could create a transparent window with a changing twirl shader effect.
I'm not sure that will solve your addiction to computers though.

Related

Fading effect on mouseover / hover event for silverlight?

I have a set of buttons in a grid on a Map/MapControl. I've been trying to figure out how to make it so that the buttons and the grid are usually invisible, but appear as soon as the user hovers their pointer over them. Suggestions?
http://msmvps.com/blogs/theproblemsolver/archive/2009/02/17/changing-the-mouseover-effect-on-a-silverlight-listbox.aspx
Here is an article that goes through a tutorial (using blend) to setup various Visual States. About 3/4 down the page there is a sample xaml snippet. Look for this section:
<vsm:VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1.2"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1.2"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
Instead of changing the scale, you could change the Opacity... There's no reason this can't be written in Visul Studio, for the Blend-Challenged (like myself).
Also, refer to http://jesseliberty.com/2010/07/09/visual-state-manager-a-z/ for a set of tutorials for using the huge capabilities of the Visial State Manager.

Remove Silverlight Animation

I have a problem with my Silverlight animation that I can't seem to fix. The problem seems to be well established, but the techniques used to solve it don't seem to work in my case.
Here is the storyboard code that I am using to animate a grid called "underGrid". underGrid is a base grid which I am applying a scale and location offset to in response to mouse input from the user, so that they can scale and move the grid in real time. The ResetGrid storyboard below simply animates from the current scale and location values back to scale {1, 1} and location {0, 0}, resetting the view for the user. I wanted to be able to apply this animation whenever the user clicks a reset button but it freezes the Scale and Translation transforms once it has run once (as discussed here: http://msdn.microsoft.com/en-us/library/aa970493.aspx). Which means that when the user then uses the mouse to move the grid, it doesn't move. I've tried everything I can think of to stop the animation from having an affect on the dependency properties. I've tried hooking the Completed event and trying (amongst other things), stopping the animation, seeking the animation to 0, looping through the ResetGrid Children and using StoryBoard.SetTarget(). I've also tried setting the FillBehavior.. No matter what I do nothing seems to make a difference, the Scale and Translation are always tapped and cannot be set again in user-code.
Can anyone suggest anything I can try that I've not listed above (drastic or otherwise :) )? All I want is the animation to have completely stopped and detached itself on Complete.
Storyboard XAML:
<Storyboard x:Name="ResetGrid">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="underGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="underGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="0">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="underGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="underGrid" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1">
<EasingDoubleKeyFrame.EasingFunction>
<CubicEase EasingMode="EaseInOut"/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
will ResetGrid.stop() work?
I used it in my applications and the animation was cut off straight away.
animation.stop will stop and reset, while animation.pause will just stop on where timeline it hit
if not u can put another animation of duration 0,
call this animation to place back the property
I've run into this issue before too... check out this thread on Silverlight.Net which I think you might find helpful:
http://forums.silverlight.net/forums/t/68888.aspx

WPF Animation of border width

I've got a dockpanel on my ui as follows;
<DockPanel>
<Border DockPanel.Dock="Top">Header</Border>
<Border DockPanel.Dock="Bottom">My footer</Border>
<Border DockPanel.Dock="Left">Menu</Border>
<Border>Content</Border>
</DockPanel>
What I want to do is to have a storyboard animation to show / hide the Menu on the left-hand side. I've got my border to increase the width when it has loaded but I want a way to close / reopen it. I need a button somewhere but I want this to trigger the animation in the border control rather than itself. Ideally I was thinking of something like the Toolbox / Server Explorer in visual studio.
Does anyone have any pointers / examples for getting started?
Thanks
I'm not sure I understand what you mean, but if you want to animate it in/out then you probably want to update its width? If you have a property on your ViewModel/PresentationModel that you can bind to then you can do something like:
<DataTrigger Binding="{Binding IShouldBeVisible}" Value="True">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard AccelerationRatio="0.4" DecelerationRatio="0.4">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.Width)">
<SplineDoubleKeyFrame KeyTime="00:00:0.13" Value="100"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard AccelerationRatio="0.4" DecelerationRatio="0.4">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.Width)">
<SplineDoubleKeyFrame KeyTime="00:00:0.1" Value="0"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>
</DataTrigger>
If you are doing complicated animations that change multiple properties, different timings etc then it's much easier to put together in Blend, even if you do it in a test project then cut+paste the resulting StoryBoard :-)

Silverlight animation tweening

I am focusing on silverlight animation (as my previous posts probably indicate), and one of the things I can't find out is how can I do a scaletransform to zoom into an object (so it appears it is coming towards you), but rather than on event initiation it goes from one size to another, I want it to gradually increase in size?
For example, if you put your hand in front of you and draw it near to you, it is gradually getting closer whereas if you abruptly pull it towards you and stop, it goes from being far to being near with no sense of an in beTWEEN state. I want to get the tweening, so an object can be zoomed and then zoom in but at a small, repetitive increment.
You can just animate the scale tranform
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<EasingDoubleKeyFrame KeyTime="00:00:02" Value="2"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="image" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<EasingDoubleKeyFrame KeyTime="00:00:02" Value="2"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
The example above will double the height and width of an image over a period of two seconds.
Hope this helps.

Silverlight animation issue

Suppose I have the following XAML snippets, my confusion is what is the meaning of the value for Storyboard.TargetProperty? i.e. the meaning of "(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)".
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="p1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" BeginTime="00:00:00">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.2500000" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
...
<Path Height="2.75" Width="2.75" Data="M2.75,1.375 C2.75,2.1343915 2.1343915,2.75 1.375,2.75 C0.61560845,2.75 0,2.1343915 0,1.375 C0,0.61560845 0.61560845,0 1.375,0 C2.1343915,0 2.75,0.61560845 2.75,1.375 z" Fill="#FF9F9B9B" Stretch="Fill" Stroke="#FF000000" StrokeThickness="0" Canvas.Left="7" Canvas.Top="14" x:Name="p1">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Path.RenderTransform>
</Path>
thanks in advance,
George
The Storyboard.TargetProperty specifies a particular property to change over time.
If you were writing it yourself, you could say something like:
<DoubleAnimationUsingKeyFrames Storyboard.TargetName="myRectange"
Storyboard.TargetProperty="Width" BeginTime="00:00:00">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.2500000" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/>
</DoubleAnimationUsingKeyFrames>
and simplify things quite a bit. In the above example, you're changing the "Width" property of your rectangle over time. Blend, in its infinite WYSIWYG fashion, makes the targeting a little more complicated.
In your example, a transform is applied to the rectangle, and you're changing that transform over time.
Clarification:
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"
is a PropertyPath. It specifies the property that will be changed over time. In this example, we're targeting the Rectangle's->RenderTransforms->first child (the ScaleTransform)->Scale X property. That's how we say what's going to change. The keyframes specify how that value changes over time.
Something to keep in mind: A transform is a static change. Apply a ScaleX of 2, and the thing doubles in the X dimension. But nothing changes over time (nothing moves on the screen). For that, you need an animation to change the transform over time.
hth, Erik

Resources