locked
Analog Clock

    Question

  • Hello, I'm making another program with a real looking clock.

    I have an image that i want to use as the border, its 100x100px.

    Can anybody help me make an Hour, Minute and Second hand please. So they move with the correct

     time.

    Please.

    Wednesday, August 13, 2008 7:56 PM

Answers

  • Cool code Derek!

     

    I took your code and changed it a little to make an analog clock based on the time, rather than just incrementing the angle.  It takes the seconds and calculates the angle to draw for seconds, also for hours, and minutes. 

     

    Since the calculations result in fractions of seconds, minutes, and hours, the clock closely resemble a true sweeping analog clock. 

     

    I set the timer interval to 100ms.

     

     

    '(Copied from Reflector, since I originally wrote it in C#)

    Private Sub timer_Tick(ByVal sender As Object, ByVal e As EventArgs)
        Dim hours As Double
        If (DateTime.Now.Hour > 12) Then
            hours = (DateTime.Now.Hour - 12)
        Else
            hours = DateTime.Now.Hour
        End If
        Dim minutes As Double = DateTime.Now.Minute
        Dim seconds As Double = DateTime.Now.Second
        Dim mseconds As Double = DateTime.Now.Millisecond
        Me.secondsAngle.Angle = ((seconds + (mseconds / 1000)) * 6)
        Me.minutesAngle.Angle = (((minutes + (seconds / 60)) + (mseconds / 60000)) * 6)
        Me.hoursAngle.Angle = ((((hours + (minutes / 60)) + (seconds / 3600)) + (mseconds / 3600000)) * 30)
    End Sub
    

     

     

    Cheers,

     

    Chris

    Thursday, August 14, 2008 9:49 PM
  • There is also a complete project about that here

     

    Thursday, August 14, 2008 11:00 PM
  • Chris,

     

    Thank you for doing that and posting the code. You took the next logical step. Looking at it now it acts like a clock but it doesn't look like a clock so I re-updated it and added a clock face. Here is the final project.... there is C# and VB version. The good thing is the clock face is just a bitmap so it can be replaced with any other face quite easily.

     

    AnalogClock.zip

     

    Need to honest and say that I could never of created a clock like this using GDI+, or at least it would have taken a week at least. Haven't been looking at WPF for long but I'm hooked, it's wonderful.
    Friday, August 15, 2008 3:26 PM

All replies

  • Hi,

     

    This is just for an example.... to prove something rather to give you a complete working piece of code.

     

    I think that you'd be better off working with WPF here.... it has many classes that will help you create a clock. Here is a very short example that shows you can create a kind of clock very easily even, in this case, without writing any code.

     

    Create a new WPF project and in the XAML view of the Window that first appears paste in the XAML below are run, it's not a clock but it shows a 'clockish' type thing. All without code, I think it would be easier for you to use WPF to create your clock.

     

     

    <Window x:Class="AnalogClock.Window1"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Window1" Height="300" Width="300">

     

        <Window.Triggers>

            <EventTrigger RoutedEvent="Window.Loaded">

                <EventTrigger.Actions>

                    <BeginStoryboard>

                        <Storyboard SpeedRatio="0.06" RepeatBehavior="Forever">

                            <DoubleAnimation Storyboard.TargetName="secondsAngle"

                                             Storyboard.TargetProperty="Angle"

                                             From="0" To="360"/>

                        </Storyboard>

                    </BeginStoryboard>

                </EventTrigger.Actions>

            </EventTrigger>

        </Window.Triggers>

     

        <Canvas>

            <Path Fill="LightBlue">

                <Path.Data>

                    <EllipseGeometry Center="100, 100" RadiusX="100" RadiusY="100"/>

                </Path.Data>

            </Path>

            <Path Stroke="Black" StrokeThickness="2">

                <Path.Data>

                    <LineGeometry StartPoint="100,100" EndPoint="100,0">

                        <LineGeometry.Transform>

                            <RotateTransform x:Name="secondsAngle"

        Angle="0" CenterX="100" CenterY="100"/>

                        </LineGeometry.Transform>

                    </LineGeometry>

                </Path.Data>

            </Path>

     

        </Canvas>

    </Window>

     

     

    Thursday, August 14, 2008 11:14 AM
  • Hi again,

     

    I took the example I created earlier and turned it into a proper analogue clock (minus the hours hand)... It is VERY easy to do in WPF. Actually the example above may not have worked, there seems to be a little difference with C# and VB. The example above was created in C# project.. the following was VB and so should work ok...

     

    Create a new WPF project and as before copy the XAML below into the XAML of the default Window1.

     

    <Window x:Class="Window1"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        Title="Window1" Height="300" Width="300">

     

        <Canvas x:Name="Clock">

           

            <Path x:Name="cirFace" Fill="LightBlue">

                <Path.Data>

                    <EllipseGeometry Center="100, 100" RadiusX="100" RadiusY="100"/>

                </Path.Data>

            </Path>

     

            <Path Stroke="Black" StrokeThickness="2">

                <Path.Data>

                    <LineGeometry StartPoint="100,100" EndPoint="100,0">

                        <LineGeometry.Transform>

                            <RotateTransform x:Name="secondsAngle"

    Angle="0" CenterX="100" CenterY="100"/>

                        </LineGeometry.Transform>

                    </LineGeometry>

                </Path.Data>

            </Path>

     

            <Path Stroke="Red" StrokeThickness="2">

                <Path.Data>

                    <LineGeometry StartPoint="100,100" EndPoint="100,0">

                        <LineGeometry.Transform>

                            <RotateTransform x:Name="minutesAngle"

    Angle="0" CenterX="100" CenterY="100"/>

                        </LineGeometry.Transform>

                    </LineGeometry>

                </Path.Data>

            </Path>

     

        </Canvas>

    </Window>

     

    This is a clock with minute and seconds hand.... basically in code you need to set a timer to tick every second and update each hand depending on how many ticks there were... here is the code... paste this in to the code file of the Window (right click window, view code)

     

     

    Imports System.Windows.Threading

     

    Class Window1

     

        Dim WithEvents timer As New DispatcherTimer()

     

        Public Sub New()

            timer.Interval = New TimeSpan(0, 0, 1)

            timer.IsEnabled = True

        End Sub

     

        Private Sub timer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles timer.Tick

            'every second move seconds hand around 6 degrees

            Me.secondsAngle.Angle += 6

            'if full circle

            If (Me.secondsAngle.Angle = 360) Then

                'reset angle

                Me.secondsAngle.Angle = 0

     

                'increment minute hand

                Me.minutesAngle.Angle += 6

                If (Me.minutesAngle.Angle = 360) Then

                    Me.minutesAngle.Angle = 0

                End If

     

                'also do something in here for hours hand, after 15 minutes

                '  should have moved move 7.5 degrees

                'also do something in here for hours hand, after 30 minutes

                '  should have moved move 15 degrees

     

            End If

        End Sub

     

    End Class

     

     

    There you have an analogue clock... .

     

     

     

     

     

     

    Thursday, August 14, 2008 6:41 PM
  • Cool code Derek!

     

    I took your code and changed it a little to make an analog clock based on the time, rather than just incrementing the angle.  It takes the seconds and calculates the angle to draw for seconds, also for hours, and minutes. 

     

    Since the calculations result in fractions of seconds, minutes, and hours, the clock closely resemble a true sweeping analog clock. 

     

    I set the timer interval to 100ms.

     

     

    '(Copied from Reflector, since I originally wrote it in C#)

    Private Sub timer_Tick(ByVal sender As Object, ByVal e As EventArgs)
        Dim hours As Double
        If (DateTime.Now.Hour > 12) Then
            hours = (DateTime.Now.Hour - 12)
        Else
            hours = DateTime.Now.Hour
        End If
        Dim minutes As Double = DateTime.Now.Minute
        Dim seconds As Double = DateTime.Now.Second
        Dim mseconds As Double = DateTime.Now.Millisecond
        Me.secondsAngle.Angle = ((seconds + (mseconds / 1000)) * 6)
        Me.minutesAngle.Angle = (((minutes + (seconds / 60)) + (mseconds / 60000)) * 6)
        Me.hoursAngle.Angle = ((((hours + (minutes / 60)) + (seconds / 3600)) + (mseconds / 3600000)) * 30)
    End Sub
    

     

     

    Cheers,

     

    Chris

    Thursday, August 14, 2008 9:49 PM
  • There is also a complete project about that here

     

    Thursday, August 14, 2008 11:00 PM
  • Chris,

     

    Thank you for doing that and posting the code. You took the next logical step. Looking at it now it acts like a clock but it doesn't look like a clock so I re-updated it and added a clock face. Here is the final project.... there is C# and VB version. The good thing is the clock face is just a bitmap so it can be replaced with any other face quite easily.

     

    AnalogClock.zip

     

    Need to honest and say that I could never of created a clock like this using GDI+, or at least it would have taken a week at least. Haven't been looking at WPF for long but I'm hooked, it's wonderful.
    Friday, August 15, 2008 3:26 PM
  •  Derek Smyth wrote:
    Need to honest and say that I could never of created a clock like this using GDI+, or at least it would have taken a week at least. Haven't been looking at WPF for long but I'm hooked, it's wonderful.

     

    I'm in the same boat.  I've just started to scratch the surface of WPF but already I can see that WPF can make things that were impossible or extremely difficult in GDI+ fairly simple!

     

    I wish I had more time to work with it.  At my job, we haven't moved to VS2008 yet. Sad

     

    Chris

    Tuesday, August 19, 2008 7:56 PM