-
Notifications
You must be signed in to change notification settings - Fork 0
/
clock.js
151 lines (129 loc) · 4.54 KB
/
clock.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
/**
* 目盛り
*/
var ScaleObject = React.createClass({
render: function () {
{/* this.props.index : 0-59 */}
var degree = "rotate(" + this.props.index * 6 + ")";
var id = "#" + this.props.type;
return <use xlinkHref={id} transform={degree}/>
}
});
/**
* 文字盤
*/
var DigitTextObject = React.createClass({
render: function () {
{/* this.props.index : 0-11 */}
var degree = this.props.index * 30;
var radian = Math.PI / 180 * degree;
var x = Math.sin(radian) * 300;
var y = Math.cos(radian) * 300 * -1;
return <text x={x} y={y+30} fill="#888" fontSize="72" textAnchor="middle">{this.props.text}</text>
}
});
/**
* 時計盤(目盛り*文字盤)
*/
var ClockScale = React.createClass({
render: function () {
const ID_SCALE_LARGE = "scale_large";
const ID_SCALE_MEDIUM = "scale_medium";
const ID_SCALE_SMALL = "scale_small";
var scaleObjects = [];
for (var i = 0; i < 60; i++) {
var type = null;
if (i % 15 == 0) {
type = ID_SCALE_LARGE
} else if (i % 5 == 0) {
type = ID_SCALE_MEDIUM
} else {
type = ID_SCALE_SMALL
}
scaleObjects.push(<ScaleObject key={i} index={i} type={type}/>);
}
var digitTextObjects = [];
for (var i = 0; i < 12; i++) {
var text = String(i == 0 ? 12 : i);
digitTextObjects.push(<DigitTextObject key={i} index={i} text={text} />);
}
return (<svg width="100%" height="100%" viewBox="-500 -500 1000 1000">
<defs>
<g id={ID_SCALE_LARGE}>
<rect x="-4" y="-400" width="8" height="48" fill="#888"/>
</g>
<g id={ID_SCALE_MEDIUM}>
<rect x="-3" y="-400" width="6" height="40" fill="#888"/>
</g>
<g id={ID_SCALE_SMALL}>
<rect x="-2" y="-400" width="4" height="24" fill="#888"/>
</g>
</defs>
<circle cx="0" cy="0" r="440" fill="#ccc"/>
<circle cx="0" cy="0" r="420" fill="#eee"/>
{digitTextObjects}
{scaleObjects}
</svg>);
}
});
/**
* 針(長針+短針+秒針)
*/
var ClockHands = React.createClass({
getTransformAttr: function (degree) {
var val = "rotate(" + degree + ")";
return val;
},
render: function () {
var now = this.props.now;
var degreeSeconds = (now.getSeconds() / 60) * 360 + (now.getMilliseconds() / 1000) * (360 / 60);
var degreeMinutes = (now.getMinutes() / 60) * 360 + ((degreeSeconds / 360) * (360 / 60));
var degreeHours = (now.getHours() / 12) * 360 + ((degreeMinutes / 360) * (360 / 12));
return <svg width="100%" height="100%" viewBox="-500 -500 1000 1000">
<defs>
<g id="def_hand_long">
<polygon points="-5,-360 5,-360 10,30 -10,30" fill="#888"/>
</g>
<g id="def_hand_short">
<polygon points="-5,-300 5,-300 10,30 -10,30" fill="#888"/>
</g>
<g id="def_hand_second">
<polygon points="-2,-360 2,-360 3,30 -3,30" fill="#CCC"/>
</g>
</defs>
<use id="hand_long" xlinkHref="#def_hand_long" transform={this.getTransformAttr(degreeMinutes)}/>
<use id="hand_short" xlinkHref="#def_hand_short" transform={this.getTransformAttr(degreeHours)}/>
<use id="hand_second" xlinkHref="#def_hand_second" transform={this.getTransformAttr(degreeSeconds)}/>
<circle cx="0" cy="0" r="16" fill="#CCC"/>
</svg>;
}
});
/**
* 時計(時計盤+針)
*/
var ClockApplication = React.createClass({
render: function () {
var now = this.props.now;
var divStyle = {
width: '95%',
height: '95%',
position: 'absolute'
};
return <div>
<div style={divStyle}><ClockScale /></div>
<div style={divStyle}><ClockHands now={now}/></div>
</div>;
}
});
var start = new Date().getTime();
const INTERVAL_MS = 1000; // 描画間隔
const SPEED = 1; // 倍速
setInterval(function () {
var now = new Date().getTime();
var diff = now - start;
var targetDate = new Date(now + diff * (SPEED - 1));
ReactDOM.render(
<ClockApplication now={targetDate}/>,
document.getElementById('container')
);
}, INTERVAL_MS);