import * as React from "react"; import { Nullable } from "babylonjs/types"; import { Observable, Observer } from "babylonjs/Misc/observable"; import { AnimationGroup } from "babylonjs/Animations/animationGroup"; import { Scene } from "babylonjs/scene"; import { PropertyChangedEvent } from "../../../../propertyChangedEvent"; import { ButtonLineComponent } from "../../../../../sharedUiComponents/lines/buttonLineComponent"; import { LineContainerComponent } from "../../../../../sharedUiComponents/lines/lineContainerComponent"; import { TextLineComponent } from "../../../../../sharedUiComponents/lines/textLineComponent"; import { SliderLineComponent } from "../../../../../sharedUiComponents/lines/sliderLineComponent"; import { LockObject } from "../../../../../sharedUiComponents/tabs/propertyGrids/lockObject"; import { GlobalState } from "../../../../globalState"; import { TextInputLineComponent } from "../../../../../sharedUiComponents/lines/textInputLineComponent"; interface IAnimationGroupGridComponentProps { globalState: GlobalState; animationGroup: AnimationGroup; scene: Scene; lockObject: LockObject; onPropertyChangedObservable?: Observable; } export class AnimationGroupGridComponent extends React.Component< IAnimationGroupGridComponentProps, { playButtonText: string; currentFrame: number } > { private _onAnimationGroupPlayObserver: Nullable>; private _onAnimationGroupPauseObserver: Nullable>; private _onBeforeRenderObserver: Nullable>; private timelineRef: React.RefObject; constructor(props: IAnimationGroupGridComponentProps) { super(props); const animationGroup = this.props.animationGroup; this.state = { playButtonText: animationGroup.isPlaying ? "Pause" : "Play", currentFrame: 0 }; this.connect(this.props.animationGroup); this._onBeforeRenderObserver = this.props.scene.onBeforeRenderObservable.add(() => { this.updateCurrentFrame(this.props.animationGroup); }); this.timelineRef = React.createRef(); } disconnect(animationGroup: AnimationGroup) { if (this._onAnimationGroupPlayObserver) { animationGroup.onAnimationGroupPlayObservable.remove(this._onAnimationGroupPlayObserver); this._onAnimationGroupPlayObserver = null; } if (this._onAnimationGroupPauseObserver) { animationGroup.onAnimationGroupPauseObservable.remove(this._onAnimationGroupPauseObserver); this._onAnimationGroupPauseObserver = null; } } connect(animationGroup: AnimationGroup) { this._onAnimationGroupPlayObserver = animationGroup.onAnimationGroupPlayObservable.add(() => { this.forceUpdate(); }); this._onAnimationGroupPauseObserver = animationGroup.onAnimationGroupPauseObservable.add(() => { this.forceUpdate(); }); this.updateCurrentFrame(animationGroup); } updateCurrentFrame(animationGroup: AnimationGroup) { var targetedAnimations = animationGroup.targetedAnimations; if (targetedAnimations.length > 0) { var runtimeAnimations = animationGroup.targetedAnimations[0].animation.runtimeAnimations; if (runtimeAnimations.length > 0) { this.setState({ currentFrame: runtimeAnimations[0].currentFrame }); } else { this.setState({ currentFrame: 0 }); } } } shouldComponentUpdate(nextProps: IAnimationGroupGridComponentProps): boolean { if (this.props.animationGroup !== nextProps.animationGroup) { this.disconnect(this.props.animationGroup); this.connect(nextProps.animationGroup); } return true; } componentWillUnmount() { this.disconnect(this.props.animationGroup); if (this._onBeforeRenderObserver) { this.props.scene.onBeforeRenderObservable.remove(this._onBeforeRenderObserver); this._onBeforeRenderObserver = null; } } playOrPause() { const animationGroup = this.props.animationGroup; if (animationGroup.isPlaying) { this.setState({ playButtonText: "Play" }); animationGroup.pause(); } else { this.setState({ playButtonText: "Pause" }); this.props.scene.animationGroups.forEach((grp) => grp.pause()); animationGroup.play(true); } } onCurrentFrameChange(value: number) { const animationGroup = this.props.animationGroup; if (!animationGroup.isPlaying) { animationGroup.play(true); animationGroup.goToFrame(value); animationGroup.pause(); } else { animationGroup.goToFrame(value); } this.setState({ currentFrame: value }); } render() { const animationGroup = this.props.animationGroup; const playButtonText = animationGroup.isPlaying ? "Pause" : "Play"; return (
this.playOrPause()} /> this.onCurrentFrameChange(value)} />
); } }