Analog Clock
-
Wednesday, August 13, 2008 7:56 PM
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.
All Replies
-
Thursday, August 14, 2008 11:14 AM
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 6:41 PM
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 9:49 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 11:00 PM
There is also a complete project about that here -
Friday, August 15, 2008 3:26 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.
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. -
Tuesday, August 19, 2008 7:56 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.

Chris

