Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: converted component to hooks API, closes #49
- Loading branch information
1 parent
25ad0c5
commit 4a9eaa0
Showing
6 changed files
with
17 additions
and
200 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,130 +1,24 @@ | ||
import React, { Component, ReactNode } from "react"; | ||
import { tsParticles } from "@tsparticles/engine"; | ||
import React, { useEffect } from "react"; | ||
import type { IParticlesProps } from "./IParticlesProps"; | ||
import type { IParticlesState } from "./IParticlesState"; | ||
import { deepCompare } from "./Utils"; | ||
import { tsParticles, type Container } from "@tsparticles/engine"; | ||
|
||
const defaultId = "tsparticles"; | ||
function Particles(props: IParticlesProps): JSX.Element { | ||
const id = props.id ?? "tsparticles"; | ||
const [container, setContainer] = React.useState<Container | undefined>(undefined); | ||
|
||
/** | ||
* @param {{id?: string,width?: string,height?: string,options?: import("@tsparticles/engine").ISourceOptions,params?: import("@tsparticles/engine").ISourceOptions,style?: import("react").CSSProperties,className?: string,canvasClassName?: string,container?: RefObject<Container>}} | ||
*/ | ||
export default class Particles extends Component<IParticlesProps, IParticlesState> { | ||
static defaultProps: IParticlesProps = { | ||
width: "100%", | ||
height: "100%", | ||
options: {}, | ||
style: {}, | ||
url: undefined, | ||
id: defaultId, | ||
}; | ||
useEffect(() => { | ||
tsParticles.load({ id, url: props.url, options: props.options }).then(c => { | ||
setContainer(c); | ||
|
||
constructor(props: IParticlesProps) { | ||
super(props); | ||
|
||
this.state = { | ||
init: false, | ||
library: undefined, | ||
}; | ||
} | ||
|
||
destroy(): void { | ||
if (!this.state.library) { | ||
return; | ||
} | ||
|
||
this.state.library.destroy(); | ||
|
||
this.setState({ | ||
library: undefined, | ||
props.particlesLoaded?.(c); | ||
}); | ||
} | ||
|
||
shouldComponentUpdate(nextProps: Readonly<IParticlesProps>): boolean { | ||
const nextOptions = nextProps.options, | ||
currentOptions = this.props.options; | ||
|
||
return ( | ||
nextProps.url !== this.props.url || | ||
nextProps.id !== this.props.id || | ||
nextProps.canvasClassName !== this.props.canvasClassName || | ||
nextProps.className !== this.props.className || | ||
nextProps.height !== this.props.height || | ||
nextProps.width !== this.props.width || | ||
!deepCompare(nextProps.style, this.props.style) || | ||
nextProps.particlesLoaded !== this.props.particlesLoaded || | ||
!deepCompare(nextOptions, currentOptions, key => key.startsWith("_")) | ||
); | ||
} | ||
|
||
componentDidUpdate(): void { | ||
this.refresh(); | ||
} | ||
|
||
forceUpdate(): void { | ||
this.refresh().then(() => { | ||
super.forceUpdate(); | ||
}); | ||
} | ||
|
||
componentDidMount(): void { | ||
(async () => { | ||
this.setState( | ||
{ | ||
init: true, | ||
}, | ||
async () => { | ||
await this.loadParticles(); | ||
}, | ||
); | ||
})(); | ||
} | ||
|
||
componentWillUnmount(): void { | ||
this.destroy(); | ||
} | ||
|
||
render(): ReactNode { | ||
const { width, height, className, canvasClassName, id } = this.props; | ||
|
||
return ( | ||
<div className={className} id={id}> | ||
<canvas | ||
className={canvasClassName} | ||
style={{ | ||
...this.props.style, | ||
width, | ||
height, | ||
}} | ||
/> | ||
</div> | ||
); | ||
} | ||
|
||
private async refresh(): Promise<void> { | ||
this.destroy(); | ||
|
||
await this.loadParticles(); | ||
} | ||
|
||
private async loadParticles(): Promise<void> { | ||
if (!this.state.init) { | ||
return; | ||
} | ||
|
||
const id = this.props.id ?? Particles.defaultProps.id ?? defaultId, | ||
container = await tsParticles.load({ | ||
url: this.props.url, | ||
id, | ||
options: this.props.options, | ||
}); | ||
|
||
this.setState({ | ||
library: container, | ||
}); | ||
return () => { | ||
container?.destroy(); | ||
}; | ||
}, []); | ||
|
||
if (this.props.particlesLoaded) { | ||
await this.props.particlesLoaded(container); | ||
} | ||
} | ||
return <div id={id} className={props.className}></div>; | ||
} | ||
|
||
export default Particles; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters