Skip to content

Commit

Permalink
feat: Add prop to draw custom confetti
Browse files Browse the repository at this point in the history
  • Loading branch information
alampros committed Mar 10, 2019
1 parent 72e7473 commit 992376b
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 23 deletions.
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,34 @@ export default () => {
| `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. |
| `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



# `drawShape()`

Draw a custom shape for a particle. If not provided, defaults to a random selection of a square, circle or strip confetto. The function is called with the canvas context as a parameter and the [Particle](src/Particle.ts) as the `this` context.

For example, to draw all spirals:

```jsx
<Confetti
drawShape={ctx => {
ctx.beginPath()
for(let i = 0; i < 22; i++) {
const angle = 0.35 * i
const x = (0.2 + (1.5 * angle)) * Math.cos(angle)
const y = (0.2 + (1.5 * angle)) * Math.sin(angle)
ctx.lineTo(x, y)
}
ctx.stroke()
ctx.closePath()
}}
/>
```
1 change: 1 addition & 0 deletions src/Confetti.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface IConfettiOptions {
confettiSource: IRect
tweenFunction: (currentTime: number, currentValue: number, targetValue: number, duration: number, s?: number) => number
tweenDuration: number
drawShape?: (context: CanvasRenderingContext2D) => void
}

export const confettiDefaults: Pick<IConfettiOptions, Exclude<keyof IConfettiOptions, 'confettiSource'>> = {
Expand Down
40 changes: 19 additions & 21 deletions src/Particle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { IConfettiOptions } from './Confetti'
export enum ParticleShape {
Cirlce = 0,
Square,
Spiral,
Strip,
}

export default class Particle {
Expand Down Expand Up @@ -46,6 +46,7 @@ export default class Particle {
wind,
friction,
opacity,
drawShape,
} = this.getOptions()
this.x += this.vx
this.y += this.vy
Expand All @@ -70,27 +71,24 @@ export default class Particle {
this.context.globalAlpha = opacity
this.context.lineCap = 'round'
this.context.lineWidth = 2
switch(this.shape) {
case ParticleShape.Cirlce: {
this.context.beginPath()
this.context.arc(0, 0, this.radius, 0, 2 * Math.PI)
this.context.fill()
break
}
case ParticleShape.Square: {
this.context.fillRect(-this.w / 2, -this.h / 2, this.w, this.h)
break
}
case ParticleShape.Spiral: {
this.context.beginPath()
for(let i = 0; i < 22; i++) {
const angle = 0.35 * i
const x = (0.2 + (1.5 * angle)) * Math.cos(angle)
const y = (0.2 + (1.5 * angle)) * Math.sin(angle)
this.context.lineTo(x, y)
if(drawShape && typeof drawShape === 'function') {
drawShape.call(this, this.context)
} else {
switch(this.shape) {
case ParticleShape.Cirlce: {
this.context.beginPath()
this.context.arc(0, 0, this.radius, 0, 2 * Math.PI)
this.context.fill()
break
}
case ParticleShape.Square: {
this.context.fillRect(-this.w / 2, -this.h / 2, this.w, this.h)
break
}
case ParticleShape.Strip: {
this.context.fillRect(-this.w / 6, -this.h / 2, this.w / 3, this.h)
break
}
this.context.stroke()
break
}
}
this.context.closePath()
Expand Down
2 changes: 1 addition & 1 deletion src/ReactConfetti.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export default class ReactConfetti extends React.Component<Props> {
function extractCanvasProps(props: Props): [Partial<IConfettiOptions>, any] {
const confettiOptions: Partial<IConfettiOptions> = {}
const rest: any = {}
const confettiOptionKeys = [...Object.keys(confettiDefaults), 'confettiSource']
const confettiOptionKeys = [...Object.keys(confettiDefaults), 'confettiSource', 'drawShape']
for(const prop in props) {
const val = props[prop as string]
if(confettiOptionKeys.includes(prop)) {
Expand Down

0 comments on commit 992376b

Please sign in to comment.