-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathReactConfetti.tsx
66 lines (60 loc) · 1.79 KB
/
ReactConfetti.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
import React, { CanvasHTMLAttributes } from 'react'
import Confetti, { IConfettiOptions, confettiDefaults } from './Confetti'
interface ComponentProps extends IConfettiOptions {
[key: string]: any
}
export type Props = ComponentProps & CanvasHTMLAttributes<HTMLCanvasElement>
export default class ReactConfetti extends React.Component<Props> {
static defaultProps = {
...confettiDefaults,
}
canvas: React.RefObject<HTMLCanvasElement> = React.createRef()
confetti?: Confetti
componentDidMount() {
if(this.canvas.current) {
const opts = extractCanvasProps(this.props)[0]
this.confetti = new Confetti(this.canvas.current, opts)
}
}
componentWillReceiveProps(nextProps: Props) {
const confettiOptions = extractCanvasProps(nextProps)[0]
if(this.confetti) {
this.confetti.options = confettiOptions as IConfettiOptions
}
}
render() {
const [ confettiOptions, passedProps ] = extractCanvasProps(this.props)
const canvasStyles = {
zIndex: 2,
position: 'absolute',
top: 0,
left: 0,
bottom: 0,
right: 0,
...passedProps.style,
}
return (
<canvas
width={confettiOptions.width}
height={confettiOptions.height}
ref={this.canvas}
{...passedProps}
style={canvasStyles}
/>
)
}
}
function extractCanvasProps(props: Props): [Partial<IConfettiOptions>, any] {
const confettiOptions: Partial<IConfettiOptions> = {}
const rest: any = {}
const confettiOptionKeys = [...Object.keys(confettiDefaults), 'confettiSource']
for(const prop in props) {
const val = props[prop as string]
if(confettiOptionKeys.includes(prop)) {
confettiOptions[prop as keyof IConfettiOptions] = val
} else {
rest[prop] = val
}
}
return [confettiOptions, rest]
}