Skip to main content

Microsoft Silverlight

Answered Question Collapsing a CanvasRSS Feed

(0)

markheath
markheath

Member

Member

117 points

63 Posts

Collapsing a Canvas

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

LostInTheCosmos
LostInTh...

Member

Member

64 points

38 Posts

Re: Collapsing a Canvas

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?

LostInTheCosmos
LostInTh...

Member

Member

64 points

38 Posts

Re: Collapsing a Canvas

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>

markheath
markheath

Member

Member

117 points

63 Posts

Re: Collapsing a Canvas

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).

Mark

WynApse
WynApse

Star

Star

8456 points

342 Posts

Silverlight MVP

Re: Collapsing a Canvas

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

Stay in the 'Light
Silverlight MVP
http://www.wynapse.com

markheath
markheath

Member

Member

117 points

63 Posts

Re: Collapsing a Canvas

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" />
 

 

Mark

markheath
markheath

Member

Member

117 points

63 Posts

Re: Re: Collapsing a Canvas

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

markheath
markheath

Member

Member

117 points

63 Posts

Re: Re: Re: Collapsing a Canvas

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.

Mark

LostInTheCosmos
LostInTh...

Member

Member

64 points

38 Posts

Re: Re: Re: Collapsing a Canvas

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 -= 5
var ClippingString = '<RectangleGeometry x:Name="MidCanvasClipRect" Rect="0,0,' + xIndex + ',100">';
var ClippingGeometry = SilverlightContent.createFromXaml(ClippingString);

myCanvas.clip = ClippingGeometry;

Bill Reiss
Bill Reiss

Contributor

Contributor

4840 points

919 Posts

Silverlight MVP

Re: Re: Collapsing a Canvas

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.


Bill Reiss, Coauthor of Hello! Silverlight 3
My blog (rss feed)

LostInTheCosmos
LostInTh...

Member

Member

64 points

38 Posts

Re: Re: Collapsing a Canvas

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.

 

Bill Reiss
Bill Reiss

Contributor

Contributor

4840 points

919 Posts

Silverlight MVP

Re: Re: Collapsing a Canvas

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.


Bill Reiss, Coauthor of Hello! Silverlight 3
My blog (rss feed)

markheath
markheath

Member

Member

117 points

63 Posts

Re: Re: Re: Collapsing a Canvas

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.

 

swirlingmass
swirling...

Participant

Participant

1348 points

385 Posts

Answered Question

Re: Re: Re: Collapsing a Canvas

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:

<Canvas xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="500" Height="200" Background="White">

<TextBlock Canvas.Top="5" Text="Hidden Text - Should be revealed as Canvas Collapses"></TextBlock>

<Canvas Name="CollapseMe" Background="LightBlue" Width="400" Height="60">

<Canvas.Clip>

<PathGeometry>

<PathFigure IsClosed="true">

<LineSegment Name="seg1" Point="0,0"/>

<LineSegment Name="seg2" Point="400,0"/>

<LineSegment Name="seg3" Point="400,60"/>

<LineSegment Name="seg4" Point="0,60"/>

</PathFigure>

</PathGeometry>

</Canvas.Clip>

<Canvas.Triggers>

<EventTrigger>

<BeginStoryboard>

<Storyboard Name="Collapse">

<PointAnimation Storyboard.TargetName="seg2" Storyboard.TargetProperty="point"

To="0,0" Duration="0:0:2" AutoReverse="true" RepeatBehavior="forever" />

<PointAnimation Storyboard.TargetName="seg3" Storyboard.TargetProperty="point"

To="0,60" Duration="0:0:2" 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" Text="This text and rectangle should be clipped"></TextBlock>

</Canvas>

</Canvas>

markheath
markheath

Member

Member

117 points

63 Posts

Re: Re: Re: Collapsing a Canvas

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

Mark

 

markheath
markheath

Member

Member

117 points

63 Posts

Re: Re: Re: Collapsing a Canvas

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.

  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities