import * as React from "react"; import { Observable, AnimationGroup, Scene, Nullable, Observer } from "babylonjs"; import { PropertyChangedEvent } from "../../../propertyChangedEvent"; import { ButtonLineComponent } from "../../lines/buttonLineComponent"; import { LineContainerComponent } from "../../lineContainerComponent"; import { TextLineComponent } from "../../lines/textLineComponent"; import { SliderLineComponent } from "../../lines/sliderLineComponent"; interface IAnimationGroupGridComponentProps { animationGroup: AnimationGroup, scene: Scene, onPropertyChangedObservable?: Observable } export class AnimationGroupGridComponent extends React.Component { private _onAnimationGroupPlayObserver: Nullable>; private _onAnimationGroupPauseObserver: Nullable>; private _onBeforeRenderObserver: Nullable>; constructor(props: IAnimationGroupGridComponentProps) { super(props); const animationGroup = this.props.animationGroup; this.state = { playButtonText: animationGroup.isPlaying ? "Pause" : "Play", currentFrame: 0 }; } 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; } componentWillMount() { this.connect(this.props.animationGroup); this._onBeforeRenderObserver = this.props.scene.onBeforeRenderObservable.add(() => { if (this.props.animationGroup.isPlaying) { this.updateCurrentFrame(this.props.animationGroup); } }); } 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)} />
); } }