Last active
May 13, 2016 09:53
-
-
Save alihammad-gist/29a1ef4027335b0be08afcecfc62b883 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <reference path="typings/react/react.d.ts" /> | |
/// <reference path="typings/react/react-dom.d.ts" /> | |
declare var React: typeof __React; | |
declare var ReactDOM: typeof __React.__DOM; | |
class App extends React.Component<{}, {}> { | |
render() { | |
return ( | |
<div> | |
<p>{tlPercentage(10, 7.5)}</p> | |
<Timer | |
duration={5} | |
title='Hello timer' | |
onFinish={() => console.log('timer finised')} | |
/> | |
</div> | |
); | |
} | |
} | |
type timerProps = { | |
title: string | |
duration: number // seconds | |
onFinish: () => any | |
} | |
type timerState = { | |
elapsedTime?: number | |
interval?: number | |
} | |
class Timer extends React.Component<timerProps, timerState> { | |
constructor(props) { | |
super(props); | |
this.state = { | |
elapsedTime: 0, | |
interval: undefined, | |
} | |
} | |
render() { | |
return ( | |
<svg width="320" height="320"> | |
<circle | |
className='inner-circle' | |
cx='160' | |
cy='160' | |
r='150' | |
fill='#00897b' | |
stroke='#00564d' | |
strokeWidth="10" | |
/> | |
<circle | |
className='inner-circle' | |
cx='160' | |
cy='160' | |
r='150' | |
fill='none' | |
stroke='#7ee510' | |
strokeWidth="8" | |
strokeDasharray={`${calcCircumference(150)}`} | |
strokeDashoffset={-`${calcCircumference(150) - calcDashoffset(tlPercentage( | |
this.props.duration, | |
this.state.elapsedTime | |
), 150)}`} | |
transform='rotate(-90 160 160)' | |
shapeRendering="optimizeQuality" | |
strokeLinecap="rounded" | |
/> | |
{React.createElement('foreginObject', { | |
width: '100%', | |
height: '100%' | |
}, [ | |
React.createFactory('div')({ | |
xmlns: "http://www.w3.org/1999/xhtml" | |
}, [ | |
<h3>hello</h3> | |
]), | |
])} | |
</svg> | |
); | |
} | |
tick() { | |
const elapsed = this.state.elapsedTime; | |
if (elapsed >= this.props.duration) { | |
this.clearInterval(); | |
this.props.onFinish(); | |
} else { | |
this.setState({ | |
elapsedTime: elapsed + 1 | |
}); | |
} | |
} | |
componentWillMount() { | |
this.setState({ | |
interval: setInterval(() => { | |
this.tick(); | |
}, 1000) // one second tick | |
}); | |
} | |
componentWillUnmount() { | |
this.clearInterval(); | |
} | |
clearInterval() { | |
clearInterval(this.state.interval); | |
this.setState({ | |
interval: undefined, | |
}) | |
} | |
} | |
// turns time in seconds to human readable form | |
function formatTime(time: number): string { | |
let mins: number = 0, | |
secs: number = 0; | |
if (time > 60) { | |
mins = Math.floor(time / 60); | |
time %= 60; | |
} | |
if (time > 1) { | |
secs = time; | |
} | |
return ( | |
`${mins < 10 ? `0${mins}` : mins}:` + | |
`${secs < 10 ? `0${secs}` : secs}` | |
); | |
} | |
// percentage of time left | |
// duration, timeElapsed - times in seconds | |
function tlPercentage(duration: number, timeElapsed: number) :number { | |
if (timeElapsed >= duration) { | |
return 0; | |
} | |
return ( (duration - timeElapsed) / duration ) * 100; | |
} | |
function calcDashoffset(tlPercentage :number, radius :number) :number { | |
const circum = calcCircumference(radius); | |
return (tlPercentage/100) * circum; | |
} | |
function calcCircumference(radius: number) :number { | |
return 2 * Math.PI * radius; | |
} | |
ReactDOM.render(<App />, document.getElementById('root')); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment