Skip to content
This repository has been archived by the owner on Feb 23, 2022. It is now read-only.

Commit

Permalink
Merge 33c35cb into 2f23ff8
Browse files Browse the repository at this point in the history
  • Loading branch information
ragrag committed Jan 8, 2020
2 parents 2f23ff8 + 33c35cb commit ebc32e5
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 84 deletions.
77 changes: 37 additions & 40 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,10 @@ You can find some examples in the [`examples` directory](https://github.com/juli
![Stylized example][example2]
![Formatter example][example3]


[example1]: https://raw.githubusercontent.com/julienc91/react-countdown360/master/doc/01_basic_countdown.gif "Baic example"
[example2]: https://raw.githubusercontent.com/julienc91/react-countdown360/master/doc/02_stylized_countdown.gif "Stylized example"
[example3]: https://raw.githubusercontent.com/julienc91/react-countdown360/master/doc/05_custom_formatters_countdown.gif "Formatter example"


## Quickstart

Install with `npm`:
Expand All @@ -31,37 +29,37 @@ npm install react-countdown360
Render your countdown:

```js
import Countdown360 from 'react-countdown360'
import Countdown360 from 'react-countdown360';

const App = () => {
return <Countdown360 seconds={10} />
}
return <Countdown360 seconds={10} />;
};
```

## Documentation

### Props

| Name | Type | Default | Description |
|---------------------|----------|-------------------------|-------------------------------------------------|
| `seconds` | Number | - | Number of seconds for the countdown |
| `autoStart` | Boolean | `true` | Start the countdown immediatly after rendering |
| `backgroundColor` | String | `'#fff'` | Color for the center of the circle |
| `borderFillColor` | String | `'#f11'` | Color for the filled part of the border |
| `borderUnfillColor` | String | `'#e6e2e7'` | Color for the unfilled part of the border |
| `borderWidth` | Number | 20 | Width in pixels of the border |
| `clockwise` | Boolean | `false` | Select the direction of rotation you prefer |
| `fontColor` | String | `'#111'` | Font color for the label |
| `fontFamily` | String | `'sans-serif'` | The font to use for the label |
| `fontSize` | Number | 45 | Font size in pixels |
| `fontWeight` | Number | 700 | Font weight for the label |
| `onComplete` | Function | `undefined` | A callback called when the countdown is over |
| `smooth` | Boolean | `false` | Update the border once every second or smoothly |
| `startingAngle` | Number | 0 | The angle at which the countdown should start |
| `timeFormatter` | Func | `timeFormatterSeconds` | A function that returns the value to display |
| `unitFormatter` | Func | `unitFormatterSeconds` | A function that returns the unit to display |
| `width` | Number | 200 | Width in pixels of the countdown to render |

| Name | Type | Default | Description |
| ------------------- | -------- | ---------------------- | -------------------------------------------------------------- |
| `seconds` | Number | - | Number of seconds for the countdown |
| `autoStart` | Boolean | `true` | Start the countdown immediatly after rendering |
| `backgroundColor` | String | `'#fff'` | Color for the center of the circle |
| `borderFillColor` | String | `'#f11'` | Color for the filled part of the border |
| `borderUnfillColor` | String | `'#e6e2e7'` | Color for the unfilled part of the border |
| `borderWidth` | Number | 20 | Width in pixels of the border |
| `clockwise` | Boolean | `false` | Select the direction of rotation you prefer |
| `fontColor` | String | `'#111'` | Font color for the label |
| `fontFamily` | String | `'sans-serif'` | The font to use for the label |
| `fontSize` | Number | 45 | Font size in pixels |
| `fontWeight` | Number | 700 | Font weight for the label |
| `onComplete` | Function | `undefined` | A callback called when the countdown is over |
| `smooth` | Boolean | `false` | Update the border once every second or smoothly |
| `startingAngle` | Number | 0 | The angle at which the countdown should start |
| `startingSecond` | Number | undefined | The second at which the countdown should start |
| `timeFormatter` | Func | `timeFormatterSeconds` | A function that returns the value to display |
| `unitFormatter` | Func | `unitFormatterSeconds` | A function that returns the unit to display |
| `width` | Number | 200 | Width in pixels of the countdown to render |

#### Time Formatters

Expand All @@ -76,47 +74,46 @@ For instance, the following function is a time formatter that always shows a val

```js
const timeFormatterTwoDigits = timeLeft => {
return Math.round(timeLeft / 1000).toString().padStart(2, '0')
}
```
return Math.round(timeLeft / 1000)
.toString()
.padStart(2, "0");
};
```

We already provide a few time formatters that you can import from the package.

| Name | Description | Examples | Suggested unit formatter |
|-----------------------------|-----------------------------------------------|----------------------------|--------------------------|
| --------------------------- | --------------------------------------------- | -------------------------- | ------------------------ |
| `timeFormatterSeconds` | Rounded number of seconds (default behaviour) | `0`, `1`, `12` | `unitFormatterSeconds` |
| `timeFormatterDigitalClock` | `MM:SS` | `00:00`, `00:12`, `01: 59` | `unitFormatterBlank` |


#### Unit Formatters

You can also customize the unit shown on the countdown by providing a custom `unitFormatter` function.

A unit formatter is a function that takes one single argument, being the value shown on the countdown (as
A unit formatter is a function that takes one single argument, being the value shown on the countdown (as
returned by the given time formatter), and returns the unit to display.

For instance, the following function is a unit formatter to show the number of seconds in Spanish:

```js
const unitFormatterSpanishSeconds = value => {
return value.toString() === '1' ? 'segundo' : 'segundos'
}
return value.toString() === "1" ? "segundo" : "segundos";
};
```

Be careful when choosing your unit formatter that it matches the time formatter in use!

We already provide a few unit formatters that you can import from the package.

| Name | Description | Examples |
|------------------------|-----------------------|---------------------|
| ---------------------- | --------------------- | ------------------- |
| `unitFormatterSeconds` | 'second' or 'seconds' | `second`, `seconds` |
| `unitFormatterBlank` | An empty string | |



### Methods

* `start`: start or resume the countdown
* `stop`: pause the countdown
* `addSeconds (Number)`: add or remove (if negative) the given number of seconds to remaining number of seconds
* `extendTimer (Number)`: add or remove (if negative) the given number of seconds to the total number of seconds
- `start`: start or resume the countdown
- `stop`: pause the countdown
- `addSeconds (Number)`: add or remove (if negative) the given number of seconds to remaining number of seconds
- `extendTimer (Number)`: add or remove (if negative) the given number of seconds to the total number of seconds
58 changes: 47 additions & 11 deletions src/countdown360.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,14 @@ class Countdown360 extends React.Component {
constructor (props) {
super(props)
const seconds = Math.max(props.seconds, 0)
const secondsLeft =
props.startingSecond && props.startingSecond > 0
? Math.min(seconds, props.startingSecond)
: seconds

this.state = {
totalSeconds: seconds,
secondsLeft: seconds * 1000,
secondsLeft: secondsLeft * 1000,
started: false,
lastTick: null
}
Expand Down Expand Up @@ -51,7 +56,12 @@ class Countdown360 extends React.Component {
addSeconds (value) {
const { secondsLeft, totalSeconds } = this.state
value *= 1000
this.setState({ secondsLeft: Math.max(Math.min(secondsLeft + value, totalSeconds * 1000), 0) })
this.setState({
secondsLeft: Math.max(
Math.min(secondsLeft + value, totalSeconds * 1000),
0
)
})
}

start () {
Expand Down Expand Up @@ -101,8 +111,20 @@ class Countdown360 extends React.Component {

render () {
const { clockwise, smooth, startingAngle, width } = this.props
const { backgroundColor, borderUnfillColor, borderFillColor, borderWidth } = this.props
const { fontColor, fontFamily, fontSize, fontWeight, timeFormatter, unitFormatter } = this.props
const {
backgroundColor,
borderUnfillColor,
borderFillColor,
borderWidth
} = this.props
const {
fontColor,
fontFamily,
fontSize,
fontWeight,
timeFormatter,
unitFormatter
} = this.props

const { secondsLeft, totalSeconds } = this.state

Expand All @@ -114,17 +136,27 @@ class Countdown360 extends React.Component {
}

const factor = clockwise ? -1 : 1
const x = ((angle >= 180 ? (90 - (360 - angle)) : 90) * factor) + startingAngle
const y = ((angle >= 180 ? 90 : (-90 + angle)) * factor) + startingAngle
const x = (angle >= 180 ? 90 - (360 - angle) : 90) * factor + startingAngle
const y = (angle >= 180 ? 90 : -90 + angle) * factor + startingAngle

const Wrapper = styled.div`
align-items: center;
background-image: linear-gradient(${x}deg, ${angle >= 180 ? borderFillColor : borderUnfillColor} 50%, transparent 50%), linear-gradient(${y}deg, ${borderUnfillColor} 50%, ${borderFillColor} 50%);
background-image: linear-gradient(
${x}deg,
${angle >= 180 ? borderFillColor : borderUnfillColor} 50%,
transparent 50%
),
linear-gradient(
${y}deg,
${borderUnfillColor} 50%,
${borderFillColor} 50%
);
border-radius: 50%;
display: flex;
height: ${width}px;
justify-content: center;
width: ${width}px;`
width: ${width}px;
`

const Label = styled.div`
align-items: center;
Expand All @@ -141,19 +173,22 @@ class Countdown360 extends React.Component {
justify-content: center;
text-align: center;
text-transform: uppercase;
width: ${width - 2 * borderWidth}px;`
width: ${width - 2 * borderWidth}px;
`

const Unit = styled.div`
text-transform: uppercase;
font-size: ${fontSize / 3}px;`
font-size: ${fontSize / 3}px;
`

const value = timeFormatter(secondsLeft)
const unit = unitFormatter(value)

return (
<Wrapper>
<Label>
{value}<br />
{value}
<br />
<Unit>{unit}</Unit>
</Label>
</Wrapper>
Expand Down Expand Up @@ -194,6 +229,7 @@ Countdown360.propTypes = {
seconds: PropTypes.number.isRequired,
smooth: PropTypes.bool,
startingAngle: PropTypes.number,
startingSecond: PropTypes.number,
timeFormatter: PropTypes.func,
unitFormatter: PropTypes.func,
width: PropTypes.number
Expand Down

0 comments on commit ebc32e5

Please sign in to comment.