Decimal Clock、10進化時計を作ってみました


雑談の中で、10進法の時計ってどうしてないのだろう?という話になりました。

しかし、歴史をひもとくと、フランス革命直後に導入しようと試みた事はあるようです。

http://ja.wikipedia.org/wiki/十進化時間

どんな動きをするのか興味本位で10進化時計を作ってみました。
やはり全然わかりません。慣れが必要です。
これでは約束の時間も守れそうもありません。

Dechimal Clock 十進化時間 – wonderfl build flash online

[sourcecode language=”as3″]
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.setTimeout;
import flash.utils.clearTimeout;
import net.hires.debug.Stats;
import flash.display.StageAlign;

[SWF(width = "465", height = "465", backgroundColor = "0xFFFFFF", frameRate = "60")]
public class Main extends Sprite
{
public static var mode:String = "deodecimal";
private var view:View;
private var id:uint;
private var stats:Stats;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point
view = new View();
addChild(view);
view.init();
//
var screen:Sprite = new Sprite();
addChild( screen );
var g:Graphics = screen.graphics;
g.beginFill(0, 0);
g.drawRect(0,0,stage.stageWidth,stage.stageHeight)
screen.buttonMode = true;
screen.addEventListener(MouseEvent.CLICK , stageClick, false, 0, false );
//
id = setTimeout( firstMove, 3000);
}
private function resizeListener(event:Event):void {

}
private function firstMove():void {
mode = "decimal";
view.changeMode( mode );
}
private function stageClick( event:MouseEvent ):void {
clearTimeout(id);
if (mode == "decimal") {
mode = "deodecimal"
}else {
mode = "decimal";
}
view.changeMode( mode );
}

}

}

import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Matrix;
import flash.text.TextField;
class View extends MovieClip
{
private const K:Number = 0.4;
private const U:Number = 0.65;
private var center_x:Number;
private var center_y:Number;
private var hours_mc:MovieClip = new MovieClip();
private var minutes_mc:MovieClip = new MovieClip();
private var seconds_mc:MovieClip = new MovieClip();
private var lines:Sprite;
private var dials:Dials;
//private var tf:TextField;
private var digital:DigitalClock;
public function View()
{
//tf = new TextField();
//addChild( tf );

}
public function init():void {
var bm:Bitmap;
var bmd:BitmapData;
center_x = stage.stageWidth * .5;
center_y = stage.stageHeight * .5;
//
dials = new Dials();
addChild( dials );
dials.init();
//
var g:Graphics
/**/
var backCricle:Sprite = new Sprite();
addChild( backCricle );
g = backCricle.graphics;
g.beginFill( 0xCCCCCC ,0.8 );
g.drawCircle( center_x , center_y , 200 );
bmd = new BitmapData( stage.width, stage.stageHeight , true, 0xFFFFFF);
bmd.draw( backCricle );
g.clear();
bm = new Bitmap( bmd , "auto" , true );
backCricle.addChild( bm );
//
digital = new DigitalClock();
addChild( digital );
digital.init();

lines = new Sprite();
addChild(lines);
//
var marix:Matrix = new Matrix()
hours_mc.w = 0;
hours_mc.x = center_x;
hours_mc.y = center_y;
addChild(hours_mc);
g=hours_mc.graphics;
g.beginFill(0x000000);
g.drawCircle(11, 120 , 10);
g.lineStyle( 1, 0x0 );
g.moveTo( 11 , 0);
g.lineTo( 11 , 120 );
bmd = new BitmapData( 22, 120+11 , true, 0x00FFFFFF);
bmd.draw( hours_mc );
g.clear();
bm = new Bitmap( bmd , "auto" , true );
hours_mc.addChild( bm );
bm.x = -11;
bm.y = 0;
//
minutes_mc.w = 0;
minutes_mc.x = center_x;
minutes_mc.y = center_y;
addChild(minutes_mc);
g=minutes_mc.graphics;
g.beginFill(0x000000);
g.drawCircle(6, 150 , 5);
g.lineStyle( 1, 0x0 );
g.moveTo( 6 , 0);
g.lineTo( 6 , 150 );
bmd = new BitmapData( 12, 150+6 , true, 0x00FFFFFF);
bmd.draw( minutes_mc );
g.clear();
bm = new Bitmap( bmd , "auto" , true );
minutes_mc.addChild( bm );
bm.x = -6;
bm.y = 0;
//
seconds_mc.w = 0;
seconds_mc.x = center_x;
seconds_mc.y = center_y;
addChild(seconds_mc);
g = seconds_mc.graphics;
g.beginFill(0x000000);
g.drawCircle(4, 190 , 3);
g.lineStyle( 1, 0x0 );
g.moveTo( 4 , 0);
g.lineTo( 4 , 190 );
bmd = new BitmapData( 8, 190+4, true, 0x00FFFFFF);
bmd.draw( seconds_mc );
g.clear();
bm = new Bitmap( bmd , "auto" , true );
seconds_mc.addChild( bm );
bm.x = -4;
bm.y = 0;
//
var pin:Shape = new Shape();
g = pin.graphics;
g.beginFill(0x000000);
g.drawCircle(0, 0, 1);
addChild( pin );
pin.x = center_x;
pin.y = center_y;
setInitPositions();
addEventListener(Event.ENTER_FRAME, enterLister, false, 0, false);
}
public function changeMode( mode:String ):void {
hours_mc.w = 0;
minutes_mc.w = 0;
seconds_mc.w = 0;
dials.changeMode( mode );
digital.changeMode( mode );
}
private function setInitPositions():void {
var h:uint;
var m:uint;
var s:uint
lines.graphics.clear();
if(Main.mode == "decimal"){
var decimal:Decimal = new Decimal();
h = decimal.hours;
m = decimal.minutes;
s = decimal.seconds;
setPosition( seconds_mc , s / 100 , 190);
setPosition( minutes_mc , (m / 100)+100*(s/100) , 150 );
setPosition( hours_mc , (h / 10)+((1/10)*(m/100))+((1/10000)*(s/100)) , 120);
}else {
var date:Date = new Date();
h = date.hours;
m = date.minutes;
s = date.seconds;
setPosition( seconds_mc , s / 60 , 190);
setPosition( minutes_mc , (m / 60)+(1/60)*(s/60) , 150 );
setPosition( hours_mc , ((h%12) / 12)+((1/12)*(m/60))+((1/3600)*(s/60)) , 120);
}
}
private function enterLister( event:Event = null):void {
var h:uint;
var m:uint;
var s:uint;
lines.graphics.clear();
if(Main.mode =="decimal"){
var decimal:Decimal = new Decimal();
h = decimal.hours;
m = decimal.minutes;
s = decimal.seconds;
setSpring( seconds_mc , s / 100 , 190 );
setSpring( minutes_mc , (m / 100)+(1/100)*(s/100) , 150 );
setSpring( hours_mc , (h / 10)+((1/10)*(m/100))+((1/10000)*(s/100)) , 120);
}else {
var date:Date = new Date();
h = date.hours;
m = date.minutes;
s = date.seconds;
setSpring( seconds_mc , s / 60 , 190);
setSpring( minutes_mc , (m / 60)+(1/60)*(s/60) , 150 );
setSpring( hours_mc , ((h%12) / 12)+((1/12)*(m/60))+((1/3600)*(s/60)) , 120);
}
}
private function setSpring( _mc:MovieClip , time:Number , radius:Number ):void {
var target_theta:Number = 360 * time -180 ;
/**/
if ( target_theta – _mc.theta < -180 ) {
_mc.theta += -360;
}

var aw:Number = K * ( target_theta – _mc.theta );
_mc.w += aw – (U * _mc.w);
//trace(target_theta , _mc.rotation ,_mc.w)
_mc.theta += _mc.w;

//
_mc.rotation = _mc.theta;
}
private function setPosition( _mc:MovieClip , time:Number , radius:Number ):void {
_mc.theta = 360*time -180 ;
_mc.rotation = _mc.theta;

}

}

import flash.display.MovieClip;
//import fl.text.TLFTextField;
import flash.text.TextField;
import flash.display.Sprite;
import flash.events.Event;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.display.BitmapData;
import flash.display.Bitmap;
class Dials extends MovieClip
{
private var center_x:Number ;
private var center_y:Number;
private var decimalList:Vector.<MovieClip>;
private var duodecimalList:Vector.<MovieClip>;
public function Dials()
{

}
public function init():void {
center_x = stage.stageWidth * 0.5;
center_y = stage.stageHeight * 0.5;
if ( Main.mode == "decimal") {
decimalList = setDials( 10, 220 , 10);
duodecimalList = setDials( 12, 50 , 5 );
}else {
decimalList = setDials( 10 , 50 , 10 );
duodecimalList = setDials( 12 , 220 , 5 );
}
}
public function changeMode( mode:String ):void {
var i:uint;
var n:uint;
var dial:MovieClip;
var theta:Number;
var radius:Number;
if ( mode == "decimal" ) {
n = decimalList.length;
radius = 220 ;
for ( i = 0; i < n ; i++) {
dial = decimalList[i];
setTarget( dial , i, n, radius);
}
n = duodecimalList.length;
radius = 50 ;
for ( i = 0; i < n ; i++) {
dial = duodecimalList[i];
setTarget( dial , i, n, radius);
}
}else {
n = decimalList.length;
radius = 55 ;
for ( i = 0; i < n ; i++) {
dial = decimalList[i];
setTarget( dial , i, n, radius);
}
n = duodecimalList.length;
radius = 220 ;
for ( i = 0; i < n ; i++) {
dial = duodecimalList[i];
setTarget( dial , i, n, radius);
}
}

}
private function setTarget( dial:MovieClip , i:uint , n:uint , radius:Number ):void {
var theta:Number = 2 * Math.PI * ((i+1) / n) – Math.PI * 0.5;
dial.target_x = center_x + (radius * Math.cos( theta ));
dial.target_y = center_y + (radius * Math.sin( theta ));
dial.removeEventListener( Event.ENTER_FRAME , targetListener );
dial.addEventListener( Event.ENTER_FRAME , targetListener , false , 0 , false );
}
private function targetListener( event:Event ):void {

var dial:MovieClip = MovieClip( event.currentTarget );
var dx:Number = dial.target_x – dial.x;
var dy:Number = dial.target_y – dial.y;
dial.x += dx * 0.3;
dial.y += dy * 0.3;
}

private function setDials( n:Number , radius:Number , coefficient:Number ):Vector.<MovieClip> {
var list:Vector.<MovieClip> = new Vector.<MovieClip>();
var i:uint;

var theta:Number;
var dial:Sprite;
//var tf:TLFTextField;
var tf_hour:TextField;
var tf_minute:TextField;
var format:TextFormat = new TextFormat();
format.bold = true;
format.align = TextFormatAlign.CENTER;
format.size = 24;
format.font = "_ゴシック";
var minuteformat:TextFormat = new TextFormat();
minuteformat.bold = true;
minuteformat.align = TextFormatAlign.CENTER;
minuteformat.size = 12;
minuteformat.font = "_ゴシック";
var bmd:BitmapData;
var bm:Bitmap;
for ( i = 1; i <= n ; i++) {
dial = new MovieClip();
addChild(dial);
//tf = new TLFTextField();
tf_hour = new TextField();
dial.addChild(tf_hour);
tf_hour.defaultTextFormat = format;
tf_hour.text = String(i);
tf_hour.height = tf_hour.textHeight;

tf_hour.width = 36;
tf_hour.x = 0;
tf_hour.y = 0;
//

//tf = new TLFTextField();
tf_minute = new TextField();
dial.addChild(tf_minute);
tf_minute.defaultTextFormat = minuteformat;
tf_minute.text = String( coefficient * i );
tf_minute.width = 36;
tf_minute.height = tf_minute.textHeight+2;
tf_minute.x = 0;
tf_minute.y = 22;

theta = 2 * Math.PI * (i / n) – Math.PI * 0.5;
dial.x = center_x + (radius * Math.cos( theta ));
dial.y = center_y + (radius * Math.sin( theta ));
bmd = new BitmapData( 36, 36, true , 0x00FFFFFF );
bmd.draw( dial );
bm = new Bitmap( bmd, "auto" , true);
dial.removeChild( tf_hour );
dial.removeChild(tf_minute );
dial.addChild( bm );
//dial.cacheAsBitmap = true;
bm.x = bm.width * -0.5;
bm.y = bm.height * -0.5;
dial.rotation = (360 / n) * i;
addChild( dial );
list.push( dial )
}
return list;
}

}
import adobe.utils.CustomActions;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.MovieClip;
//import fl.text.TLFTextField;
import flash.events.Event;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
class DigitalClock extends MovieClip
{
private const K:Number = 0.3;
private const U:Number = 0.4;
private var duoClock:MovieClip;
private var demicalClock:MovieClip;
private var bmdList:Vector.<BitmapData>;
private var clearBmd:BitmapData;
private var dateBmd:BitmapData;
private var dateBm:Bitmap;
private var decimalBmd:BitmapData;
private var decimalBm:Bitmap;
private var colonBmd:BitmapData;
public function DigitalClock()
{
//init();
bmdList = new Vector.<BitmapData>();
var tf:TextField = new TextField();
//addChild(tf);
var format:TextFormat = new TextFormat();
format.size = 36;
format.font = "_ゴシック";
format.color = 0xFFFFFF;
format.bold = true;
tf.defaultTextFormat = format;
var bmd:BitmapData;
var bm:Bitmap;
var i:uint;
var n:uint = 10;
for ( i = 0 ; i < n ; i++) {
tf.text = String(i);
bmd = new BitmapData(36, 45, true , 0x00FFFFFF);
bmd.draw( tf );
bmdList.push( bmd );
}
tf.text = ":";
colonBmd = new BitmapData(36, 45, true , 0x00FFFFFF);
colonBmd.draw( tf );
}
public function init():void {
var bm:Bitmap;
var i:uint;
var n:uint = 3;
var textfield:TextField;
duoClock = new MovieClip();
addChild( duoClock );
duoClock.v = 0;
duoClock.x = stage.stageWidth * 0.5;
duoClock.y = stage.stageHeight * 0.5 + 70;
//
demicalClock = new MovieClip();
addChild(demicalClock );
demicalClock.v = 0;
demicalClock.x = stage.stageWidth * 0.5;
demicalClock.y = stage.stageHeight * 0.5 + 70;
//
clearBmd = new BitmapData( 160 , 45 , true , 0x00FFFFFF);
dateBmd = clearBmd.clone();
dateBm = new Bitmap( dateBmd, "auto", true);
duoClock.addChild( dateBm );
dateBm.x = -70;
dateBm.y = -18;
//
decimalBmd = clearBmd.clone();
decimalBm = new Bitmap( decimalBmd, "auto", true);
demicalClock.addChild( decimalBm );
decimalBm.x = -70;
decimalBm.y = -18;
//
setTime();
//
addEventListener( Event.ENTER_FRAME , setTime , false , 0 , false);
if ( Main.mode == "deodecimal") {
duoClock.scaleX = 1;
duoClock.scaleY = 1;
demicalClock.scaleX = 0;
demicalClock.scaleY = 0;
}else {
duoClock.scaleX = 0;
duoClock.scaleY = 0;
demicalClock.scaleX = 1;
demicalClock.scaleY = 1;
}
}

public function setTime(event:Event = null):void {
var i:uint ;
var bmd1:BitmapData;
var bmd0:BitmapData;
//
dateBmd.lock();
dateBmd = clearBmd.clone();
//
var date:Date = new Date();
var h:String = zeroPlus(date.hours );
var h0:Number = Number(h.substr(0, 1));
var h1:Number = Number(h.substr(1, 1));
var s:String = zeroPlus(date.seconds );
var s0:Number = Number(s.substr(0, 1));
var s1:Number = Number(s.substr(1, 1));
var m:String = zeroPlus(date.minutes );
var m0:Number = Number(m.substr(0, 1));
var m1:Number = Number(m.substr(1, 1));
bmd1 = bmdList[h1];
bmd0 = bmdList[h0];
//
dateBmd.copyPixels( bmd0, new Rectangle(0, 0, bmd0.width , bmd0.height) , new Point(0 , 0) , null, null, true);
dateBmd.copyPixels( bmd1, new Rectangle(0, 0, bmd1.width , bmd1.height) , new Point(0 + 20, 0) , null, null, true);
//
bmd1 = bmdList[m1];
bmd0 = bmdList[m0];
dateBmd.copyPixels( bmd0, new Rectangle(0, 0, bmd0.width , bmd0.height) , new Point( 50, 0) , null, null, true);
dateBmd.copyPixels( bmd1, new Rectangle(0, 0, bmd1.width , bmd1.height) , new Point( 70, 0) , null, null, true);
//
bmd1 = bmdList[s1];
bmd0 = bmdList[s0];
dateBmd.copyPixels( bmd0, new Rectangle(0, 0, bmd0.width , bmd0.height) , new Point( 100, 0) , null, null, true);
dateBmd.copyPixels( bmd1, new Rectangle(0, 0, bmd1.width , bmd1.height) , new Point( 120, 0) , null, null, true);
if( Number( s )%2 == 0){
dateBmd.copyPixels ( colonBmd, new Rectangle(0, 0, colonBmd.width, colonBmd.height) , new Point(40 , -5) , null, null, true );
dateBmd.copyPixels ( colonBmd, new Rectangle(0, 0, colonBmd.width, colonBmd.height) , new Point(90 , -5) , null, null, true );
}
dateBm.bitmapData = dateBmd;
dateBmd.unlock();
/**/
decimalBmd.lock();
decimalBmd = clearBmd.clone();
//
var decimal:Decimal = new Decimal();
h = String(decimal.hours );
h0= Number(h);
s = zeroPlus(decimal.seconds );
s0 = Number(s.substr(0, 1));
s1 = Number(s.substr(1, 1));
m = zeroPlus(decimal.minutes );
m0 = Number(m.substr(0, 1));
m1 = Number(m.substr(1, 1));
//
bmd0 = bmdList[h0];
decimalBmd.copyPixels( bmd0, new Rectangle(0, 0, bmd0.width , bmd0.height) , new Point(20 , 0) , null, null, true);
//
bmd1 = bmdList[m1];
bmd0 = bmdList[m0];
decimalBmd.copyPixels( bmd0, new Rectangle(0, 0, bmd0.width , bmd0.height) , new Point( 50, 0) , null, null, true);
decimalBmd.copyPixels( bmd1, new Rectangle(0, 0, bmd1.width , bmd1.height) , new Point( 70, 0) , null, null, true);
//
bmd1 = bmdList[s1];
bmd0 = bmdList[s0];
decimalBmd.copyPixels( bmd0, new Rectangle(0, 0, bmd0.width , bmd0.height) , new Point( 100, 0) , null, null, true);
decimalBmd.copyPixels( bmd1, new Rectangle(0, 0, bmd1.width , bmd1.height) , new Point( 120, 0) , null, null, true);
if( Number( s )%2 == 0){
decimalBmd.copyPixels ( colonBmd, new Rectangle(0, 0, colonBmd.width, colonBmd.height) , new Point(40 , -5) , null, null, true );
decimalBmd.copyPixels ( colonBmd, new Rectangle(0, 0, colonBmd.width, colonBmd.height) , new Point(90 , -5) , null, null, true );
}
decimalBm.bitmapData = decimalBmd;
decimalBmd.unlock();
}
public function changeMode( mode:String ):void {
if ( mode == "deodecimal") {
duoClock.target_scale = 1;
demicalClock.target_scale = 0;
duoClock.removeEventListener( Event.ENTER_FRAME , clockListener );
demicalClock.removeEventListener( Event.ENTER_FRAME , clockListener);
duoClock.addEventListener( Event.ENTER_FRAME , clockListener , false, 0 , false );
demicalClock.addEventListener( Event.ENTER_FRAME , clockListener , false, 0 , false );
}else {
duoClock.target_scale = 0;
demicalClock.target_scale = 1;
duoClock.removeEventListener( Event.ENTER_FRAME , clockListener );
demicalClock.removeEventListener( Event.ENTER_FRAME , clockListener);
duoClock.addEventListener( Event.ENTER_FRAME , clockListener , false, 0 , false );
demicalClock.addEventListener( Event.ENTER_FRAME , clockListener , false, 0 , false );
}
}
private function clockListener( event:Event ):void {
var clock:MovieClip = MovieClip( event.currentTarget );
var a:Number = K * ( clock.target_scale – clock.scaleX );
clock.v += a – U * clock.v;
clock.scaleX += clock.v;
clock.scaleY = clock.scaleX;
}
private function zeroPlus( number:Number ):String {
var answer_string:String = String(100 + number).substr(1, 2);
return answer_string;
}
}

class Decimal
{
public var hours:uint;
public var minutes:uint;
public var seconds:uint;
public function Decimal()
{
var date:Date = new Date();
var zero:Date = new Date( date.fullYear , date.month , date.date , 0 , 0 , 0 , 0 );
var msTime:Number = date.getTime() – zero.getTime();
var decimalTime:Number = msTime*(10*100*100*1000)/(24*60*60*1000);
hours = Math.floor(decimalTime / (100*100*1000));
minutes = Math.floor( (decimalTime – hours*100*100*1000) / (100 * 1000) );
seconds = Math.floor( (decimalTime – hours*100*100*1000 – minutes*100*1000) / (1000) );
}
}

[/sourcecode]

最近スタッフの携帯電話が急速にAndroid化しています。
折角なのでAIR for Androidにしてみました。
最初は、文字盤やデジタル時計はTextFieldでしたが、表示が重かったためビットマップ化しました。
アナログ時計のdraw類も、シャギーがひどくビットマップ化。
cashAsBitmapではバグがあり、画像に荒れが発生してしまいました。
やはり最適化にコストがかかりそうです。

http://works.mztm.jp/kawamura/android/DecimalClock.apk

アイコンは下記のサイトから書き出しました。綺麗に出来ました。
http://www.androidicongenerator.net/home_ja.html

アプリを作ると弊社の結束が喜んで自分の携帯にインストールしていました。
結束曰く「休日はこの方が便利なんですよ。1日の何分の一か一目でわかるじゃないですか!」とのこと。
世の中には変わった人がいるものです。

 

Comments are closed.