Neave Strobe using Windows Presentation Foundation

[Update 2006-12-05: Changed the download location of NeaveStrobe.xaml to my new domain which serves the right mime type application/xaml+xml for .xaml files.]

Ever since I saw the Neave Strobe I wanted to create a Windows Presentation Foundation version. The original version uses Flash. The Neave Strobe is an optical illusion. Stare at the middle of the strobing lines for 20 seconds and then look away. You will be amazed at what you see.

Staring at the image below doesn't work of course, because the lines don't move 🙂

If you have the .NET Framework 3.0 installed you can view my animated WPF version: NeaveStrobe.xaml.

It doesn't work when you view this this link directly in Internet Explorer. The reason is that the web server that is hosting my XAML file, does not return the mime type application/xaml+xml for .xaml files. To work around this, download the file and save it to your local disc. Then open it in Internet Explorer.

Alternatively, you can view it in XamlPad (included in the Windows SDK). Or better, use Charles Petzold's XAML Cruncher. This program is click-once deployed to your computer if you click here.

To create the XAML file I tried using Expression Interactive Designer and "Cider". They didn't really help, so I ended up hand-coding most of it. You can see the code below:

 

<?xml version="1.0" encoding="utf-8" ?>
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Name="DocumentRoot"
    WindowTitle="Neave Strobe" Width="400" Height="400">
  <Page.Resources>
    <Style TargetType="{x:Type Line}" x:Key="LineStyle">
      <Setter Property="Stroke" Value="Black"/>
      <Setter Property="StrokeThickness" Value="18"/>
    </Style>

    <Style TargetType="{x:Type Line}" x:Key="LineStyle2">
      <Setter Property="Stroke" Value="Black"/>
      <Setter Property="StrokeThickness" Value="18"/>
    </Style>

    <Style TargetType="{x:Type Canvas}" x:Key="BlockStyle">
      <Setter Property="Width" Value="200"/>
      <Setter Property="Height" Value="200"/>
    </Style>

    <Style TargetType="{x:Type Grid}" x:Key="GridSize">
      <Setter Property="Width" Value="400"/>
      <Setter Property="Height" Value="400"/>
    </Style>

    <Grid x:Key="LineGrid" RenderTransformOrigin="0.5,0.5">
      <Grid.RenderTransform>
        <TransformGroup>
          <TranslateTransform X="0" Y="0" x:Name="LineTransform" />
        </TransformGroup>
      </Grid.RenderTransform>
      <Grid.Children>
        <Line X1="-25" Y1="-25" X2="100" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="25" Y1="-25" X2="150" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-75" Y1="-25" X2="50" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-125" Y1="-25" X2="0" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-175" Y1="-25" X2="-50" Y2="100"
          Style="{StaticResource LineStyle}" />
      </Grid.Children>
    </Grid>

    <Grid x:Key="LineGrid2" RenderTransformOrigin="0.5,0.5">
      <Grid.RenderTransform>
        <TransformGroup>
          <TranslateTransform X="0" Y="0" x:Name="LineTransform2" />
        </TransformGroup>
      </Grid.RenderTransform>
      <Grid.Children>
        <Line X1="-25" Y1="-25" X2="100" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="25" Y1="-25" X2="150" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-75" Y1="-25" X2="50" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-125" Y1="-25" X2="0" Y2="100"
          Style="{StaticResource LineStyle}" />
        <Line X1="-175" Y1="-25" X2="-50" Y2="100"
          Style="{StaticResource LineStyle}" />
      </Grid.Children>
    </Grid>

    <VisualBrush x:Key="DiagonalLines" x:Name="DiagonalLines" 
      Viewbox="0,0,50,50" 
      ViewboxUnits="Absolute" 
      Viewport="0,0,0.1,0.1"
      ViewportUnits="RelativeToBoundingBox" 
      TileMode="Tile" 
      AlignmentX="Center"
      AlignmentY="Center"
      Visual="{StaticResource LineGrid}" />

    <VisualBrush x:Key="DiagonalLines2" x:Name="DiagonalLines2" 
      Viewbox="0,0,50,50" 
      ViewboxUnits="Absolute" 
      Viewport="0,0,0.1,0.1"
      ViewportUnits="RelativeToBoundingBox" 
      TileMode="Tile" 
      AlignmentX="Center"
      AlignmentY="Center"
      Visual="{StaticResource LineGrid2}" />

    <Storyboard x:Key="LineStoryboard" >
      <DoubleAnimation Storyboard.TargetProperty="X" BeginTime="00:00:00" 
         Storyboard.TargetName="LineTransform" 
      From="0" To="100" Duration="0:0:1" RepeatBehavior="Forever" />
      <DoubleAnimation Storyboard.TargetProperty="X" BeginTime="00:00:00" 
         Storyboard.TargetName="LineTransform2" 
      From="100" To="0" Duration="0:0:1" RepeatBehavior="Forever" />
    </Storyboard>

    <Grid x:Key="QuadLineGrid" VerticalAlignment="Top" Style="{StaticResource GridSize}">

      <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
      </Grid.RowDefinitions>

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="1" Grid.Column="1" RenderTransformOrigin="0.5,0.5" 
          Canvas.Background="{StaticResource DiagonalLines}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="90"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>

      <Canvas Style="{StaticResource BlockStyle}"
        Grid.Row="0" Grid.Column="1" 
        Grid.ColumnSpan="1" Grid.RowSpan="1"
        Canvas.Background="{StaticResource DiagonalLines}" />

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="1" Grid.Column="0" 
          Grid.ColumnSpan="1" Grid.RowSpan="1" RenderTransformOrigin="0.5,0.5"
          Canvas.Background="{StaticResource DiagonalLines}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="180"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="0" Grid.Column="0" 
          Grid.ColumnSpan="1" Grid.RowSpan="1" RenderTransformOrigin="0.5,0.5" 
          Canvas.Background="{StaticResource DiagonalLines}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="270"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>

    </Grid>

    <Grid x:Key="QuadLineGrid2" VerticalAlignment="Top" Style="{StaticResource GridSize}">
      <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>
      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
      </Grid.RowDefinitions>

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="1" Grid.Column="1" RenderTransformOrigin="0.5,0.5" 
          Canvas.Background="{StaticResource DiagonalLines2}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="90"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="0" Grid.Column="1" 
          Grid.ColumnSpan="1" Grid.RowSpan="1"
          Canvas.Background="{StaticResource DiagonalLines2}">
      </Canvas>

      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="1" Grid.Column="0" 
          Grid.ColumnSpan="1" Grid.RowSpan="1" RenderTransformOrigin="0.5,0.5"
          Canvas.Background="{StaticResource DiagonalLines2}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="180"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>


      <Canvas Style="{StaticResource BlockStyle}"
          Grid.Row="0" Grid.Column="0" 
          Grid.ColumnSpan="1" Grid.RowSpan="1" RenderTransformOrigin="0.5,0.5" 
          Canvas.Background="{StaticResource DiagonalLines2}">
        <Canvas.RenderTransform>
          <TransformGroup>
            <RotateTransform Angle="270"/>
          </TransformGroup>
        </Canvas.RenderTransform>
      </Canvas>
    </Grid>

    <VisualBrush x:Key="QuadLineBrush" x:Name="QuadLineBrush"      
    Visual="{StaticResource QuadLineGrid2}" Stretch="None" />

  </Page.Resources>

  <Page.Triggers>
    <EventTrigger RoutedEvent="Canvas.Loaded">
      <BeginStoryboard Storyboard="{StaticResource LineStoryboard}">
      </BeginStoryboard>
    </EventTrigger>
  </Page.Triggers>

  <Canvas>
    <StaticResource ResourceKey="QuadLineGrid"/>
    <Ellipse Width="200" Height="200" Margin="100,100">
      <Ellipse.Fill>
        <SolidColorBrush Color="White"/>
      </Ellipse.Fill>
    </Ellipse>
    <Ellipse Width="200" Height="200" Fill="{StaticResource QuadLineBrush}" Margin="100,100" />
  </Canvas>

</Page>

One thought on “Neave Strobe using Windows Presentation Foundation

Leave a Reply

Your email address will not be published. Required fields are marked *