Clock animation : Clock « 2D « C# / CSharp Tutorial

Home
C# / CSharp Tutorial
1.Language Basics
2.Data Type
3.Operator
4.Statement
5.String
6.struct
7.Class
8.Operator Overload
9.delegate
10.Attribute
11.Data Structure
12.Assembly
13.Date Time
14.Development
15.File Directory Stream
16.Preprocessing Directives
17.Regular Expression
18.Generic
19.Reflection
20.Thread
21.I18N Internationalization
22.LINQ
23.GUI Windows Forms
24.Windows Presentation Foundation
25.Windows Communication Foundation
26.Workflow
27.2D
28.Design Patterns
29.Windows
30.XML
31.XML LINQ
32.ADO.Net
33.Network
34.Directory Services
35.Security
36.unsafe
C# / C Sharp
C# / C Sharp by API
C# / CSharp Open Source
C# / CSharp Tutorial » 2D » Clock 
27.34.2.Clock animation
Clock animation
/* Quote from 

Programming .NET Windows Applications

By Jesse Liberty, Dan Hurwitz
First Edition October 2003 
Pages: 1246 (More details)
*/


using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Timers;
using System.Windows.Forms;


namespace Clock3CS
{
  // Rename the class
  public class ClockFace : System.Windows.Forms.Form
  {
    // Required designer variable.
    private System.ComponentModel.Container components = null;
  
    private int FaceRadius = 450;    // size of the clock face
    private bool b24Hours = false;    // 24 hour clock face?
    private System.Windows.Forms.Button btnClockFormat;    
    private DateTime currentTime;    // used in more than one method

    // new
    private int xCenter;        // center of the clock
    private int yCenter;
    private static int DateRadius = 600// outer circumference for date
    private static int Offset = 0;    // for moving the text 
    Font font = new Font("Arial"40);  // use the same font throughout
    private StringDraw sdToday;      // the text to animate

    public ClockFace()
    {
      // Required for Windows Form Designer support
      InitializeComponent();

      // use the user's choice of colors
      BackColor = SystemColors.Window;
      ForeColor = SystemColors.WindowText;

    
      // *** begin new
      string today = System.DateTime.Now.ToLongDateString();
      today = " " + today.Replace(",","");
      
      // create a new stringdraw object with today's date
      sdToday = new StringDraw(today,this);
      currentTime = DateTime.Now;


      // set the current center based on the
      // client area
      xCenter = Width / 2;
      yCenter = Height / 2;


      // *** end new


      // update the clock by timer
      System.Timers.Timer timer = new System.Timers.Timer();
      timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimer);
      timer.Interval = 20;  // shorter interval - more movement
      timer.Enabled = true;


    }

    protected override void OnPaint PaintEventArgs e )
    {
      base.OnPaint(e);
      Graphics g = e.Graphics;
      SetScale(g);
      DrawFace(g);
      DrawTime(g,true);  // force an update
    }

    // every time the timer event fires, update the clock
    public void OnTimer(Object source, ElapsedEventArgs e)
    {
      Graphics g = this.CreateGraphics();

      SetScale(g);
      DrawFace(g);
      DrawTime(g,false);
      DrawDate(g);
      g.Dispose();    
      
    }


    #region Windows Form Designer generated code
    protected override void Disposebool disposing )
    {
      ifdisposing )
      {
        if (components != null
        {
          components.Dispose();
        }
      }
      base.Disposedisposing );
    }

    
    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
      this.btnClockFormat = new System.Windows.Forms.Button();
      this.SuspendLayout();
      // 
      // btnClockFormat
      // 
      this.btnClockFormat.Location = new System.Drawing.Point(88);
      this.btnClockFormat.Name = "btnClockFormat";
      this.btnClockFormat.TabIndex = 1;
      this.btnClockFormat.Text = "24 Hours";
      this.btnClockFormat.Click += new System.EventHandler(this.btnClockFormat_Click);
      // 
      // ClockFace
      // 
      this.AutoScaleBaseSize = new System.Drawing.Size(513);
      this.ClientSize = new System.Drawing.Size(292266);
      this.Controls.AddRange(new System.Windows.Forms.Control[] {
                                      this.btnClockFormat});
      this.Name = "ClockFace";
      this.Text = "Clock3CS";
      this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ClockFace_MouseDown);
      this.ResumeLayout(false);

    }
    #endregion

    [STAThread]
    static void Main() 
    {
      Application.Run(new ClockFace());
    }

    private void SetScale(Graphics g)
    {
      // if the form is too small, do nothing
      if Width == || Height == )
        return;

      // set the origin at the center
      g.TranslateTransform(xCenter, yCenter);  // use the members vars

      // set inches to the minimum of the width 
      // or height dividedby the dots per inch  
      float inches = Math.Min(Width / g.DpiX, Height / g.DpiX);

      // set the scale to a grid of 2000 by 2000 units
      g.ScaleTransform(
        inches * g.DpiX / 2000, inches * g.DpiY / 2000);
    }

    private void DrawFace(Graphics g)
    {
      // numbers are in forecolor except flash number in green
      // as the seconds go by.
      Brush brush = new SolidBrush(ForeColor);
      float x, y;

      // new code
      int numHours = b24Hours ? 24 12;
      int deg = 360 / numHours;
      
      // for each of the hours on the clock face
      for (int i = 1; i <= numHours; i++)
      {
        // i = hour  30 degrees = offset per hour  
        // +90 to make 12 straight up
        x = GetCos(i*deg + 90* FaceRadius;
        y = GetSin(i*deg + 90* FaceRadius;

        StringFormat format = new StringFormat();
        format.Alignment = StringAlignment.Center;
        format.LineAlignment = StringAlignment.Center;

        g.DrawString(
          i.ToString(), font, brush, -x, -y,format);
      
      }  // end for loop
    }    // end drawFace


    private void DrawTime(Graphics g, bool forceDraw)
    {

      //  length of the hands
      float hourLength = FaceRadius * 0.5f;
      float minuteLength = FaceRadius * 0.7f;
      float secondLength = FaceRadius * 0.9f;

      // set to back color to erase old hands first
      Pen hourPen = new Pen(BackColor);
      Pen minutePen = new Pen(BackColor);
      Pen secondPen = new Pen(BackColor);

      // set the arrow heads
      hourPen.EndCap = LineCap.ArrowAnchor;
      minutePen.EndCap = LineCap.ArrowAnchor;

      // hour hand is thicker
      hourPen.Width = 30;
      minutePen.Width = 20;

      // second hand 
      Brush secondBrush = new SolidBrush(BackColor);
      const int EllipseSize = 50;

      GraphicsState state;  // to to protect and to serve


      // 1 - delete the old time

      // delete the old second hand
      // figure out how far around to rotate to draw the second hand
      // save the current state, rotate, draw and then restore the state
      float rotation = GetSecondRotation();
      state = g.Save();
      g.RotateTransform(rotation);
      g.FillEllipse(
        secondBrush,
        -(EllipseSize/2),
        -secondLength,
        EllipseSize,
        EllipseSize);
      g.Restore(state);

      DateTime newTime = DateTime.Now;
      bool newMin = false;  // has the minute changed?

      // if the minute has changed, set the flag
      if newTime.Minute != currentTime.Minute )
        newMin = true;


      // if the minute has changed or you must draw anyway then you 
      // must first delete the old minute and hour hand
      if newMin  || forceDraw )
      {

        // figure out how far around to rotate to draw the minute hand
        // save the current state, rotate, draw and then restore the state
        rotation = GetMinuteRotation();
        state = g.Save();
        g.RotateTransform(rotation);
        g.DrawLine(minutePen,0,0,0,-minuteLength);
        g.Restore(state);

        // figure out how far around to rotate to draw the hour hand
        // save the current state, rotate, draw and then restore the state
        rotation = GetHourRotation();
        state = g.Save();
        g.RotateTransform(rotation);
        g.DrawLine(hourPen,0,0,0,-hourLength);
        g.Restore(state);
      }

      // step 2 - draw the new time
      currentTime = newTime;

      hourPen.Color = Color.Red;
      minutePen.Color = Color.Blue;
      secondPen.Color = Color.Green;
      secondBrush = new SolidBrush(Color.Green);

      // draw the new second hand
      // figure out how far around to rotate to draw the second hand
      // save the current state, rotate, draw and then restore the state
      state = g.Save();
      rotation = GetSecondRotation();
      g.RotateTransform(rotation);
      g.FillEllipse(
        secondBrush,
        -(EllipseSize/2),
        -secondLength,
        EllipseSize,
        EllipseSize);
      g.Restore(state);

      // if the minute has changed or you must draw anyway then you 
      // must draw the new minute and hour hand
      if newMin || forceDraw )
      {

        // figure out how far around to rotate to draw the minute hand
        // save the current state, rotate, draw and then restore the state
        state = g.Save();
        rotation = GetMinuteRotation();
        g.RotateTransform(rotation);
        g.DrawLine(minutePen,0,0,0,-minuteLength);
        g.Restore(state);

        // figure out how far around to rotate to draw the hour hand
        // save the current state, rotate, draw and then restore the state
        state = g.Save();
        rotation = GetHourRotation();
        g.RotateTransform(rotation);
        g.DrawLine(hourPen,0,0,0,-hourLength);
        g.Restore(state);
      }
    }

    // determine the rotation to draw the hour hand
    private float GetHourRotation()
    {
      // degrees depend on 24 vs. 12 hour clock
      float deg = b24Hours ? 15 30;
      float numHours = b24Hours ? 24 12;
      return360f * currentTime.Hour / numHours +
        deg * currentTime.Minute / 60f);
    }

    private float GetMinuteRotation()
    {
      return360f * currentTime.Minute / 60f )
    }

    private float GetSecondRotation()
    {
      return(360f * currentTime.Second / 60f);
    }

    private static float GetSin(float degAngle)
    {
      return (floatMath.Sin(Math.PI * degAngle / 180f);
    }

    private static float GetCos(float degAngle)
    {
      return (floatMath.Cos(Math.PI * degAngle / 180f);
    }

    private void btnClockFormat_Click(object sender, System.EventArgs e)
    {
      btnClockFormat.Text = b24Hours ? "24 Hour" "12 Hour";
      b24Hours = ! b24Hours;
      this.Invalidate();
    }

    private void DrawDate(Graphics g)
    {
      Brush brush = new SolidBrush(ForeColor);
      sdToday.DrawString(g,brush);
    }

    private void ClockFace_MouseDown(
      object sender, System.Windows.Forms.MouseEventArgs e)
    {
      xCenter = e.X;
      yCenter = e.Y;
      this.Invalidate();
    
    }


    // each letter in the outer string knows how to draw itself
    private class LtrDraw
    {
      char myChar;    // the actual letter i draw
      float x;      // current x coordinate
      float y;      // current y coordinate
      float oldx;      // old x coordinate (to delete)
      float oldy;      // old y coordinate (to delete)
      

      // constructor
      public LtrDraw(char c)
      {
        myChar = c;
      }

      // property for X coordinate
      public float X
      {
        get return x; }
        set oldx = x; x = value; }
      }

      // property for Y coordinate
      public float Y
      {
        get return y; }
        set oldy = y; y = value; }
      }

      // get total width of the string
      public float GetWidth(Graphics g, Font font)
      {
        SizeF stringSize = g.MeasureString(myChar.ToString(),font);
        return stringSize.Width;
      }

      // get total height of the string
      public float GetHeight(Graphics g, Font font)
      {
        SizeF stringSize = g.MeasureString(myChar.ToString(),font);
        return stringSize.Height;
      }


      // get the font from the control and draw the current character
      // First delete the old and then draw the new
      public void DrawString(Graphics g, Brush brush, ClockFace cf)
      {
        Font font = cf.font;
        Brush blankBrush = new SolidBrush(cf.BackColor);
        g.DrawString(myChar.ToString(),font,blankBrush,oldx,oldy);
        g.DrawString(myChar.ToString(),font,brush,x,y);
      }

    }

    // holds an array of LtrDraw objects
    // and knows how to tell them to draw
    private class StringDraw
    {
      ArrayList theString = new ArrayList();
      LtrDraw l;
      ClockFace theControl;

      // constructor takes a string, populates the array
      // and stashes away the calling control (ClockFace)
      public StringDraw(string s, ClockFace theControl)
      {
        this.theControl = theControl;
        foreach (char c in s)
        {
          l = new LtrDraw(c);
          theString.Add(l);
        }
      }

      // divide the circle by the number of letters
      // and draw each letter in position
      public void DrawString(Graphics g, Brush brush)
      {
        int angle = 360 / theString.Count;
        int counter = 0;

        foreach (LtrDraw theLtr in theString)
        {
          // 1. To find the X coordinate, take the Cosine of the angle
          // and multiply by the radius.
          // 2. To compute the angle, start with the base angle 
          // (360 divided by the number of letters)
          // and multiply by letter position.
          // Thus if each letter is 10 degrees, and this is the third
          // letter, you get 30 degrees. Add 90 to start at 12 O'clock.
          // Each time through, subtract the clockFace offset to move 
          // the entire string around the clock on each timer call
          float newX = GetCos(angle  * counter + 90 - ClockFace.Offset* ClockFace.DateRadius ;
          float newY = GetSin(angle * counter + 90 - ClockFace.Offset* ClockFace.DateRadius ;
          theLtr.X = 
            newX - (theLtr.GetWidth(g,theControl.font2);
          theLtr.Y = 
            newY - (theLtr.GetHeight(g,theControl.font2);
          counter++;
          theLtr.DrawString(g,brush,theControl);
        }
        ClockFace.Offset += 1;  // rotate the entire string
      }
    }

  }  // end class
}    // end namespace
27.34.Clock
27.34.1.12/24 hour clock
27.34.2.Clock animationClock animation
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.