Skip to content

Commit

Permalink
feat: Add onConfettiComplete param
Browse files Browse the repository at this point in the history
With stories.
  • Loading branch information
alampros committed Apr 17, 2019
1 parent a8bd0c2 commit 8af89f2
Show file tree
Hide file tree
Showing 7 changed files with 58 additions and 23 deletions.
1 change: 1 addition & 0 deletions .storybook/addons.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import '@storybook/addon-knobs/register'
import '@storybook/addon-storysource/register'
import '@storybook/addon-actions/register'
1 change: 1 addition & 0 deletions .storybook/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { addParameters, configure } from '@storybook/react'
import { create } from '@storybook/theming'
addParameters({
options: {
sortStoriesByKind: true,
theme: create({
base: 'light',
brandTitle: 'React Confetti',
Expand Down
33 changes: 17 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,23 @@ export default () => {

## Props

| Property | Type | Default | Description |
| ---------------- | --------------------- | --- | --- |
| `width` | `Number` | `window.innerWidth \|\| 300` | Width of the `<canvas>` element. |
| `height` | `Number` | `window.innerHeight \|\| 200` | Height of the `<canvas>` element. |
| `numberOfPieces` | `Number` | 200 | Number of confetti pieces at one time. |
| `confettiSource` | `{ x: Number, y: Number, w: Number, h: Number }` | `{x: 0, y: 0, w: canvas.width, h:0}` | Rectangle where the confetti should spawn. Default is across the top. |
| `friction` | `Number` | 0.99 | |
| `wind` | `Number` | 0 | |
| `gravity` | `Number` | 0.1 | |
| `colors` | `String[]` | `['#f44336'`</br>`'#e91e63'`</br>`'#9c27b0'`</br>`'#673ab7'`</br>`'#3f51b5'`</br>`'#2196f3'`</br>`'#03a9f4'`</br>`'#00bcd4'`</br>`'#009688'`</br>`'#4CAF50'`</br>`'#8BC34A'`</br>`'#CDDC39'`</br>`'#FFEB3B'`</br>`'#FFC107'`</br>`'#FF9800'`</br>`'#FF5722'`</br>`'#795548']`</br> | All available Colors for the confetti pieces. |
| `opacity` | `Number` | 1.0 | |
| `recycle` | `Bool` | true | Keep spawning confetti after `numberOfPieces` pieces have been shown. |
| `run` | `Bool` | true | Run the animation loop |
| `tweenDuration` | `Number` | 5000 | How fast the confetti is added |
| `tweenFunction` | `(currentTime: number, currentValue: number, targetValue: number, duration: number, s?: number) => number` | easeInOutQuad | See [tween-functions](https://github.com/chenglou/tween-functions) |
| `drawShape` | `(context: CanvasRenderingContext2D) => void` | `undefined` | See below
| Property | Type | Default | Description |
| ---------------- | --------------------- | --- | --- |
| `width` | `Number` | `window.innerWidth \|\| 300` | Width of the `<canvas>` element. |
| `height` | `Number` | `window.innerHeight \|\| 200` | Height of the `<canvas>` element. |
| `numberOfPieces` | `Number` | 200 | Number of confetti pieces at one time. |
| `confettiSource` | `{ x: Number, y: Number, w: Number, h: Number }` | `{x: 0, y: 0, w: canvas.width, h:0}` | Rectangle where the confetti should spawn. Default is across the top. |
| `friction` | `Number` | 0.99 | |
| `wind` | `Number` | 0 | |
| `gravity` | `Number` | 0.1 | |
| `colors` | `String[]` | `['#f44336'`</br>`'#e91e63'`</br>`'#9c27b0'`</br>`'#673ab7'`</br>`'#3f51b5'`</br>`'#2196f3'`</br>`'#03a9f4'`</br>`'#00bcd4'`</br>`'#009688'`</br>`'#4CAF50'`</br>`'#8BC34A'`</br>`'#CDDC39'`</br>`'#FFEB3B'`</br>`'#FFC107'`</br>`'#FF9800'`</br>`'#FF5722'`</br>`'#795548']`</br> | All available Colors for the confetti pieces. |
| `opacity` | `Number` | 1.0 | |
| `recycle` | `Bool` | true | Keep spawning confetti after `numberOfPieces` pieces have been shown. |
| `run` | `Bool` | true | Run the animation loop |
| `tweenDuration` | `Number` | 5000 | How fast the confetti is added |
| `tweenFunction` | `(currentTime: number, currentValue: number, targetValue: number, duration: number, s?: number) => number` | easeInOutQuad | See [tween-functions](https://github.com/chenglou/tween-functions) |
| `drawShape` | `(context: CanvasRenderingContext2D) => void` | `undefined` | See below |
| `onConfettiComplete` | `(confetti: Confetti) => void` | `undefined` | Called when all confetti has fallen off-canvas. |



Expand Down
20 changes: 20 additions & 0 deletions src/Confetti.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export interface IConfettiOptions {
* Function to draw your own confetti shapes.
*/
drawShape?: (context: CanvasRenderingContext2D) => void
/**
* Function called when all confetti has fallen off-canvas.
*/
onConfettiComplete?: (confettiInstance?: Confetti) => void
}

export const confettiDefaults: Pick<IConfettiOptions, Exclude<keyof IConfettiOptions, 'confettiSource'>> = {
Expand Down Expand Up @@ -128,9 +132,13 @@ export class Confetti {
}
set options(opts: Partial<IConfettiOptions>) {
const lastRunState = this._options && this._options.run
const lastRecycleState = this._options && this._options.recycle
this.setOptionsWithDefaults(opts)
if(this.generator) {
Object.assign(this.generator, this.options.confettiSource)
if(typeof opts.recycle === 'boolean' && opts.recycle && lastRecycleState === false) {
this.generator.lastNumberOfPieces = this.generator.particles.length
}
}
if(typeof opts.run === 'boolean' && opts.run && lastRunState === false) {
this.update()
Expand All @@ -154,6 +162,7 @@ export class Confetti {
const {
options: {
run,
onConfettiComplete,
},
canvas,
context,
Expand All @@ -165,10 +174,21 @@ export class Confetti {
if(this.generator.animate()) {
this.rafId = requestAnimationFrame(this.update)
} else {
if(onConfettiComplete && typeof onConfettiComplete === 'function' && this.generator.particlesGenerated > 0) {
onConfettiComplete.call(this, this)
}
this._options.run = false
}
}

reset = () => {
if(this.generator && this.generator.particlesGenerated > 0) {
this.generator.particlesGenerated = 0
this.generator.particles = []
this.generator.lastNumberOfPieces = 0
}
}

stop = () => {
this.options = { run: false }
if(this.rafId) {
Expand Down
2 changes: 1 addition & 1 deletion src/ReactConfetti.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export class ReactConfetti extends Component<Props> {
function extractCanvasProps(props: Partial<IConfettiOptions> | any): [Partial<IConfettiOptions>, Partial<CanvasHTMLAttributes<HTMLCanvasElement>>] {
const confettiOptions: Partial<IConfettiOptions> = {}
const rest: any = {}
const confettiOptionKeys = [...Object.keys(confettiDefaults), 'confettiSource', 'drawShape']
const confettiOptionKeys = [...Object.keys(confettiDefaults), 'confettiSource', 'drawShape', 'onConfettiComplete']
for(const prop in props) {
const val = props[prop as string]
if(confettiOptionKeys.includes(prop)) {
Expand Down
2 changes: 2 additions & 0 deletions stories/index.story.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import SizedConfetti from './SizedConfetti'
import { withKnobs, boolean, number } from '@storybook/addon-knobs'
import { storiesOf } from '@storybook/react'
import { withInfo } from '@storybook/addon-info'
import { action } from '@storybook/addon-actions'

import ReactConfetti from '../src/ReactConfetti'

Expand Down Expand Up @@ -54,6 +55,7 @@ storiesOf('Props|Demos', module)
max: 100,
step: 1,
}) / 100}
onConfettiComplete={action('Confetti Complete')}
/>
))
.add('Custom Source', () => (
Expand Down
Loading

0 comments on commit 8af89f2

Please sign in to comment.