Skip to content

Commit

Permalink
Finish typescript rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
alampros committed Mar 6, 2019
1 parent 157a4e8 commit f040e0e
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 469 deletions.
46 changes: 31 additions & 15 deletions src/Confetti.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,46 +38,62 @@ export default class Confetti {
this.canvas = canvas
const ctx = this.canvas.getContext('2d')
if(!ctx) {
throw new Error('Could not get canvas context');
throw new Error('Could not get canvas context')
}
this.context = ctx

this.generator = new ParticleGenerator(this.canvas, () => (this.options as IConfettiOptions))
this.options = opts
this.update()
}
canvas: HTMLCanvasElement
context: CanvasRenderingContext2D
_options!: IConfettiOptions
generator: ParticleGenerator

get options(): Partial<IConfettiOptions> {
return this._options
}
set options(opts: Partial<IConfettiOptions>) {
const lastRunState = this._options && this._options.run
this.setOptionsWithDefaults(opts)
if(this.generator) {
Object.assign(this.generator, this.options.confettiSource)
}
if(typeof opts.run === 'boolean' && opts.run && lastRunState === false) {
this.update()
}
}

setOptionsWithDefaults = (opts: Partial<IConfettiOptions>) => {
const computedConfettiDefaults = {
confettiSource: {
x: 0,
y: 0,
w: canvas.width,
w: this.canvas.width,
h: 0,
}
},
}
this.options = { ...computedConfettiDefaults, ...confettiDefaults, ...opts }
console.log('creating new Confetti with opts:', this.options)
this.generator = new ParticleGenerator(this.canvas, this.options)
this.update()
this._options = { ...computedConfettiDefaults, ...confettiDefaults, ...opts }
Object.assign(this, opts.confettiSource)
}
canvas: HTMLCanvasElement
context: CanvasRenderingContext2D
options: IConfettiOptions
generator: ParticleGenerator

update = () => {
const {
options: {
run,
numberOfPieces,
},
canvas,
context,
} = this
if(run) {
this.generator.options = this.options
context.fillStyle = 'white'
context.clearRect(0, 0, canvas.width, canvas.height)
}
if(this.generator.animate()) {
requestAnimationFrame(this.update)
} else {
this.options.run = false
this._options.run = false
}
}

}
16 changes: 8 additions & 8 deletions src/Particle.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { IRect } from './Rect'
import { randomRange, randomInt, degreesToRads } from './utils';
import { IConfettiOptions } from './confetti';
import { randomRange, randomInt, degreesToRads } from './utils'
import { IConfettiOptions } from './confetti'

export enum ParticleShape {
Cirlce = 0,
Expand All @@ -9,9 +8,10 @@ export enum ParticleShape {
}

export default class Particle {
constructor(context: CanvasRenderingContext2D, options: IConfettiOptions, x: number, y: number) {
constructor(context: CanvasRenderingContext2D, getOptions: () => IConfettiOptions, x: number, y: number) {
this.getOptions = getOptions
const { colors } = this.getOptions()
this.context = context
this.options = options
this.x = x
this.y = y
this.w = randomRange(5, 20)
Expand All @@ -22,11 +22,10 @@ export default class Particle {
this.shape = randomInt(0, 2)
this.angle = degreesToRads(randomRange(0, 360))
this.angularSpin = randomRange(-0.2, 0.2)
this.color = options.colors[Math.floor(Math.random() * options.colors.length)]
this.color = colors[Math.floor(Math.random() * colors.length)]
this.rotateY = randomRange(0, 1)
}
context: CanvasRenderingContext2D
options: IConfettiOptions
radius: number
x: number
y: number
Expand All @@ -39,14 +38,15 @@ export default class Particle {
angularSpin: number
color: string
rotateY: number
getOptions: () => IConfettiOptions

update() {
const {
gravity,
wind,
friction,
opacity,
} = this.options
} = this.getOptions()
this.x += this.vx
this.y += this.vy
this.vy += gravity
Expand Down
34 changes: 13 additions & 21 deletions src/ParticleGenerator.ts
Original file line number Diff line number Diff line change
@@ -1,64 +1,56 @@
import { IConfettiOptions } from './Confetti'
import { IRect } from './Rect'
import Particle from './Particle'
import { randomRange } from './utils';
import { randomRange } from './utils'

export interface IParticleGenerator extends IRect {
removeParticleAt: (index: number) => void
getParticle: () => void
animate: () => void
animate: () => boolean
particles: Particle[]
particlesGenerated: number
}

export default class ParticleGenerator implements IParticleGenerator {
constructor(canvas: HTMLCanvasElement, options: IConfettiOptions) {
constructor(canvas: HTMLCanvasElement, getOptions: () => IConfettiOptions) {
this.canvas = canvas
const ctx = this.canvas.getContext('2d')
if(!ctx) {
throw new Error('Could not get canvas context');
throw new Error('Could not get canvas context')
}
this.context = ctx
this.options = options
this.getOptions = getOptions
}
canvas: HTMLCanvasElement
context: CanvasRenderingContext2D
_options!: IConfettiOptions
getOptions: () => IConfettiOptions
x: number = 0
y: number = 0
w: number = 0
h: number = 0
particles: Particle[] = []
particlesGenerated: number = 0

get options(): IConfettiOptions {
return this._options
}
set options(opts: IConfettiOptions) {
this._options = opts
Object.assign(this, opts.confettiSource)
}

removeParticleAt = (i: number) => {
this.particles.splice(i, 1)
}

getParticle = () => {
const newParticleX = randomRange(this.x, this.w + this.x)
const newParticleY = randomRange(this.y, this.h + this.y)
return new Particle(this.context, this.options, newParticleX, newParticleY)
return new Particle(this.context, this.getOptions, newParticleX, newParticleY)
}

animate = () => {
animate = (): boolean => {
const {
canvas,
options: {
run,
recycle,
numberOfPieces,
},
particlesGenerated,
} = this
const {
run,
recycle,
numberOfPieces,
} = this.getOptions()
if(!run) {
return false
}
Expand Down
8 changes: 5 additions & 3 deletions src/ReactConfetti.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export type Props = ComponentProps & CanvasHTMLAttributes<HTMLCanvasElement>

export default class ReactConfetti extends React.Component<Props> {
static defaultProps = {
...confettiDefaults
...confettiDefaults,
}

canvas: React.RefObject<HTMLCanvasElement> = React.createRef()
Expand All @@ -22,7 +22,9 @@ export default class ReactConfetti extends React.Component<Props> {
}
componentWillReceiveProps(nextProps: Props) {
const confettiOptions = extractCanvasProps(nextProps)[0]
this.confetti.options = confettiOptions
if(this.confetti) {
this.confetti.options = confettiOptions as IConfettiOptions
}
}

render() {
Expand All @@ -34,7 +36,7 @@ export default class ReactConfetti extends React.Component<Props> {
left: 0,
bottom: 0,
right: 0,
...passedProps.style
...passedProps.style,
}
return (
<canvas
Expand Down
Loading

0 comments on commit f040e0e

Please sign in to comment.