Create a simple clock

Visual Basic tutorials for UWP apps.
3 posts Page 1 of 1
Contributors
User avatar
CodenStuff
Site Admin
Site Admin
Posts: 4389
Joined: Tue Aug 04, 2009 1:47 am

Create a simple clock
CodenStuff
Simple animated clock

This tutorial based on a silverlight tutorial HERE will show you how to create a simple clock for metro and its good for learning basic animation.

Im still learning all this xaml stuff myself so it may be a bit choppy lol

So start a new blank project and head into MainPage.xaml which is pretty empty at this point and just shows your main grid where all our elements/controls/visuals will be placed into:
Code: Select all
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">

    </Grid>
The first thing we want to do is add a grid which will hold our clock elements (this is similar to a panel in winforms). Our clock will be sized at 350 x 350 and placed center on screen so we add out grid into the code like this:
Code: Select all
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid Height="350" Width="350" HorizontalAlignment="Center" VerticalAlignment="Center">
            
        </Grid>
    </Grid>
Now that we have our grid in place we create a clock face inside that grid using an ellipse the same size as the grid and we fill it with the colour white:
Code: Select all
    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid Height="350" Width="350" HorizontalAlignment="Center" VerticalAlignment="Center">
            <Ellipse Fill="White" Height="350" Width="350" Stroke="Black" HorizontalAlignment="Left" VerticalAlignment="Top"/>
        </Grid>
    </Grid>
Image

Ok we have our clock face its now time to add the hands (Hour, Minute and Second) and we start with the hour hand. Controls are rendered in order so the control at the start of the code will be rendered at the bottom and the one at the end of the code will be rendered at the top so to make our clock "realistic" we want the hour hand at the bottom, then the minute hand and the second hand on the top so we start with the hour hand. Each hand needs to be half the size of our grid (175 pixels) and placed roughly in the center of our grid so it ticks round in a circle.

Hour hand code (all code placed below the ellipse)
Code: Select all
            <Rectangle x:Name="Hour" Fill="#FF0352B0" HorizontalAlignment="Left" Height="150" Margin="169,25,0,0" Stroke="Black" VerticalAlignment="Top" Width="12" RenderTransformOrigin="0.5,1">
                <Rectangle.RenderTransform>
                    <RotateTransform x:Name="HourHand" />
                </Rectangle.RenderTransform>
            </Rectangle>
Then the minute hand:
Code: Select all
            <Rectangle x:Name="Minute" Fill="#FF060606" HorizontalAlignment="Left" Height="170" Margin="169,5,0,0" Stroke="Black" VerticalAlignment="Top" Width="12" RenderTransformOrigin="0.5,1">
                <Rectangle.RenderTransform>
                    <RotateTransform x:Name="MinuteHand" />
                </Rectangle.RenderTransform>
            </Rectangle>
And finally the second hand:
Code: Select all
            <Rectangle x:Name="Second" Fill="#FFFB1207" HorizontalAlignment="Left" Height="175" Margin="169,0,0,0" Stroke="Black" VerticalAlignment="Top" Width="12" RenderTransformOrigin="0.5,1">
                <Rectangle.RenderTransform>
                    <RotateTransform x:Name="SecondHand"/>
                </Rectangle.RenderTransform>
            </Rectangle>
Notice all 3 rectangles have different sizes 150, 170 and 175 and that is because each hand on a clock is slightly smaller than the other and because we have changed the size of our hands we need to adjust each hands top margin so the all still appear in the middle of the clock. We also changed the RenderTransformOrigin to the middle-bottom of the rectangle so it rotates from the bottom instead of its center otherwise it would look like a helicopter propeller.

RenderTransformOriginal(X,Y) these are simple values from 0 to 1 and 0 being the top and 1 being the bottom (or left and right) changing any value to 0.5 would place it in the center of the control.

Image

We now have our clock face and hands in place but its going to leave a small gap in the middle as they spin around so lets add another small ellipse in the center to cover that gap up:
Code: Select all
<Ellipse Fill="#FF0352B0" HorizontalAlignment="Center" Height="20" Margin="0" Stroke="Black" VerticalAlignment="Center" Width="20"/>
Image

Our clock visual is now finished and its time to put in some animation and to do that we add a resource list above our mainpage grid we started with earlier:
Code: Select all
    <Page.Resources>

    </Page.Resources>
Within that we add a storyboard which holds the animations we are going to create for our clock so add that and we call it TickTockClock:
Code: Select all
    <Page.Resources>
        <Storyboard x:Name="TickTockClock">
            
        </Storyboard>
    </Page.Resources>
Now inside our storyboard we add our animation code for all 3 hands as follows:
Code: Select all
    <Page.Resources>
        <Storyboard x:Name="TickTockClock">
            <DoubleAnimation x:Name="HourAnimation" 
                Storyboard.TargetProperty="Angle"
                Storyboard.TargetName="HourHand"
                RepeatBehavior="forever"
                Duration="12:0:0"
                To="360" />
            <DoubleAnimation x:Name="MinuteAnimation" 
                Storyboard.TargetProperty="Angle"
                Storyboard.TargetName="MinuteHand"
                RepeatBehavior="forever"
                Duration="1:0:0"
                To="360" />
            <DoubleAnimation x:Name="SecondAnimation" 
                Storyboard.TargetProperty="Angle"
                Storyboard.TargetName="SecondHand"
                RepeatBehavior="forever"
                Duration="0:1:0"
                To="360" />
        </Storyboard>
    </Page.Resources>
Each animation is almost the same we want to adjust the angle of each hand (to make them rotate around the clock) so we set each animations "Storyborad.TergetProperty" to Angle and a complete circle is 360 degrees and we want it to rotate all the way round so we set the "To" property to 360. RepeatBehaviour is how many times we want to run the animation and we set it to forever so that our hands keep going after they complete a full 360 degress..if we didnt set it to forever then the clock would stop ticking. The "Duration" property is also different for each hand and this tells our animation how long it takes to complete so we tell the hour hand to complete a full 360 degree rotation in 12 hours because theres 12 hours on a clock face, the minute hand is told to complete a rotation every hour and the second hand completes its rotation every minute.

Also notice each animations "TagetName" property is different for each hand this tells the animation which control (in this case rectangle) to animate so if you look back at our hand code:
Code: Select all
            <Rectangle x:Name="Hour" Fill="#FF0352B0" HorizontalAlignment="Left" Height="150" Margin="169,25,0,0" Stroke="Black" VerticalAlignment="Top" Width="12" RenderTransformOrigin="0.5,1">
                <Rectangle.RenderTransform>
                    <RotateTransform x:Name="HourHand" />
                </Rectangle.RenderTransform>
            </Rectangle>
You can see we added "<Rectangle.RenderTransform>" code to it which is going to give us access to its transform properties. We are going to rotate this control so we added "<RotateTransform/>" to it and gave it a unique name. Our "TargetName" property in the animation targets the control with the same RotateTransform name inside it.

OK our xaml code is now complete and here it is when put together:
Code: Select all
<Page.Resources>
        <Storyboard x:Name="TickTockClock">
            <DoubleAnimation x:Name="HourAnimation" 
                Storyboard.TargetProperty="Angle"
                Storyboard.TargetName="HourHand"
                RepeatBehavior="forever"
                Duration="12:0:0"
                To="360" />
            <DoubleAnimation x:Name="MinuteAnimation" 
                Storyboard.TargetProperty="Angle"
                Storyboard.TargetName="MinuteHand"
                RepeatBehavior="forever"
                Duration="1:0:0"
                To="360" />
            <DoubleAnimation x:Name="SecondAnimation" 
                Storyboard.TargetProperty="Angle"
                Storyboard.TargetName="SecondHand"
                RepeatBehavior="forever"
                Duration="0:1:0"
                To="360" />
        </Storyboard>
    </Page.Resources>

    <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
        <Grid Height="350" Width="350" HorizontalAlignment="Center" VerticalAlignment="Center">
            <Ellipse Fill="White" Height="350" Width="350" Stroke="Black" HorizontalAlignment="Left" VerticalAlignment="Top"/>
            <Rectangle x:Name="Hour" Fill="#FF0352B0" HorizontalAlignment="Left" Height="150" Margin="169,25,0,0" Stroke="Black" VerticalAlignment="Top" Width="12" RenderTransformOrigin="0.5,1">
                <Rectangle.RenderTransform>
                    <RotateTransform x:Name="HourHand" />
                </Rectangle.RenderTransform>
            </Rectangle>
            <Rectangle x:Name="Minute" Fill="#FF060606" HorizontalAlignment="Left" Height="170" Margin="169,5,0,0" Stroke="Black" VerticalAlignment="Top" Width="12" RenderTransformOrigin="0.5,1">
                <Rectangle.RenderTransform>
                    <RotateTransform x:Name="MinuteHand" />
                </Rectangle.RenderTransform>
            </Rectangle>
            <Rectangle x:Name="Second" Fill="#FFFB1207" HorizontalAlignment="Left" Height="175" Margin="169,0,0,0" Stroke="Black" VerticalAlignment="Top" Width="12" RenderTransformOrigin="0.5,1">
                <Rectangle.RenderTransform>
                    <RotateTransform x:Name="SecondHand"/>
                </Rectangle.RenderTransform>
            </Rectangle>
            <Ellipse Fill="#FF0352B0" HorizontalAlignment="Center" Height="20" Margin="0" Stroke="Black" VerticalAlignment="Center" Width="20"/>
        </Grid>
    </Grid>
Lets now add our code to adjust the clock to the current time. Goto into MainPage code view and add this sub:
Code: Select all
Private Sub SetAndStartClock()

        ' The current date and time.
        Dim currentDate As Date = DateTime.Now

        ' Find the appropriate angle (in degrees) for the hour hand
        ' based on the current time.
        Dim hourangle As Double = (((CType(currentDate.Hour, Single) / 12) * 360) + (currentDate.Minute / 2))

        ' The same as for the minute angle.
        Dim minangle As Double = ((CType(currentDate.Minute, Single) / 60) * 360)

        ' The same for the second angle.
        Dim secangle As Double = ((CType(currentDate.Second, Single) / 60) * 360)

        ' Set the beginning of the animation (From property) to the angle 
        ' corresponging to the current time.
        HourAnimation.From = hourangle

        ' Set the end of the animation (To property)to the angle 
        ' corresponding to the current time PLUS 360 degrees. Thus, the
        ' animation will end after the clock hand moves around the clock 
        ' once. Note: The RepeatBehavior property of the animation is set
        ' to "Forever" so the animation will begin again as soon as it completes.
        HourAnimation.To = (hourangle + 360)

        ' Same as with the hour animation.
        MinuteAnimation.From = minangle
        MinuteAnimation.To = (minangle + 360)

        ' Same as with the hour animation.
        SecondAnimation.From = secangle
        SecondAnimation.To = (secangle + 360)

        ' Start the storyboard.
        TickTockClock.Begin()

    End Sub
Finally go back to our xaml code and in the 350x350 grid we added add "Loaded="SetAndStartClock"" to the end of it like this:
Code: Select all
<Grid Height="350" Width="350" HorizontalAlignment="Center" VerticalAlignment="Center" Loaded="SetAndStartClock">
When our app starts and the grid is loaded it will activate that subroutine and adjust our clock to the current time.

Save/Build/run the app and you should now have a working clock :D

Image

Tick Tock cooll;
Welcome to CodenStuff.com Learn Code, Love Code. Thank you for being a member of the community.
User avatar
Shim
VIP - Donator
VIP - Donator
Posts: 882
Joined: Wed Dec 14, 2011 5:02 am

Re: Create a simple clock
Shim
nice tutorial + nice clock and superbly explained . +rep
Find my programs on Softpedia
User avatar
Dummy1912
VIP - Donator
VIP - Donator
Posts: 1969
Joined: Sat Aug 21, 2010 2:17 pm

Re: Create a simple clock
Dummy1912
:lol: tock tock :p
nice tut cns :D
visit us on:


http://www.softpedia.com/get/System/Lau ... -Run.shtml
Check it out ! http://www.softpedia.com/publisher/I-A- ... 90017.html
Check it out ! http://www.softpedia.com/get/Desktop-En ... lock.shtml
3 posts Page 1 of 1
Return to “Visual Basic”