1 | /**
|
2 | * Analog clock.
|
3 | * @constructor ApAnalogClock
|
4 | */
|
5 |
|
6 | ;
|
7 |
|
8 | const React = require('react'),
|
9 | ReactDOM = require('react-dom'),
|
10 | classnames = require('classnames'),
|
11 | ApClock = require('./ap_clock'),
|
12 | PureRenderMixin = require('react-addons-pure-render-mixin'),
|
13 | chopcal = require('chopcal'),
|
14 | numcal = require('numcal'),
|
15 | types = React.PropTypes,
|
16 | ApAnalogClockHand = require('./ap_analog_clock_hand'),
|
17 | ApAnalogClockLetter = require('./ap_analog_clock_letter');
|
18 |
|
19 | /** @lends ApAnalogClock */
|
20 | let ApAnalogClock = React.createClass({
|
21 | displayName: 'ApAnalogClock',
|
22 |
|
23 | //--------------------
|
24 | // Specs
|
25 | //--------------------
|
26 |
|
27 | propTypes: {
|
28 | boardLetters: types.array
|
29 | },
|
30 |
|
31 | mixins: [PureRenderMixin],
|
32 |
|
33 | statics: {
|
34 | _angleForValue: function (value, max) {
|
35 | let rate = value % max / max;
|
36 | return chopcal.round(rate * 360, 0.1);
|
37 | },
|
38 | hourHandAngle: function (date) {
|
39 | let hours = date.getHours();
|
40 | return ApAnalogClock._angleForValue(hours, 12);
|
41 | },
|
42 | minuteHandAngle: function (date) {
|
43 | let minutes = date.getMinutes();
|
44 | return ApAnalogClock._angleForValue(minutes, 60);
|
45 | },
|
46 | secondHandAngle: function (date) {
|
47 | let seconds = date.getSeconds();
|
48 | return ApAnalogClock._angleForValue(seconds, 60);
|
49 | },
|
50 | letterAngle: function (i, count) {
|
51 | return ApAnalogClock._angleForValue(i, count);
|
52 | }
|
53 | },
|
54 |
|
55 | getInitialState: function () {
|
56 | return {
|
57 | looping: false,
|
58 | hour: 0,
|
59 | minute: 0,
|
60 | second: 0,
|
61 | size: 256
|
62 | };
|
63 | },
|
64 |
|
65 | getDefaultProps: function () {
|
66 | return {
|
67 | boardLetters: '12,1,2,3,4,5,6,7,8,9,10,11'.split(',')
|
68 | };
|
69 | },
|
70 |
|
71 | render: function () {
|
72 | let s = this,
|
73 | state = s.state,
|
74 | props = s.props;
|
75 |
|
76 | let letters = props.boardLetters.map((letter, i, letters) => {
|
77 | let angle = ApAnalogClock.letterAngle(i, letters.length);
|
78 | return React.createElement(ApAnalogClockLetter, { key: "ap-analog-letter-" + i,
|
79 | letter: letter,
|
80 | angle: angle });
|
81 | });
|
82 |
|
83 | return React.createElement(
|
84 | ApClock,
|
85 | { className: classnames("ap-analog-clock", props.className) },
|
86 | React.createElement(
|
87 | 'div',
|
88 | { className: 'ap-analog-clock-board', style: { width: state.size, height: state.size } },
|
89 | React.createElement(
|
90 | 'div',
|
91 | { className: 'ap-analog-clock-board-inner' },
|
92 | React.createElement(ApAnalogClockHand, { width: 4, heightRate: 0.8, angle: state.hour }),
|
93 | React.createElement(ApAnalogClockHand, { width: 4, heightRate: 1, angle: state.minute }),
|
94 | React.createElement(ApAnalogClockHand, { width: 2, heightRate: 1, angle: state.second })
|
95 | ),
|
96 | React.createElement(
|
97 | 'div',
|
98 | null,
|
99 | letters
|
100 | )
|
101 | )
|
102 | );
|
103 | },
|
104 |
|
105 | //--------------------
|
106 | // Lifecycle
|
107 | //--------------------
|
108 |
|
109 | componentWillMount: function () {
|
110 | let s = this;
|
111 | s._looping = true;
|
112 | },
|
113 |
|
114 | componentDidMount: function () {
|
115 | let s = this,
|
116 | props = s.props;
|
117 |
|
118 | function _loop() {
|
119 | if (!s._looping) {
|
120 | return;
|
121 | }
|
122 | let now = new Date();
|
123 | s.setState({
|
124 | hour: ApAnalogClock.hourHandAngle(now),
|
125 | minute: ApAnalogClock.minuteHandAngle(now),
|
126 | second: ApAnalogClock.secondHandAngle(now)
|
127 | });
|
128 | window.requestAnimationFrame(_loop);
|
129 | }
|
130 |
|
131 | window.addEventListener('resize', s.resizeClock);
|
132 | _loop();
|
133 | s.resizeClock();
|
134 | },
|
135 |
|
136 | componentWillReceiveProps: function (nextProps) {
|
137 | let s = this;
|
138 | },
|
139 |
|
140 | componentWillUpdate: function (nextProps, nextState) {
|
141 | let s = this;
|
142 | },
|
143 |
|
144 | componentDidUpdate: function (prevProps, prevState) {
|
145 | let s = this;
|
146 | },
|
147 |
|
148 | componentWillUnmount: function () {
|
149 | let s = this;
|
150 | window.removeEventListener('resize', s.resizeClock);
|
151 | s._looping = false;
|
152 | },
|
153 |
|
154 | //------------------
|
155 | // Helper
|
156 | //------------------
|
157 |
|
158 | resizeClock: function () {
|
159 | let s = this,
|
160 | elm = ReactDOM.findDOMNode(s);
|
161 | let size = numcal.min(elm.offsetWidth, elm.offsetHeight);
|
162 | s.setState({
|
163 | size: size
|
164 | });
|
165 | }
|
166 | //------------------
|
167 | // Private
|
168 | //------------------
|
169 | });
|
170 |
|
171 | module.exports = ApAnalogClock;
|
172 | //# sourceMappingURL=data:application/json;base64,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O0FBQ3BELFNBQUMsQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO0tBQ3RCOzs7Ozs7QUFNRCxlQUFXLEVBQUUsWUFBWTtBQUNyQixZQUFJLENBQUMsR0FBRyxJQUFJO1lBQ1IsR0FBRyxHQUFHLFFBQVEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDbEMsWUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztBQUN6RCxTQUFDLENBQUMsUUFBUSxDQUFDO0FBQ1AsZ0JBQUksRUFBRSxJQUFJO1NBQ2IsQ0FBQyxDQUFDO0tBQ047Ozs7QUFBQSxDQUlKLENBQUMsQ0FBQzs7QUFFSCxNQUFNLENBQUMsT0FBTyxHQUFHLGFBQWEsQ0FBQyIsImZpbGUiOiJhcF9hbmFsb2dfY2xvY2suanMiLCJzb3VyY2VSb290IjoiL1VzZXJzL29rdW5pc2hpdGFrYS9wcm9qZWN0cy9hcGVtYW4tcmVhY3QtbGFiby9hcGVtYW4tcmVhY3QtY2xvY2svbGliL2pzeCIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQW5hbG9nIGNsb2NrLlxuICogQGNvbnN0cnVjdG9yIEFwQW5hbG9nQ2xvY2tcbiAqL1xuXG5cInVzZSBzdHJpY3RcIjtcblxuY29uc3QgUmVhY3QgPSByZXF1aXJlKCdyZWFjdCcpLFxuICAgIFJlYWN0RE9NID0gcmVxdWlyZSgncmVhY3QtZG9tJyksXG4gICAgY2xhc3NuYW1lcyA9IHJlcXVpcmUoJ2NsYXNzbmFtZXMnKSxcbiAgICBBcENsb2NrID0gcmVxdWlyZSgnLi9hcF9jbG9jaycpLFxuICAgIFB1cmVSZW5kZXJNaXhpbiA9IHJlcXVpcmUoJ3JlYWN0LWFkZG9ucy1wdXJlLXJlbmRlci1taXhpbicpLFxuICAgIGNob3BjYWwgPSByZXF1aXJlKCdjaG9wY2FsJyksXG4gICAgbnVtY2FsID0gcmVxdWlyZSgnbnVtY2FsJyksXG4gICAgdHlwZXMgPSBSZWFjdC5Qcm9wVHlwZXMsXG4gICAgQXBBbmFsb2dDbG9ja0hhbmQgPSByZXF1aXJlKCcuL2FwX2FuYWxvZ19jbG9ja19oYW5kJyksXG4gICAgQXBBbmFsb2dDbG9ja0xldHRlciA9IHJlcXVpcmUoJy4vYXBfYW5hbG9nX2Nsb2NrX2xldHRlcicpO1xuXG4vKiogQGxlbmRzIEFwQW5hbG9nQ2xvY2sgKi9cbmxldCBBcEFuYWxvZ0Nsb2NrID0gUmVhY3QuY3JlYXRlQ2xhc3Moe1xuXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIFNwZWNzXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgcHJvcFR5cGVzOiB7XG4gICAgICAgIGJvYXJkTGV0dGVyczogdHlwZXMuYXJyYXlcbiAgICB9LFxuXG4gICAgbWl4aW5zOiBbXG4gICAgICAgIFB1cmVSZW5kZXJNaXhpblxuICAgIF0sXG5cbiAgICBzdGF0aWNzOiB7XG4gICAgICAgIF9hbmdsZUZvclZhbHVlOiBmdW5jdGlvbiAodmFsdWUsIG1heCkge1xuICAgICAgICAgICAgbGV0IHJhdGUgPSAodmFsdWUgJSBtYXgpIC8gbWF4O1xuICAgICAgICAgICAgcmV0dXJuIGNob3BjYWwucm91bmQocmF0ZSAqIDM2MCwgMC4xKTtcbiAgICAgICAgfSxcbiAgICAgICAgaG91ckhhbmRBbmdsZTogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICAgICAgICAgIGxldCBob3VycyA9IGRhdGUuZ2V0SG91cnMoKTtcbiAgICAgICAgICAgIHJldHVybiBBcEFuYWxvZ0Nsb2NrLl9hbmdsZUZvclZhbHVlKGhvdXJzLCAxMik7XG4gICAgICAgIH0sXG4gICAgICAgIG1pbnV0ZUhhbmRBbmdsZTogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICAgICAgICAgIGxldCBtaW51dGVzID0gZGF0ZS5nZXRNaW51dGVzKCk7XG4gICAgICAgICAgICByZXR1cm4gQXBBbmFsb2dDbG9jay5fYW5nbGVGb3JWYWx1ZShtaW51dGVzLCA2MCk7XG4gICAgICAgIH0sXG4gICAgICAgIHNlY29uZEhhbmRBbmdsZTogZnVuY3Rpb24gKGRhdGUpIHtcbiAgICAgICAgICAgIGxldCBzZWNvbmRzID0gZGF0ZS5nZXRTZWNvbmRzKCk7XG4gICAgICAgICAgICByZXR1cm4gQXBBbmFsb2dDbG9jay5fYW5nbGVGb3JWYWx1ZShzZWNvbmRzLCA2MCk7XG4gICAgICAgIH0sXG4gICAgICAgIGxldHRlckFuZ2xlOiBmdW5jdGlvbiAoaSwgY291bnQpIHtcbiAgICAgICAgICAgIHJldHVybiBBcEFuYWxvZ0Nsb2NrLl9hbmdsZUZvclZhbHVlKGksIGNvdW50KTtcbiAgICAgICAgfVxuICAgIH0sXG5cbiAgICBnZXRJbml0aWFsU3RhdGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGxvb3Bpbmc6IGZhbHNlLFxuICAgICAgICAgICAgaG91cjogMCxcbiAgICAgICAgICAgIG1pbnV0ZTogMCxcbiAgICAgICAgICAgIHNlY29uZDogMCxcbiAgICAgICAgICAgIHNpemU6IDI1NlxuICAgICAgICB9O1xuICAgIH0sXG5cbiAgICBnZXREZWZhdWx0UHJvcHM6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGJvYXJkTGV0dGVyczogJzEyLDEsMiwzLDQsNSw2LDcsOCw5LDEwLDExJy5zcGxpdCgnLCcpXG4gICAgICAgIH07XG4gICAgfSxcblxuICAgIHJlbmRlcjogZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgcyA9IHRoaXMsXG4gICAgICAgICAgICBzdGF0ZSA9IHMuc3RhdGUsXG4gICAgICAgICAgICBwcm9wcyA9IHMucHJvcHM7XG5cbiAgICAgICAgbGV0IGxldHRlcnMgPSBwcm9wcy5ib2FyZExldHRlcnMubWFwKChsZXR0ZXIsIGksIGxldHRlcnMpPT4ge1xuICAgICAgICAgICAgbGV0IGFuZ2xlID0gQXBBbmFsb2dDbG9jay5sZXR0ZXJBbmdsZShpLCBsZXR0ZXJzLmxlbmd0aCk7XG4gICAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgICAgIDxBcEFuYWxvZ0Nsb2NrTGV0dGVyIGtleT17XCJhcC1hbmFsb2ctbGV0dGVyLVwiICsgaX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXR0ZXI9e2xldHRlcn1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmdsZT17YW5nbGV9PjwvQXBBbmFsb2dDbG9ja0xldHRlcj5cbiAgICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICA8QXBDbG9jayBjbGFzc05hbWU9e2NsYXNzbmFtZXMoXCJhcC1hbmFsb2ctY2xvY2tcIiwgcHJvcHMuY2xhc3NOYW1lKX0+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJhcC1hbmFsb2ctY2xvY2stYm9hcmRcIiBzdHlsZT17e3dpZHRoOnN0YXRlLnNpemUsIGhlaWdodDpzdGF0ZS5zaXplfX0+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYXAtYW5hbG9nLWNsb2NrLWJvYXJkLWlubmVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8QXBBbmFsb2dDbG9ja0hhbmQgd2lkdGg9ezR9IGhlaWdodFJhdGU9ezAuOH0gYW5nbGU9e3N0YXRlLmhvdXJ9PjwvQXBBbmFsb2dDbG9ja0hhbmQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8QXBBbmFsb2dDbG9ja0hhbmQgd2lkdGg9ezR9IGhlaWdodFJhdGU9ezF9IGFuZ2xlPXtzdGF0ZS5taW51dGV9PjwvQXBBbmFsb2dDbG9ja0hhbmQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8QXBBbmFsb2dDbG9ja0hhbmQgd2lkdGg9ezJ9IGhlaWdodFJhdGU9ezF9IGFuZ2xlPXtzdGF0ZS5zZWNvbmR9PjwvQXBBbmFsb2dDbG9ja0hhbmQ+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICA8ZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAge2xldHRlcnN9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9BcENsb2NrPlxuICAgICAgICApO1xuICAgIH0sXG5cblxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBMaWZlY3ljbGVcbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICBjb21wb25lbnRXaWxsTW91bnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IHMgPSB0aGlzO1xuICAgICAgICBzLl9sb29waW5nID0gdHJ1ZTtcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkTW91bnQ6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgbGV0IHMgPSB0aGlzLFxuICAgICAgICAgICAgcHJvcHMgPSBzLnByb3BzO1xuXG4gICAgICAgIGZ1bmN0aW9uIF9sb29wKCkge1xuICAgICAgICAgICAgaWYgKCFzLl9sb29waW5nKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbGV0IG5vdyA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgICBzLnNldFN0YXRlKHtcbiAgICAgICAgICAgICAgICBob3VyOiBBcEFuYWxvZ0Nsb2NrLmhvdXJIYW5kQW5nbGUobm93KSxcbiAgICAgICAgICAgICAgICBtaW51dGU6IEFwQW5hbG9nQ2xvY2subWludXRlSGFuZEFuZ2xlKG5vdyksXG4gICAgICAgICAgICAgICAgc2Vjb25kOiBBcEFuYWxvZ0Nsb2NrLnNlY29uZEhhbmRBbmdsZShub3cpXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUoX2xvb3ApO1xuICAgICAgICB9XG5cbiAgICAgICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHMucmVzaXplQ2xvY2spO1xuICAgICAgICBfbG9vcCgpO1xuICAgICAgICBzLnJlc2l6ZUNsb2NrKCk7XG5cblxuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsUmVjZWl2ZVByb3BzOiBmdW5jdGlvbiAobmV4dFByb3BzKSB7XG4gICAgICAgIGxldCBzID0gdGhpcztcbiAgICB9LFxuXG4gICAgY29tcG9uZW50V2lsbFVwZGF0ZTogZnVuY3Rpb24gKG5leHRQcm9wcywgbmV4dFN0YXRlKSB7XG4gICAgICAgIGxldCBzID0gdGhpcztcbiAgICB9LFxuXG4gICAgY29tcG9uZW50RGlkVXBkYXRlOiBmdW5jdGlvbiAocHJldlByb3BzLCBwcmV2U3RhdGUpIHtcbiAgICAgICAgbGV0IHMgPSB0aGlzO1xuICAgIH0sXG5cbiAgICBjb21wb25lbnRXaWxsVW5tb3VudDogZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgcyA9IHRoaXM7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdyZXNpemUnLCBzLnJlc2l6ZUNsb2NrKTtcbiAgICAgICAgcy5fbG9vcGluZyA9IGZhbHNlO1xuICAgIH0sXG5cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vIEhlbHBlclxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgICByZXNpemVDbG9jazogZnVuY3Rpb24gKCkge1xuICAgICAgICBsZXQgcyA9IHRoaXMsXG4gICAgICAgICAgICBlbG0gPSBSZWFjdERPTS5maW5kRE9NTm9kZShzKTtcbiAgICAgICAgbGV0IHNpemUgPSBudW1jYWwubWluKGVsbS5vZmZzZXRXaWR0aCwgZWxtLm9mZnNldEhlaWdodCk7XG4gICAgICAgIHMuc2V0U3RhdGUoe1xuICAgICAgICAgICAgc2l6ZTogc2l6ZVxuICAgICAgICB9KTtcbiAgICB9XG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLyBQcml2YXRlXG4gICAgLy8tLS0tLS0tLS0tLS0tLS0tLS1cbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IEFwQW5hbG9nQ2xvY2s7XG4iXX0= |
\ | No newline at end of file |