loadsnippet.tsx 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import * as React from "react";
  2. import { Observable } from "babylonjs/Misc/observable";
  3. import { PropertyChangedEvent } from "../../../../../components/propertyChangedEvent";
  4. import { Animation } from "babylonjs/Animations/animation";
  5. import { ButtonLineComponent } from "../../../lines/buttonLineComponent";
  6. import { FileButtonLineComponent } from "../../../lines/fileButtonLineComponent";
  7. import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
  8. import { LockObject } from "../lockObject";
  9. import { Tools } from "babylonjs/Misc/tools";
  10. import { GlobalState } from "../../../../globalState";
  11. import { ReadFileError } from "babylonjs/Misc/fileTools";
  12. import { IAnimatable } from "babylonjs/Animations/animatable.interface";
  13. import { TargetedAnimation } from "babylonjs/Animations/animationGroup";
  14. interface ILoadSnippetProps {
  15. animations: Animation[];
  16. onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
  17. lockObject: LockObject;
  18. globalState: GlobalState;
  19. snippetServer: string;
  20. setSnippetId: (id: string) => void;
  21. entity: IAnimatable | TargetedAnimation;
  22. setNotificationMessage: (message: string) => void;
  23. animationsLoaded: (numberOfAnimations: number) => void;
  24. }
  25. /**
  26. * Loads animation locally or from the Babylon.js Snippet Server
  27. */
  28. export class LoadSnippet extends React.Component<ILoadSnippetProps, { snippetId: string }> {
  29. private _serverAddress: string;
  30. constructor(props: ILoadSnippetProps) {
  31. super(props);
  32. this._serverAddress = this.props.snippetServer;
  33. this.state = { snippetId: "" };
  34. }
  35. change = (value: string) => {
  36. this.setState({ snippetId: value });
  37. this.props.setSnippetId(value);
  38. };
  39. loadFromFile = (file: File) => {
  40. Tools.ReadFile(
  41. file,
  42. (data) => {
  43. let decoder = new TextDecoder("utf-8");
  44. let jsonObject = JSON.parse(decoder.decode(data));
  45. var result: Animation[] = [];
  46. for (var i in jsonObject) {
  47. result.push(Animation.Parse(jsonObject[i]));
  48. }
  49. if (this.props.entity) {
  50. (this.props.entity as IAnimatable).animations = result;
  51. var e = new PropertyChangedEvent();
  52. e.object = this.props.entity;
  53. e.property = "animations";
  54. e.value = (this.props.entity as IAnimatable).animations;
  55. this.props.globalState.onPropertyChangedObservable.notifyObservers(e);
  56. this.props.animationsLoaded(result.length);
  57. }
  58. },
  59. undefined,
  60. true,
  61. (error: ReadFileError) => {
  62. console.log(error.message);
  63. }
  64. );
  65. };
  66. loadFromSnippet = () => {
  67. if (this.state.snippetId !== "") {
  68. //Notify observers
  69. Animation.CreateFromSnippetAsync(this.state.snippetId)
  70. .then((newAnimations) => {
  71. // Explore how observers are notified from snippet
  72. if (newAnimations instanceof Array) {
  73. (this.props.entity as IAnimatable).animations = newAnimations;
  74. }
  75. if (newAnimations instanceof Animation) {
  76. (this.props.entity as IAnimatable).animations?.push(newAnimations);
  77. }
  78. })
  79. .catch((err) => {
  80. this.props.setNotificationMessage(`Unable to load your animations: ${err}`);
  81. });
  82. } else {
  83. this.props.setNotificationMessage(`You need to add an snippet id`);
  84. }
  85. };
  86. render() {
  87. return (
  88. <div className="load-container">
  89. <TextInputLineComponent
  90. label="Snippet Id"
  91. lockObject={this.props.lockObject}
  92. value={this.state.snippetId}
  93. onChange={this.change}
  94. />
  95. <ButtonLineComponent label="Load from snippet server" onClick={this.loadFromSnippet} />
  96. <div className="load-browse">
  97. <p>Local File</p>
  98. <FileButtonLineComponent label="Load" onClick={this.loadFromFile} accept=".json" />
  99. </div>
  100. <div className="load-server">
  101. <p>Snippet Server: </p>&nbsp;
  102. <p> {this._serverAddress ?? "-"}</p>
  103. </div>
  104. </div>
  105. );
  106. }
  107. }