Skip to main content
Home Forums General Silverlight Getting Started Collapsing a Canvas
15 replies. Latest Post by markheath on June 2, 2007.
(0)
markheath
Member
117 points
63 Posts
05-25-2007 9:59 AM |
I have a Canvas with a few textblock and rectangles on it, and I am using an animation to 'collapse' the canvas by reducing its width. However, the items on the Canvas remain visible even though they are now outside the bounds of their parent canvas. I thought that the Clip property might help me, with a RectangleGeometry that I could reduce, but I don't know the syntax for specifying the width of the Rect property of RectangleGeometry
<Storyboard x:Name="collapse"> <DoubleAnimation Storyboard.TargetName="MidCanvas" Storyboard.TargetProperty="Width" To="100" Duration="0:0:1" /></Storyboard>
<Canvas x:Name="MidCanvas" ... etc
Am I on the right lines with animating a Clip rectangle or is there another trick I can use?
Mark
LostInTh...
64 points
38 Posts
05-25-2007 4:43 PM |
You could collapse a canvas by doing a scale transform on the X from 100% (1.0) to 0% (0.0). Is this the effect you are trying to achieve?
05-25-2007 4:46 PM |
Some XAML code to help:
<Canvas IsHitTestVisible="false" Opacity="0" x:Name="MyCanvas"> <Canvas.RenderTransform> <ScaleTransform x:Name="MyCanvas.Scale" /> </Canvas.RenderTransform> <Canvas.Resources> <Storyboard x:Name="Collapse"> <DoubleAnimation Storyboard.TargetName="MyCanvas.Scale" Storyboard.TargetProperty="(ScaleX)" From="0" To="1" Duration="0:0:0.3" /> </Storyboard> </Canvas.Resources>
<!-- Items in the Canvas -->
</Canvas>
05-25-2007 5:18 PM |
thanks for the suggestion, but I actually don't want the contents of the Canvas to move or change size - I just want the right hand edge to progressively be chopped off, a bit like when you resize a window in Windows to make it narrower.
Imagine that XXX and YYY are other visual elements and in between them there is a Canvas with a "hello world" textblock on it. What I want to happen is this:
XXX hello world YYY (before animation)
XXX hello woYYY (1/2 way through animation)
XXX heYYY (after animation)
but what I see is:
XXX heYYYorld
not sure if that makes it clearer or not! (obviously in this trivial example I could simply reduce the width of the textblock, but the Canvas has more than just one element on it).
WynApse
Star
8456 points
342 Posts
05-25-2007 5:27 PM |
Hi Mark...
I thought you wanted the whole canvas to shrink down, initially, but after reading this post (and maybe I'm worng), it doesn't sound that way.
I had questions early-on about something that I think is related to this... I wanted to slide a rectangle out of a point on a canvas, and then slide it back in. I ended up using that as a slide-out menu on one demo, and ultimately wrote an article about clipping rectangles here:
http://www.wynapse.com/Silverlight/Tutor/Clipping_Silverlight_Animated_Rectangles.aspx
I understand it's not exactly what you're asking about, but it's a working example of something that you might be able to modify into what you DO want.. let me know if I'm completely off base, or if it gets you closer.
-Dave
05-26-2007 5:50 AM |
thanks Dave, its a useful sample, but I think you are able to get away with sliding one object behind another, which I do not want to do (although I may have to use as a last resort).
What I think I need is a RectAnimation, but this doesn't seem to be supported in Silverlight, so unless I can point a DoubleAnimation at the Rect.Width property of a RectangleGeometry, then I am not sure how I can animate the Clip rectangle for my Canvas. But all my attempts to animate Rect.Width have failed.
here's my Canvas
<Canvas x:Name="MidCanvas" Background="LightBlue" Canvas.Top="5" Canvas.Left="120" Width="500" Height="100"> <Canvas.Clip> <RectangleGeometry x:Name="MidCanvasClipRect" Rect="0,0,500,100"> </RectangleGeometry> </Canvas.Clip>
here's my attempt at animating the Clip Rect width, but it doesn't do anything
<Storyboard x:Name="collapse"> <DoubleAnimation Storyboard.TargetName="MidCanvasClipRect" Storyboard.TargetProperty="Rect.Width" To="100" Duration="0:0:1" />
05-26-2007 6:06 AM |
I tried another idea, where I tried to animate the scale of my clip rectangle from ScaleX = 1 to ScaleX = 0, which does at least mean I can use a DoubleAnimation, but it doesn't seem to do anything:
<Canvas.Clip> <RectangleGeometry x:Name="MidCanvasClipRect" Rect="0,0,500,100"> <RectangleGeometry.Transform> <TransformGroup> <ScaleTransform x:Name="ClipScale" ScaleX="1.0" ScaleY="1.0" /> </TransformGroup> </RectangleGeometry.Transform> </RectangleGeometry> </Canvas.Clip>
Animation:
<DoubleAnimation Storyboard.TargetName="ClipScale" Storyboard.TargetProperty="ScaleX" To="0" Duration="0:0:1" />
again, any suggestions gratefully received, as I am running out of ideas!
05-26-2007 6:41 AM |
Here's a full sample you can paste into SilverlightPad (http://www.simplegeek.com/mharsh/silverlightpad/) which might make it easier to visualise what I am trying to achieve.
<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="500" Height="200" Background="White"><TextBlock Canvas.Top="5">Hidden Text - Should be revealed as Canvas Collapses</TextBlock><Canvas x:Name="CollapseMe" Background="LightBlue" Width="400" Height="60"><Canvas.Triggers><EventTrigger><BeginStoryboard><Storyboard x:Name="Collapse"> <DoubleAnimation Storyboard.TargetName="CollapseMe" Storyboard.TargetProperty="Width" To="100" Duration="0:0:1" AutoReverse="true" RepeatBehavior="forever" /></Storyboard></BeginStoryboard></EventTrigger></Canvas.Triggers><Rectangle Stroke="Black" Canvas.Left="50" Canvas.Top="30" Width="200" Height="20" /><TextBlock Canvas.Top="5" Canvas.Left="5">This text and rectangle should be clipped</TextBlock></Canvas></Canvas>
Obviously I need to animate the Canvas' Clip Rectangle width, not the Canvas width itself, but I can't work out how to do this.
05-26-2007 7:42 AM |
How about this...
Make a timer (using either set Interval or a Silverlight Animation timer) and with each tick of the timer you switch out the clip object:
var xIndex -= 5var ClippingString = '<RectangleGeometry x:Name="MidCanvasClipRect" Rect="0,0,' + xIndex + ',100">';var ClippingGeometry = SilverlightContent.createFromXaml(ClippingString);
myCanvas.clip = ClippingGeometry;
Bill Reiss
Contributor
4840 points
919 Posts
05-26-2007 1:46 PM |
markheath: I tried another idea, where I tried to animate the scale of my clip rectangle from ScaleX = 1 to ScaleX = 0, which does at least mean I can use a DoubleAnimation, but it doesn't seem to do anything: <Canvas.Clip> <RectangleGeometry x:Name="MidCanvasClipRect" Rect="0,0,500,100"> <RectangleGeometry.Transform> <TransformGroup> <ScaleTransform x:Name="ClipScale" ScaleX="1.0" ScaleY="1.0" /> </TransformGroup> </RectangleGeometry.Transform> </RectangleGeometry> </Canvas.Clip> Animation: <DoubleAnimation Storyboard.TargetName="ClipScale" Storyboard.TargetProperty="ScaleX" To="0" Duration="0:0:1" /> again, any suggestions gratefully received, as I am running out of ideas! Mark
I tried this too, and it behaves the way you want it to in Blend when you play the animation, so it looks like it may be a bug. I also tried to set ScaleX like it's defined above on a timer and it didn't seem to work either. You could only set it once and then it wouldn't respond anymore. Hope you have better results.
05-26-2007 2:02 PM |
Maybe because Blend works for WPF but not for Silverlight?
The way I get this to work is by replacing the Canvas.Clip property every frame.
05-26-2007 8:40 PM |
I meant Blend 2 in a Silverlight project. The things that aren't supported are typically because that particular control hasn't been implemented in Silverlight, but I would expect that if a property can be set manually, that it would also work in an animation. Thanks for the help.
05-29-2007 4:54 AM |
LostInTheCosmos: How about this... Make a timer (using either set Interval or a Silverlight Animation timer) and with each tick of the timer you switch out the clip object:
Yes, this would work, and looks like my only option. I would still be interested to hear from Microsoft if there is a way I can achieve what I want using normal animation, or if they have plans to add this to a future Silverlight.
swirling...
Participant
1348 points
385 Posts
05-29-2007 6:20 PM |
You can use a different geometry for your clip. Specifically, a pathgeometry, composed of four linesegments, which together make your rectangle. Use two pointanimations to simultaneously collapse the top and bottom lines:
<
</
05-30-2007 2:58 AM |
swirlingmass:You can use a different geometry for your clip. Specifically, a pathgeometry, composed of four linesegments, which together make your rectangle. Use two pointanimations to simultaneously collapse the top and bottom lines:
Excellent - that is exactly what I wanted to achieve! Hopefully we'll get RectAnimation in the future, but this solution will work for now.
thanks
06-02-2007 3:56 AM |
I've found another easy way to do what I want in WPF, which allows the width of the Canvas to be animated with a DoubleAnimation rather than needing to animate the Canvas' Clip Geometry
<Canvas x:Name="CollapseMe" Background="LightBlue" Width="400" Height="60" ClipToBounds="true" >
Unfortunately it looks like the Silverlight Canvas doesn't have this capability either, so here's another feature request for the next drop of Silverlight.