Flash to Silverlight

You do Flash and now you want to add Silverlight to your skillset?
You've come to the right place.

A Fun Interactive Example

This is page 3 of Color, Scale and Rotation tutorial in the Getting Started series. As an introduction to Silverlight, this tutorial walks through dynamically modifying the color, scale and rotation of objects.

Get Microsoft Silverlight

Using the same concepts described in the previous tutorials and little math magic, I’ve updated the sample to be much more interesting. I’ll explain below how we went from static blocks to spinning interactive blocks below.

Upgrading the Block

Minor changes were made to the composition of the block control. The original Tile Rectangle went from a square shape to a leaner 30x10 rectangle shape. An Ellipse was also added to appear as a pivot point for the Rectangle. The dotted stroke was accomplished by changing the StrokeDashArray (available in the Appearance pane under the Advanced properties) from the default “1 0” to “1 2”.

The real change is found in the code-behind. The CompositionTarget.Rendering event is handled easing the rectangle towards the new target angle.

public double targetAngle = 0;

public block()
{
   InitializeComponent();


   CompositionTarget.Rendering += compositionTarget_Rendering;
}

private void compositionTarget_Rendering(object sender, System.EventArgs e)
{
   transform.Rotation += (targetAngle - transform.Rotation) * 0.08;
}

Spinning the Blocks

The majority of the work is handled in the MainPage UserControl. The block controls are still added on the Loaded event, but this time they are positioned in multiple rows.

for(int x = 0; x < 15; x++){
   for(int y = 0; y < 10; y++){
      block b = new block();
      Canvas.SetLeft(b, 115+x*25);
      Canvas.SetTop(b, 50+y*25);
      b.Tile.Fill = new SolidColorBrush(Color.FromArgb(0xCC, (byte)(100 + x * 10),
                                                              0, (byte)(100 + y * 15)));
      LayoutRoot.Children.Add(b);
   }
}

In order to have the position of the mouse available at any time, an event handler is added to the MouseMove event of LayoutRoot and a variable is used to store the mouse coordinates.

Point mouse;

private void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
{
   mouse = e.GetPosition(this);
}

With the block controls and the mouse coordinates captured, the final step is to animate the scale and rotation of the controls. This is accomplished by handling the CompositionTarget.Rendering event of the MainPage control, following the same pattern as the block code above.

When the event fires, a loop iterates through the blocks and resets their scale and angle based on their position compared to the mouse position.

private void compositionTarget_Rendering(object sender, EventArgs e)
{
   foreach(block b in LayoutRoot.Children){
      double x = Canvas.GetLeft(b) - mouse.X;
      double y = Canvas.GetTop(b) - mouse.Y;
      double distance = Math.Sqrt(x * x + y * y);
      double rad = Math.Atan2(y, x);
      double angle = rad * (180/Math.PI);
      b.transform.ScaleX = b.transform.ScaleY = 0.6 + distance / 300.0;
      if(distance < 200){
         b.targetAngle = angle-180;
      }
      else{
         b.targetAngle = 0;
      }
   }
}

Pages 1, 2, 3

 

But wait, there's more! For resources, updates and a summary read the Conclusion to the series.

blog comments powered by Disqus