73 lines
No EOL
2.1 KiB
TypeScript
73 lines
No EOL
2.1 KiB
TypeScript
"use client";
|
|
// Utility component for executing animations
|
|
|
|
import anime, { AnimeParams } from "animejs";
|
|
import React from "react";
|
|
|
|
interface IProps {
|
|
params: AnimeParams;
|
|
children: React.ReactNode;
|
|
}
|
|
|
|
interface IState {
|
|
scopeState: string;
|
|
}
|
|
|
|
export default class Anime extends React.Component<IProps, IState> {
|
|
private anime: anime.AnimeInstance | null;
|
|
|
|
constructor(props: IProps) {
|
|
super(props);
|
|
this.state = {
|
|
scopeState: "",
|
|
};
|
|
|
|
this.anime = null;
|
|
}
|
|
|
|
private applyDescendantSelector(selector: string): string {
|
|
console.log("Applying descendant selector to: " + selector);
|
|
return selector.split(",").map((s) => {
|
|
return "." + this.state.scopeState + ' ' + s;
|
|
}).join(", ");
|
|
}
|
|
|
|
componentDidMount(): void {
|
|
const scope = "anime-scope-" + Math.random().toString(36).substring(4);
|
|
this.setState({
|
|
scopeState: scope,
|
|
}, () => {
|
|
console.log("Anime scope state: " + this.state.scopeState);
|
|
const postTargets = '.' + this.state.scopeState;
|
|
console.log("Targets: " + postTargets);
|
|
|
|
// Update all params targets CSS selectors to include a descendant selector
|
|
if (this.props.params.targets !== undefined) {
|
|
// Identify if is single or is array (type AnimeTarget)
|
|
this.props.params.targets = this.applyDescendantSelector(this.props.params.targets?.toString() as string);
|
|
|
|
console.log("Updated targets: " + this.props.params.targets);
|
|
|
|
} else {
|
|
this.props.params.targets = postTargets;
|
|
}
|
|
|
|
this.anime = anime({
|
|
...this.props.params,
|
|
});
|
|
});
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<div>
|
|
<style>
|
|
{`.${this.state.scopeState} {}`}
|
|
</style>
|
|
<div className={this.state.scopeState}>
|
|
{this.props.children}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
} |