Skip to content

Commit aa998f8

Browse files
committed
Basic counter with demo
0 parents  commit aa998f8

File tree

7 files changed

+421
-0
lines changed

7 files changed

+421
-0
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/
2+
*.swp

build/react-countdown-clock.js

Lines changed: 206 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/react-countdown-clock.js.map

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
React = require 'react'
2+
3+
_radius = null
4+
_fraction = null
5+
_context = null
6+
_canvas = null
7+
8+
module.exports = React.createClass
9+
propTypes:
10+
seconds: React.PropTypes.number
11+
size: React.PropTypes.number
12+
color: React.PropTypes.string
13+
alpha: React.PropTypes.number
14+
onComplete: React.PropTypes.func
15+
16+
getDefaultProps: ->
17+
seconds: 60
18+
size: 300
19+
color: '#000'
20+
alpha: 1
21+
22+
getInitialState: ->
23+
seconds: @props.seconds
24+
25+
componentWillReceiveProps: (props) ->
26+
@setState seconds: props.seconds
27+
28+
componentWillMount: ->
29+
@_setScale()
30+
31+
componentDidMount: ->
32+
@_setupCanvas() if !_canvas
33+
@_drawTimer()
34+
@_startTimer()
35+
36+
componentDidUpdate: ->
37+
@_setScale()
38+
@_clearTimer()
39+
@_drawTimer()
40+
if @state.seconds <= 0
41+
@_handleComplete()
42+
43+
_setScale: ->
44+
_radius = @props.size / 2
45+
_fraction = 2 / @props.seconds
46+
47+
_setupCanvas: ->
48+
_canvas = @getDOMNode()
49+
_context = _canvas.getContext '2d'
50+
_context.textAlign = 'center'
51+
_context.textBaseline = 'middle'
52+
_context.font = "bold #{_radius/2}px Arial"
53+
54+
_startTimer: ->
55+
# Give it a moment to collect it's thoughts for smoother render
56+
setTimeout ( => @_tick() ), 200
57+
58+
_tick: ->
59+
start = Date.now()
60+
setTimeout ( =>
61+
duration = Date.now() - start
62+
@setState
63+
seconds: @state.seconds - duration / 1000
64+
@_tick() unless @state.seconds <= 0
65+
), 30
66+
67+
_handleComplete: ->
68+
@setState seconds: 0
69+
if @props.onComplete
70+
@props.onComplete()
71+
72+
_clearTimer: ->
73+
_context.clearRect 0, 0, _canvas.width, _canvas.height
74+
@_drawBackground()
75+
76+
_drawBackground: ->
77+
_context.beginPath()
78+
_context.globalAlpha = @props.alpha / 3
79+
_context.arc _radius, _radius, _radius, 0, Math.PI * 2, false
80+
_context.arc _radius, _radius, _radius/1.8, Math.PI * 2, 0, true
81+
_context.fill()
82+
83+
_drawTimer: ->
84+
percent = _fraction * @state.seconds + 1.5
85+
decimals = (@state.seconds <= 9.9) ? 1 : 0
86+
_context.globalAlpha = @props.alpha
87+
_context.fillStyle = @props.color
88+
_context.fillText @state.seconds.toFixed(decimals), _radius, _radius
89+
_context.beginPath()
90+
_context.arc _radius, _radius, _radius, Math.PI * 1.5, Math.PI * percent, false
91+
_context.arc _radius, _radius, _radius/1.8, Math.PI * percent, Math.PI * 1.5, true
92+
_context.fill()
93+
94+
render: ->
95+
<canvas className="react-countdown-clock" width={@props.size} height={@props.size}></canvas>

index.html

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8" />
5+
<title>react-countdown-clock</title>
6+
<style>
7+
body {
8+
background-color: #CCC;
9+
}
10+
#parappa {
11+
position: absolute;
12+
top: 50%;
13+
left: 50%;
14+
width: 300px;
15+
height: 300px;
16+
margin: -150px 0 0 -150px;
17+
}
18+
</style>
19+
</head>
20+
<body>
21+
<div id="parappa"></div>
22+
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.js"></script>
23+
<script src="//cdnjs.cloudflare.com/ajax/libs/react/0.12.2/JSXTransformer.js"></script>
24+
<script src="./build/react-countdown-clock.js"></script>
25+
<script type="text/jsx">
26+
/** @jsx React.DOM */
27+
var MAX = 30;
28+
var MIN = 5;
29+
30+
randomAmountOfSeconds = function(){
31+
return Math.floor( Math.random() * ( MAX - MIN + 1) + MIN )
32+
}
33+
34+
randomColor = function(){
35+
return '#' + ( Math.random() * 0xFFFFFF << 0 ).toString(16);
36+
}
37+
38+
Demo = React.createClass({
39+
getState: function(){
40+
return {
41+
seconds: randomAmountOfSeconds(),
42+
color: randomColor()
43+
}
44+
},
45+
getInitialState: function(){
46+
return this.getState();
47+
},
48+
handleOnComplete: function(){
49+
this.setState(this.getState());
50+
},
51+
render: function(){
52+
return <ReactCountdownClock seconds={this.state.seconds} color={this.state.color} alpha={0.9} onComplete={this.handleOnComplete} />
53+
}
54+
});
55+
56+
React.render(<Demo />, document.getElementById('parappa'))
57+
</script>
58+
</body>
59+
</html>

package.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "react-countdown-clock",
3+
"version": "1.0.0",
4+
"description": "HTML5 canvas countdown clock React component",
5+
"main": "build/react-countdown-clock.js",
6+
"repository": {
7+
"type": "git",
8+
"url": "https://github.com/pughpugh/react-countdown-clock"
9+
},
10+
"keywords": [
11+
"react-component",
12+
"react",
13+
"countdown",
14+
"timer",
15+
"canvas"
16+
],
17+
"author": "Hugh Gallagher <[email protected]> (http://www.hughgallagher.co.uk/)",
18+
"license": "ISC",
19+
"bugs": {
20+
"url": "https://github.com/pughpugh/react-countdown-clock/issues"
21+
},
22+
"homepage": "https://github.com/pughpugh/react-countdown-clock",
23+
"devDependencies": {
24+
"cjsx-loader": "^1.1.0",
25+
"coffee-loader": "^0.7.2",
26+
"coffee-script": "^1.8.0",
27+
"webpack": "^1.4.15"
28+
}
29+
}

0 commit comments

Comments
 (0)