posted on Monday, August 22, 2005 5:32 PM by Jonathan Hodgson

Optical Illusions, XAML and WinFX

I really like optical illusions and this post by Ian Moulster caught by eye.

If you stare at the central +, you should start to see a green circle and then the purple circles will disappear.

Read the full explanation as to why our vision is affected.

Another favourite of mine is Escher's work especially the Drawing Hands and High & Low.

 

Well Ian wondered when someone would produce a version in XAML, so how could I resist! It's been a while since I've played with XAML, previously I did some Data Visualisation using Treemaps under Longhorn.

I had a Virtual PC with Windows XP SP 2 and the WinFX Beta 1 RC Runtimes installed, so I started mocking it together using Chris Anderson's AVPad and everything was going well until I started trying storyboards for animation. I'd try to cut and paste the examples from the documentation and gave a strange errors, like "The Clr property 'Storyboards' is not defined on 'ContentControl' or one of its base classes".

Most probably the issue was related to "...Although all framework elements have a Storyboards property, you can only define storyboards on root elements. Only Window and Page objects can be root elements". Eventually I gave in with AvPad and decided that I ought to install Visual C# express and the full SDK.

So I downloaded the Visual C# Express Beta 2 edition (Beta 2 NOT the latest August build), WinFX Avalon/Indigo (sorry WPF, WCF) Beta 1 RC Runtimes, WinFX SDK & Visual Studio Extensions for WinFX Beta 1. I thought all this wouldn't be too difficult to install as I'd been keeping on eye on the CTP Madness.

But it was about four hours later I actually got things working. So here is the correct order, install Visual C# Express, then SDK, then WinFX and finally the project extensions. I did try the Visual C# Express August CTP but that didn't work and stupidly I also thought the SDK would include the WinFX runtimes.

My intention was to write the whole thing using only declarative XAML so I was more limited in the animations that could be used. Also I had a bit of pain finding another way to set the TargetName aside from the resource style. Eventually I decided on using SetterTimeline with DoubleAnimation over Keyframes, mainly because it seemed easiest. Also getting the correct RepeatBehavior and AutoReverse setting on the individual elements and the paralleltimeline took a little trial and error.

Using Visual C# Express, I chose to create a new Avalon application; Tim Sneath details the choices for application types.

It's a bit hacky using the hardcoded timelines & cut'n'paste code but it works as a quick example. Eventually the XAML looked similar to this:

<Application.Resources>
  <Style TargetType="{x:Type Ellipse}" x:Key="PurpleGradient">
   <Setter Property="Fill" Value="RadialGradient #FFFD19FD #33F932F9" />
   <Setter Property="Width" Value="50" />
   <Setter Property="Height" Value="50" />
  </Style>         
</Application.Resources>

<Window x:Class="AvalonApplication4.Window1"
  xmlns="
http://schemas.microsoft.com/winfx/avalon/2005"
  xmlns:x="
http://schemas.microsoft.com/winfx/xaml/2005"
  Text="AvalonApplication4"
  Background="#B2B2B2" Width="460" Height="460">

<Window.Storyboards>
  <ParallelTimeline x:Name="myMainTimeline" RepeatBehavior="Forever">
   <SetterTimeline TargetName="e1" Path="(Ellipse.Opacity)">
    <DoubleAnimation From="1" To="0" Duration="0:0:0.1" BeginTime="0:0:0" AutoReverse="True" />
   </SetterTimeline>
   <SetterTimeline TargetName="e2" Path="(Ellipse.Opacity)">
    <DoubleAnimation From="1" To="0" Duration="0:0:0.1" BeginTime="0:0:0.1" AutoReverse="True" />
   </SetterTimeline>
   ...

 </ParallelTimeline>
</Window.Storyboards>
 
<Canvas>
 
<Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="89" Canvas.Left="306" Name="e1" />
  <Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="145" Canvas.Left="363" Name="e2" />
  <Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="221" Canvas.Left="385" Name="e3" />
  <!-- 3 -->
  <Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="297" Canvas.Left="363" Name="e4" />
  <Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="346" Canvas.Left="306" Name="e5" />
  <Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="382" Canvas.Left="220" Name="e6" />
  <!-- 6 -->
  <Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="346" Canvas.Left="134" Name="e7" />
  <Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="297" Canvas.Left="77" Name="e8" />
  <Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="221" Canvas.Left="55" Name="e9" />
  <!-- 9 -->
  <Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="145" Canvas.Left="77" Name="e10" />
  <Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="89" Canvas.Left="134" Name="e11" />
 
<Ellipse Style="{StaticResource PurpleGradient}" Canvas.Top="64" Canvas.Left="220" Name="e12"/>
  <!-- 12 o'click -->
  
  <Line Stroke="Black" StrokeThickness="2" StrokeStartLineCap="Square" StrokeEndLineCap="Square"
    X1="240" Y1="235" X2="240" Y2="255"/>

 
<Line Stroke="Black" StrokeThickness="2" StrokeStartLineCap="Square" StrokeEndLineCap="Square"
    X1="230" Y1="245" X2="250" Y2="245"/>

  </Canvas>
</Window>

Was it easier than an animated GIF? No
Was it easier than doing it in Flash? No
Was it easier than doing it as Win32 GDI code? Yes
But hopefully with proper IDE support and
Sparkle it will become easier.

You can download the full source code here.

Now I'm all configured for Avalon (WPF) maybe I should have a go at developing some my Solitaire for Windows Vista ideas!

Comments

# re: Optical Illusions, XAML and WinFX

Tuesday, August 23, 2005 5:29 AM by Ian Moulster
This is great work. Producing something like this is going to become a whole lot easier to do once we have full tool support, but it's good to see it can be done now just by hand-coding.

Congratulations on rising to the challenge!

# Challenges in Avalon

Friday, August 26, 2005 1:18 PM by Anonymous
Ian Moulster recently sent out a XAML developer challenge to recreate an optical illusion in XAML. Jonathan...

# good site

Saturday, September 17, 2005 1:48 AM by Daniel
Realy good site!