zoukankan      html  css  js  c++  java
  • My Clock

    Windows phone 中 自制 小Clock 如图:

    基本思路: 首先在界面绘制表盘,由一个圆和一些刻度 当然还有clock中间的中心点了

    绘制圆和中心点都很简单,主要是刻度的绘制 如图红色为刻度

    我以12点为基准线, 圆心为中心点centerpoint, 顺时针偏离角为a (如1点偏离角为30度)

    则刻度的起始点就是(centerpoint.x+r*sin(a),centerpoint.y-r*cos(a)) ,为了计算刻度的终点的坐标,假设有一个稍微小一点的同心圆,同理计算出一个坐标作为终点坐标,

    如图就得到刻度的起始坐标,然后绘制一条线即可。

    表针的绘制:表针使用小矩形来表示,使用RenderTransform来对矩形进行控制,先绘制一个小矩形让其居中,然后让其向上移动矩形高度的一半就能使矩形像表针的样子了,设置其变换中心点,并设置其倾斜角度,当时间改变的时候通过改变其倾斜角度就能让Clock走起来了

    根据时间改变三个指针的角度:这里定义了updateClock方法实现,很简单就是简单计算下各个指针应该对应的角度,如秒针就是当前second*6即可,然后根据角度设置指针的Rotation角度即可让指针倾斜到指定的角度了。

    简单实现如下:

    首先定义几个变量:

     //ContentPanel中心点
            Point centerPoint;
            //三个表针
            Rectangle secondPointer = new Rectangle();
            Rectangle minutePointer = new Rectangle();
            Rectangle hourPointer = new Rectangle();
            DispatcherTimer timer = new DispatcherTimer();
    

    然后创建表盘:createClockPanel

    View Code
     //创建Clock面板,参数radius为clock直径,color 为表盘的颜色
    private void createClockPanel(double radius,Color strockColor,double strokeThickness)
    {
    double centerRadius = radius * 0.08;
    double contentPanelWidth = ContentPanel.ActualWidth;
    double contentPanelHeight = ContentPanel.ActualHeight;
    //获取ContentPanel中心点
    centerPoint = new Point(contentPanelWidth / 2, contentPanelHeight / 2);


    //定义clock边缘
    Ellipse clockEllipse = new Ellipse();
    clockEllipse.Width
    = radius*2;
    clockEllipse.Height
    = radius*2;
    clockEllipse.HorizontalAlignment
    = HorizontalAlignment.Center;
    clockEllipse.VerticalAlignment
    = VerticalAlignment.Center;
    clockEllipse.Stroke
    = new SolidColorBrush(strockColor);
    clockEllipse.StrokeThickness
    = strokeThickness;

    //定义Clock中心
    Ellipse clockCenter = new Ellipse();
    clockCenter.Width
    = centerRadius;
    clockCenter.Height
    = centerRadius;
    clockCenter.HorizontalAlignment
    = HorizontalAlignment.Center;
    clockCenter.VerticalAlignment
    = VerticalAlignment.Center;
    clockCenter.Fill
    = new SolidColorBrush(Color.FromArgb(255,0,255,0));

    //绘制时间刻度
    ////获取12点处的刻度坐标
    //Point twelvePoint = new Point(centerPoint.X,centerPoint.Y-radius);
    //记录各点坐标
    //为了绘制刻度,假设有一个比现在的边缘小10%的圆,然后找到各个角度对应的刻度 的起始坐标
    Point startpoint=new Point();
    Point endpoint
    = new Point();

    for (int angle = 0; angle <=360; angle += 6)
    {
    //正余弦函数的参数参数 a类型:System.Double 以弧度计量的角度,所以必须先将角度转换成弧度
    //注:弧长等于圆半径长的弧所对的圆心角为1弧度
    double circulrAngle = Math.PI * angle / 180;
    startpoint.X
    = centerPoint.X + radius * Math.Sin(circulrAngle);
    startpoint.Y
    = centerPoint.Y - radius * Math.Cos(circulrAngle);

    Line line1
    = new Line();
    double rate = 0.95;
    //整点高亮显示
    if (angle % 90 == 0)
    {
    line1.StrokeThickness
    = 4;
    rate
    = 0.9;
    }
    else if (angle % 30 == 0 && angle % 90 != 0)
    {
    line1.StrokeThickness
    = 2;
    rate
    = 0.92;
    }
    endpoint.X
    = centerPoint.X + (radius * rate) * Math.Sin(circulrAngle);
    endpoint.Y
    = centerPoint.Y - (radius * rate) * Math.Cos(circulrAngle);

    line1.X1
    = startpoint.X;
    line1.Y1
    = startpoint.Y;
    line1.X2
    = endpoint.X;
    line1.Y2
    = endpoint.Y;

    line1.Stroke
    = new SolidColorBrush(strockColor);
    //绘制刻度
    ContentPanel.Children.Add(line1);
    }
    //将表盘添加到ContentPanel中
    ContentPanel.Children.Add(clockEllipse);
    ContentPanel.Children.Add(clockCenter);
    }

    创建三个表针 :

    View Code
     //创建三个表针  radius 表示表盘半径
    private void createClockPointer(double radius,Color pointerColor)
    {
    //秒针
    secondPointer.Width = 2;
    secondPointer.Height
    = radius;
    secondPointer.Name
    = "secondPointer";
    secondPointer.Fill
    = new SolidColorBrush(pointerColor);

    CompositeTransform secondTransform
    = new CompositeTransform();
    secondTransform.TranslateY
    = -secondPointer.Height / 2.5;
    //这里设置秒针中心点 ,貌似有点不准确----------待解决
    secondTransform.CenterX = 0;
    secondTransform.CenterY
    = secondPointer.Height / 2.5 + secondPointer.Height/2;
    secondTransform.Rotation
    = secondPointer.Width/2;
    secondPointer.RenderTransform
    = secondTransform;
    ContentPanel.Children.Add(secondPointer);

    //分针
    minutePointer.Width = 4;
    minutePointer.Height
    = radius * 0.8;
    minutePointer.Name
    = "minutePointer";
    minutePointer.Fill
    = new SolidColorBrush(pointerColor);

    CompositeTransform minuteTransform
    = new CompositeTransform();
    minuteTransform.TranslateY
    = -minutePointer.Height / 2;
    minuteTransform.CenterX
    = minutePointer.Width/2;
    minuteTransform.CenterY
    = minutePointer.Height;
    minutePointer.RenderTransform
    = minuteTransform;
    ContentPanel.Children.Add(minutePointer);

    //时针
    hourPointer.Width = 6;
    hourPointer.Height
    = radius * 0.7;
    hourPointer.Name
    = "hourPointer";
    hourPointer.Fill
    = new SolidColorBrush(pointerColor);

    CompositeTransform hourTransform
    = new CompositeTransform();
    hourTransform.TranslateY
    = -hourPointer.Height / 2.5;
    hourTransform.CenterX
    = hourPointer.Width/2;
    hourTransform.CenterY
    = hourPointer.Height/2.5+hourPointer.Height/2;
    hourPointer.RenderTransform
    = hourTransform;
    ContentPanel.Children.Add(hourPointer);
    }

      

    根据当前时间计算各个指针角度:

     private void updateClock()
            {
                DateTime dt = DateTime.Now;
                double angle;
                angle=dt.Second*6;
                resetPointer(secondPointer, angle);
                angle = dt.Minute * 6 + angle / 60;
                resetPointer(minutePointer,angle);
                angle = (dt.Hour%12) * 30 + angle /60;
                resetPointer(hourPointer,angle);
            }
    

    resetPointer方法:

     //根据对应的角度重新设置pointer角度
            private void resetPointer(Rectangle rect,double angle)
            {
                CompositeTransform transform = rect.RenderTransform as CompositeTransform;
                transform.Rotation = angle;
            }
    

    当然在构造函数中需要先设置定时器并启动

    timer.Interval = TimeSpan.FromSeconds(1);
    timer.Tick += new EventHandler(timer_Tick);
    timer.Start();
    

      

    tick方法:

     void timer_Tick(object sender, EventArgs e)
            {
                try
                {
                    updateClock();
                }
                catch(Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
    

      

    然后在页面加载的时候调用reflush方法就可以了

    为了当屏幕方向改变时也能正常显示,需要在ContentPanel的 SizeChanged方法中

    执行如下操作:

    timer.Stop();
    reflush();
    timer.Start();
    

    这样就OK了。

    LandScape下显示如下

  • 相关阅读:
    java.lang.NoSuchMethodError
    asm相关内容想下载(包括 jar 包)
    Initialization of bean failed; nested exception is java.lang.NoClassDefFoundError: org/objectweb/asm/Type
    用Navicat连接mysql报错:2003-Can't connect to MySql server on '10.100.0.109'(10039)
    The type java.lang.reflect.AnnotatedElement cannot be resolved. It is indirectly referenced from required .class files
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    交通测速方式
    卡口和电子警察的区别
    Myeclipse连接Mysql数据库时报错:Error while performing database login with the pro driver:unable
    在window上安装mysql
  • 原文地址:https://www.cnblogs.com/yinghuochong/p/2171312.html
Copyright © 2011-2022 走看看