UNPKG

16.8 kBJavaScriptView Raw
1/**
2 * Analog clock.
3 * @constructor ApAnalogClock
4 */
5
6"use strict";
7
8const 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 */
20let 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
171module.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