flex两种方式画出一个动态时钟
2015-09-07 11:33
246 查看
flex在画图方面有着得天独厚的条件.它的前身是flash,让画图和动画变得更加容易.打败了java的applet.另外就算在windows编程
这一块.flex也要比java的swing更容易编写.网上看到有人写了个java的时钟,我觉得写的太艰难,于是用flex的两种方式简单实现了一下:
======================================================================================================================
我觉得第一种方式代码写分离性不如第二种高.第一种是要进行整体的考虑,每次都要对每个指针进行擦除和绘制.而第二种布局好了固定不变的
图形安排后.剩下的任务就是编写指针的运动逻辑.这样便于代码的阅读和维护.
笛卡尔坐标系中的顺时针,在PC坐标系看来是顺时针的,反之亦然.
这一块.flex也要比java的swing更容易编写.网上看到有人写了个java的时钟,我觉得写的太艰难,于是用flex的两种方式简单实现了一下:
方式一
采用的是画布的方式实现,利用画布中的graphics调用基础的画图API.<?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="init(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; private var g:Graphics; private var middlePointX:Number = 200;//中心点位置 private var middlePointY:Number = 200; private var hourCursorLength:Number = 120;//各表针长度 private var minuteCursorLength:Number = 160; private var secCursorLength:Number = 180; private var hangle:Number = 0;//各表针相对于0点的角度 private var mangle:Number = 0; private var sangle:Number = 0; private var nowDate:Date;//当前时间 [Bindable] private var hour:Number;//当前时,分,秒 [Bindable] private var min:Number; [Bindable] private var sec:Number; private var R:Number = 200;//表盘半径 protected function init(event:FlexEvent):void { g = canvas.graphics; var timer:Timer = new Timer(1000);//1秒刷新一次界面 timer.addEventListener(TimerEvent.TIMER,drawClock); timer.start(); } private function drawClock(e:TimerEvent):void { g.clear();//先擦除 //画个表盘 for(var i:int = 0; i < 60; i++)//表盘上有60个点 { var r:Number = 10; if(i % 5 == 0)//每5个点是一个钟头 { g.beginFill(0x00cc00,1); r = 10; } else { g.beginFill(0xcc0000,1); r = 5; } g.drawCircle( middlePointX + R*Math.cos(Math.PI/2 - Math.PI/30*i), middlePointY + R*Math.sin(Math.PI/2 - Math.PI/30*i), r ); g.endFill(); } /////////////////////////// nowDate = new Date; hour = nowDate.getHours(); min = nowDate.getMinutes(); sec = nowDate.getSeconds(); //秒 sangle = Math.PI/2 - sec*Math.PI/30;//以90度为0点,逆时针旋转 drawCursor(1,0xff0000,1,secCursorLength,sangle); //分 mangle = Math.PI/2 - (min + sec/60)*Math.PI/30;//分针的旋转角度是分和秒在分上的积累 drawCursor(3,0x00ff00,1,minuteCursorLength,mangle); //时 hangle = Math.PI/2 - (hour+min/60+sec/3600)*Math.PI/6;//////////// drawCursor(6,0x0000ff,1,hourCursorLength,hangle); } private function drawCursor(thickness:Number,color:uint,alpha:Number,cursorLen:Number,angle:Number):void { g.lineStyle(thickness,color,alpha); g.moveTo(middlePointX,middlePointY); g.lineTo( middlePointX + cursorLen*Math.cos(angle), middlePointY - cursorLen*Math.sin(angle) ); } ]]> </fx:Script> <mx:Canvas id="canvas" width="100%" height="100%" top="20" left="30"/> </s:WindowedApplication>
方式二:
采用矢量图形的办法,这种方式在flex4之后才有.可以很方便的用现有的图形来组合出想要的效果<?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" backgroundColor="green" width="800" height="600" creationComplete="init(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; private var increament:Number = 0; protected function init(event:FlexEvent):void { var timer:Timer = new Timer(1000); timer.addEventListener(TimerEvent.TIMER,function(e:TimerEvent):void { run("timer"); }); timer.start(); } private function run(mode:String = "clock"):void { var nowDate:Date = new Date; var hour:Number = mode == "clock" ? nowDate.hours : 0; var min:Number = mode == "clock" ? nowDate.minutes : 0; var sec:Number = mode == "clock" ? nowDate.seconds : ++increament; var sangle:Number = sec*6 - 90; var mangle:Number = (min + sec/60)*6 - 90 ; var hangle:Number = (hour+min/60+sec/3600)*30 - 90; secNeedle.rotation = sangle; minNeedle.rotation = mangle; hourNeedle.rotation = hangle; } ]]> </fx:Script> <s:Group top="30" left="50"> <s:Ellipse width="300" height="300"> <s:stroke> <s:SolidColorStroke color="black" weight="4"/> </s:stroke> </s:Ellipse> <s:Ellipse width="10" height="10" x="145" y="145"> <s:stroke> <s:SolidColorStroke color="black" weight="2"/> </s:stroke> <s:fill> <s:SolidColor color="white"/> </s:fill> </s:Ellipse> <s:Line x="150" y="150" width="140" id="secNeedle" rotation="-90"> <s:stroke> <s:SolidColorStroke color="red" weight="1"/> </s:stroke> </s:Line> <s:Line x="150" y="150" width="110" id="minNeedle" rotation="-90"> <s:stroke> <s:SolidColorStroke color="yellow" weight="2"/> </s:stroke> </s:Line> <s:Line x="150" y="150" width="70" id="hourNeedle" rotation="-90"> <s:stroke> <s:SolidColorStroke color="blue" weight="3"/> </s:stroke> </s:Line> </s:Group> </s:WindowedApplication>
对第一种方式的正确理解:
<?xml version="1.0" encoding="utf-8"?> <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" <span style="white-space:pre"> </span> xmlns:s="library://ns.adobe.com/flex/spark" <span style="white-space:pre"> </span> xmlns:mx="library://ns.adobe.com/flex/mx" <span style="white-space:pre"> </span> creationComplete="init(event)"> <fx:Script> <span style="white-space:pre"> </span> <![CDATA[ <span style="white-space:pre"> </span> import mx.events.FlexEvent; <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> private var g:Graphics; <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> private var middlePointX:Number = 200;//中心点位置 <span style="white-space:pre"> </span> private var middlePointY:Number = 200; <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> private var hourCursorLength:Number = 120;//各表针长度 <span style="white-space:pre"> </span> private var minuteCursorLength:Number = 160; <span style="white-space:pre"> </span> private var secCursorLength:Number = 180; <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> private var R:Number = 200;//表盘半径 <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> protected function init(event:FlexEvent):void <span style="white-space:pre"> </span> { <span style="white-space:pre"> </span> g = canvas.graphics; <span style="white-space:pre"> </span> var timer:Timer = new Timer(1000);//1秒刷新一次界面 <span style="white-space:pre"> </span> timer.addEventListener(TimerEvent.TIMER,drawClock); <span style="white-space:pre"> </span> timer.start(); <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> private function drawClock(e:TimerEvent):void <span style="white-space:pre"> </span> { <span style="white-space:pre"> </span> g.clear();//先擦除 <span style="white-space:pre"> </span> //画个表盘 <span style="white-space:pre"> </span> for(var i:int = 0; i < 60; i++)//表盘上有60个点 <span style="white-space:pre"> </span> { <span style="white-space:pre"> </span> var r:Number = 10; <span style="white-space:pre"> </span> if(i % 5 == 0)//每5个点是一个钟头 <span style="white-space:pre"> </span> { <span style="white-space:pre"> </span> g.beginFill(0x00cc00,1); <span style="white-space:pre"> </span> r = 10; <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> else <span style="white-space:pre"> </span> { <span style="white-space:pre"> </span> g.beginFill(0xcc0000,1); <span style="white-space:pre"> </span> r = 5; <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> g.drawCircle( //<span style="white-space:pre"> </span> 由于整好画满一个圆周,所以从哪里画并不重要,结果都是一致的 //<span style="white-space:pre"> </span> middlePointX + R*Math.cos(Math.PI/2 - Math.PI/30*i), //<span style="white-space:pre"> </span> middlePointY + R*Math.sin(Math.PI/2 - Math.PI/30*i), <span style="white-space:pre"> </span> middlePointX + R*Math.cos(Math.PI/30*i), <span style="white-space:pre"> </span> middlePointY + R*Math.sin(Math.PI/30*i), <span style="white-space:pre"> </span> r <span style="white-space:pre"> </span> ); <span style="white-space:pre"> </span> g.endFill(); <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> var nowDate:Date = new Date; <span style="white-space:pre"> </span> var hour:Number = nowDate.getHours(); <span style="white-space:pre"> </span> var min:Number = nowDate.getMinutes(); <span style="white-space:pre"> </span> var sec:Number = nowDate.getSeconds(); <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> //在PC坐标中角度递增是顺时针旋转,与笛卡尔坐标相反 <span style="white-space:pre"> </span> //另外0刻所在的角度是90度,所以要减去90度 <span style="white-space:pre"> </span> var sangle:Number = sec*Math.PI/30 - Math.PI/2 ; <span style="white-space:pre"> </span> drawCursor(1,0xff0000,1,secCursorLength,sangle); <span style="white-space:pre"> </span> var mangle:Number = (min + sec/60)*Math.PI/30 - Math.PI/2 ; <span style="white-space:pre"> </span> drawCursor(3,0x00ff00,1,minuteCursorLength,mangle); <span style="white-space:pre"> </span> var hangle:Number = (hour + min/60 + sec/3600)*Math.PI/6 - Math.PI/2 ; <span style="white-space:pre"> </span> drawCursor(6,0x0000ff,1,hourCursorLength,hangle); <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> <span style="white-space:pre"> </span> private function drawCursor(thickness:Number,color:uint,alpha:Number,cursorLen:Number,angle:Number):void <span style="white-space:pre"> </span> { <span style="white-space:pre"> </span> g.lineStyle(thickness,color,alpha); <span style="white-space:pre"> </span> g.moveTo(middlePointX,middlePointY); <span style="white-space:pre"> </span> g.lineTo( <span style="white-space:pre"> </span> middlePointX + cursorLen*Math.cos(angle), <span style="white-space:pre"> </span> middlePointY + cursorLen*Math.sin(angle) <span style="white-space:pre"> </span> ); <span style="white-space:pre"> </span> } <span style="white-space:pre"> </span> ]]> </fx:Script> <span style="white-space:pre"> </span><mx:Canvas id="canvas" width="100%" height="100%" top="20" left="30"/> </s:WindowedApplication>
======================================================================================================================
我觉得第一种方式代码写分离性不如第二种高.第一种是要进行整体的考虑,每次都要对每个指针进行擦除和绘制.而第二种布局好了固定不变的
图形安排后.剩下的任务就是编写指针的运动逻辑.这样便于代码的阅读和维护.
结尾补充:
计算机坐标系是笛卡尔坐标系y轴区间对x轴的镜像.或者说相当于笛卡尔坐标系沿着x轴翻转180度.笛卡尔坐标系中的顺时针,在PC坐标系看来是顺时针的,反之亦然.
相关文章推荐
- 安卓系统(android)常用权限
- shelve模块
- 欢迎使用CSDN-markdown编辑器
- Java第四周常用类与集合框架上机实验四学会包装类常用方法使用
- Java第四周常用类与集合框架上机实验三学会String类常用方法使用
- linux进程及进程控制
- linux syslogd 守护进程
- 利用WheelView实现时间选择器DatePicker
- Java第四周常用类与集合框架上机实验二学会Math类常用方法使用
- 网络安全漏洞平台
- 非规范处理IMP-00010错误一例
- 仿iOS滚轮时间选择器和地区选择
- Light oj 1021 Painful Bases(状压dp)
- log4j.properties使用
- spring笔记
- Java第四周常用类与集合框架上机实验一接口+抽象类
- 一种Dump文件解析
- js访问对象的区别
- GCC常用命令
- 开源项目的一些好文章