Home » Featured, Sample Code + Tutorials

Turntable Control for Windows Phone 7/Silverlight

5 November 2010 626 views One Comment

One day I decided that it would be interesting to have a control that used lateral touch displacement mapped to radial movement in Silverlight. I was a bit baffled at how it would be accomplished at first because there is no control in the Windows Phone 7/Silverlight framework by default that does this that I know of. I wanted to use purely XAML but I didn’t find an effective way to do so. NOTE: The code itself is not perfect. There are some erratic rotations depending on what quadrant you touch first and move. If somebody fixes it please email me so I can update it. The real purpose of this code is to show how it could be done theoretically more than fully functionally. If anybody has a more elegant solution (like purely in XAML or using Expression Blend) please post it or email me! …

Click here to download the turntable disc png

XAML Code (turntable.xaml)

<UserControl x:Class="PhoneControls.Turntable"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" Height="293" Width="393">
    <Grid x:Name="LayoutRoot" Background="#FF1F1F1F" Height="296" Width="392">
        <Image x:Name="Background" Source="turntable.jpg" MouseMove="Circle_MouseMove" Margin="0,0,13,0"></Image>
        <Grid Height="293" x:Name="circHolder" HorizontalAlignment="Left" VerticalAlignment="Top" Width="290" Margin="32,0,0,0">
            <Image x:Name="Circle" Width="290" Height="292" Source="disc.png" MouseMove="Circle_MouseMove" 

MouseLeftButtonDown="Circle_MouseLeftButtonDown" MouseLeftButtonUp="Circle_MouseLeftButtonUp" 

Margin="-9,-4,9,5" HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="None">
                <Image.RenderTransform>
                    <RotateTransform x:Name="TurnTableRotation" />
                </Image.RenderTransform>
            </Image>
        </Grid>
        <TextBlock Height="24" HorizontalAlignment="Left" Margin="306,260,0,0" Name="mousePositionText" 

Text="TextBlock" VerticalAlignment="Top" Width="85" Foreground="Red" />
    </Grid>
</UserControl>

C# Code-behind (turntable.xaml.cs)

    public partial class Turntable : UserControl
    {
        Point start, center;
        double distance = 0;
        bool down = false;
        double initAngle = 0;
        public Turntable()
        {
            InitializeComponent();
            this.TurnTableRotation.CenterX =  145;
            this.TurnTableRotation.CenterY = 145;
        }
        private void Circle_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            start = e.GetPosition(this.Circle);
            center = new Point(145, 145);
            down = true;
            initAngle = this.TurnTableRotation.Angle;
        }
        private void Circle_MouseMove(object sender, MouseEventArgs e)
        {
            mousePositionText.Text = e.GetPosition(this.Circle).ToString();
            if (down)
            {
                double a = calculateDistance(e.GetPosition(this.Circle), center);
                double b = calculateDistance(e.GetPosition(this.Circle), start);
                double c = calculateDistance(start, center);
                if (b == 0)
                    b = 1;
                this.TurnTableRotation.Angle = initAngle + calculateAngle(a, b, c);
            }
        }
        private double calculateDistance(Point pt1, Point pt2)
        {
            return Math.Sqrt(Math.Pow(pt2.X - pt1.X, 2) + Math.Pow(pt2.Y - pt1.Y, 2));
        }
        private double calculateAngle(double distA, double distB, double distC)
        {
            return Math.Acos((-distC * distC + distA * distA + distB * distB) / (2 * distA * distB)) * 60;
        }
        private void Circle_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            down = false;
        }
    }

Did you like this? Share it:
1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

One Comment »

  • Cory Smith said:

    This is awesome, thanks for posting!

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.