Bläddra i källkod

Merge pull request #8454 from BabylonJS/master

Deploy nightly
sebavan 5 år sedan
förälder
incheckning
e636e868ee

+ 48 - 48
dist/preview release/gui/babylon.gui.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-gui"] = factory(require("babylonjs"));
 	else
 		root["BABYLON"] = root["BABYLON"] || {}, root["BABYLON"]["GUI"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_observable__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -400,7 +400,7 @@ module.exports = g;
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedDynamicTextureInstrumentation", function() { return AdvancedDynamicTextureInstrumentation; });
-/* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/perfCounter */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/perfCounter */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__);
 
 /**
@@ -543,7 +543,7 @@ var AdvancedDynamicTextureInstrumentation = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedDynamicTexture", function() { return AdvancedDynamicTexture; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _controls_container__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controls/container */ "./2D/controls/container.ts");
 /* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./style */ "./2D/style.ts");
@@ -1515,7 +1515,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _textBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./textBlock */ "./2D/controls/textBlock.ts");
 /* harmony import */ var _image__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./image */ "./2D/controls/image.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__);
 
 
@@ -1747,7 +1747,7 @@ babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_5__["_TypeStore"].RegisteredTy
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Checkbox", function() { return Checkbox; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
@@ -1930,7 +1930,7 @@ babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorPicker", function() { return ColorPicker; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _inputText__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./inputText */ "./2D/controls/inputText.ts");
@@ -3319,7 +3319,7 @@ babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Container", function() { return Container; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../measure */ "./2D/measure.ts");
@@ -3734,7 +3734,7 @@ babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredTypes
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Control", function() { return Control; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../measure */ "./2D/measure.ts");
@@ -5660,7 +5660,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DisplayGrid", function() { return DisplayGrid; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -5893,7 +5893,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__);
 
 
@@ -5990,7 +5990,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__);
 
 
@@ -6448,7 +6448,7 @@ babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__["_TypeStore"].RegisteredTypes[
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Image", function() { return Image; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 
@@ -7375,7 +7375,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputPassword", function() { return InputPassword; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _inputText__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./inputText */ "./2D/controls/inputText.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -7414,7 +7414,7 @@ babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTy
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputText", function() { return InputText; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -8427,7 +8427,7 @@ babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].RegisteredT
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Line", function() { return Line; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -8698,7 +8698,7 @@ babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].Registere
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiLine", function() { return MultiLine; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/abstractMesh */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/abstractMesh */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _multiLinePoint__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../multiLinePoint */ "./2D/multiLinePoint.ts");
@@ -8968,7 +8968,7 @@ babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__["_TypeStore"].Registe
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RadioButton", function() { return RadioButton; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
@@ -9175,7 +9175,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Rectangle", function() { return Rectangle; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -9325,7 +9325,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _scrollViewerWindow__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./scrollViewerWindow */ "./2D/controls/scrollViewers/scrollViewerWindow.ts");
 /* harmony import */ var _sliders_scrollBar__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../sliders/scrollBar */ "./2D/controls/sliders/scrollBar.ts");
 /* harmony import */ var _sliders_imageScrollBar__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../sliders/imageScrollBar */ "./2D/controls/sliders/imageScrollBar.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_7__);
 
 
@@ -10948,7 +10948,7 @@ var SelectionPanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseSlider", function() { return BaseSlider; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -11278,7 +11278,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _baseSlider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./baseSlider */ "./2D/controls/sliders/baseSlider.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../measure */ "./2D/measure.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_3__);
 
 
@@ -11871,7 +11871,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Slider", function() { return Slider; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _baseSlider__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./baseSlider */ "./2D/controls/sliders/baseSlider.ts");
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__);
 
 
@@ -12126,7 +12126,7 @@ babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_2__["_TypeStore"].RegisteredTy
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StackPanel", function() { return StackPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
@@ -12394,7 +12394,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextWrapping", function() { return TextWrapping; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextBlock", function() { return TextBlock; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
@@ -12857,7 +12857,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeyPropertySet", function() { return KeyPropertySet; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VirtualKeyboard", function() { return VirtualKeyboard; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
 /* harmony import */ var _button__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./button */ "./2D/controls/button.ts");
@@ -13246,7 +13246,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector2WithInfo", function() { return Vector2WithInfo; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Matrix2D", function() { return Matrix2D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -13471,7 +13471,7 @@ var Matrix2D = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Measure", function() { return Measure; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 
 var tmpRect = [
@@ -13620,7 +13620,7 @@ var Measure = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiLinePoint", function() { return MultiLinePoint; });
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./valueAndUnit */ "./2D/valueAndUnit.ts");
 
@@ -13763,7 +13763,7 @@ var MultiLinePoint = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Style", function() { return Style; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./valueAndUnit */ "./2D/valueAndUnit.ts");
 
@@ -14069,7 +14069,7 @@ var ValueAndUnit = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "XmlLoader", function() { return XmlLoader; });
-/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/typeStore */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_typeStore__WEBPACK_IMPORTED_MODULE_0__);
 
 /**
@@ -14388,7 +14388,7 @@ var XmlLoader = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AbstractButton3D", function() { return AbstractButton3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control3D */ "./3D/controls/control3D.ts");
 
@@ -14431,7 +14431,7 @@ var AbstractButton3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Button3D", function() { return Button3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _abstractButton3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./abstractButton3D */ "./3D/controls/abstractButton3D.ts");
 /* harmony import */ var _2D_advancedDynamicTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../2D/advancedDynamicTexture */ "./2D/advancedDynamicTexture.ts");
@@ -14612,7 +14612,7 @@ var Button3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Container3D", function() { return Container3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control3D */ "./3D/controls/control3D.ts");
 
@@ -14769,7 +14769,7 @@ var Container3D = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Control3D", function() { return Control3D; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _vector3WithInfo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../vector3WithInfo */ "./3D/vector3WithInfo.ts");
 
@@ -15175,7 +15175,7 @@ var Control3D = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CylinderPanel", function() { return CylinderPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -15261,7 +15261,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HolographicButton", function() { return HolographicButton; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _button3D__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./button3D */ "./3D/controls/button3D.ts");
-/* harmony import */ var babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Materials/standardMaterial */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Materials/standardMaterial */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_standardMaterial__WEBPACK_IMPORTED_MODULE_2__);
 /* harmony import */ var _materials_fluentMaterial__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../materials/fluentMaterial */ "./3D/materials/fluentMaterial.ts");
 /* harmony import */ var _2D_controls_stackPanel__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../2D/controls/stackPanel */ "./2D/controls/stackPanel.ts");
@@ -15755,7 +15755,7 @@ var MeshButton3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlanePanel", function() { return PlanePanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
@@ -15810,7 +15810,7 @@ var PlanePanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScatterPanel", function() { return ScatterPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -15937,7 +15937,7 @@ var ScatterPanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpherePanel", function() { return SpherePanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -16023,7 +16023,7 @@ var SpherePanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StackPanel3D", function() { return StackPanel3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 
@@ -16148,7 +16148,7 @@ var StackPanel3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VolumeBasedPanel", function() { return VolumeBasedPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 
@@ -16339,7 +16339,7 @@ var VolumeBasedPanel = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GUI3DManager", function() { return GUI3DManager; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _controls_container3D__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./controls/container3D */ "./3D/controls/container3D.ts");
 
@@ -16606,7 +16606,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FluentMaterialDefines", function() { return FluentMaterialDefines; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FluentMaterial", function() { return FluentMaterial; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _shaders_fluent_vertex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./shaders/fluent.vertex */ "./3D/materials/shaders/fluent.vertex.ts");
 /* harmony import */ var _shaders_fluent_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./shaders/fluent.fragment */ "./3D/materials/shaders/fluent.fragment.ts");
@@ -16929,7 +16929,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fluentPixelShader", function() { return fluentPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'fluentPixelShader';
@@ -16951,7 +16951,7 @@ var fluentPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fluentVertexShader", function() { return fluentVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'fluentVertexShader';
@@ -16974,7 +16974,7 @@ var fluentVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector3WithInfo", function() { return Vector3WithInfo; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Maths/math.vector");
+/* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math.vector */ "babylonjs/Misc/observable");
 /* harmony import */ var babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -17276,14 +17276,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Maths/math.vector":
+/***/ "babylonjs/Misc/observable":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math_vector__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_observable__;
 
 /***/ })
 

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 1
dist/preview release/gui/babylon.gui.js.map


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 293 - 72
dist/preview release/inspector/babylon.inspector.bundle.max.js


Filskillnaden har hållts tillbaka eftersom den är för stor
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 27 - 0
dist/preview release/inspector/babylon.inspector.d.ts

@@ -638,25 +638,38 @@ declare module INSPECTOR {
         selected: BABYLON.IAnimationKey | null;
         currentFrame: number;
         onCurrentFrameChange: (frame: number) => void;
+        onAnimationLimitChange: (limit: number) => void;
         dragKeyframe: (frame: number, index: number) => void;
         playPause: (direction: number) => void;
         isPlaying: boolean;
+        animationLimit: number;
+        fps: number;
     }
     export class Timeline extends React.Component<ITimelineProps, {
         selected: BABYLON.IAnimationKey;
         activeKeyframe: number | null;
+        start: number;
+        end: number;
+        scrollWidth: number | undefined;
+        selectionLength: number[];
     }> {
         readonly _frames: object[];
         private _scrollable;
         private _scrollbarHandle;
+        private _scrollContainer;
         private _direction;
         private _scrolling;
         private _shiftX;
+        private _active;
         constructor(props: ITimelineProps);
+        componentDidMount(): void;
+        calculateScrollWidth(start: number, end: number): number | undefined;
         playBackwards(event: React.MouseEvent<HTMLDivElement>): void;
         play(event: React.MouseEvent<HTMLDivElement>): void;
         pause(event: React.MouseEvent<HTMLDivElement>): void;
         handleInputChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        setCurrentFrame(event: React.MouseEvent<HTMLDivElement>): void;
+        handleLimitChange(event: React.ChangeEvent<HTMLInputElement>): void;
         nextFrame(event: React.MouseEvent<HTMLDivElement>): void;
         previousFrame(event: React.MouseEvent<HTMLDivElement>): void;
         nextKeyframe(event: React.MouseEvent<HTMLDivElement>): void;
@@ -674,6 +687,12 @@ declare module INSPECTOR {
         scrollDrag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
         scrollDragEnd(e: React.TouchEvent<HTMLDivElement>): void;
         scrollDragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        moveScrollbar(pageX: number): void;
+        resizeScrollbarRight(clientX: number): void;
+        resizeScrollbarLeft(clientX: number): void;
+        range(start: number, end: number): number[];
+        getKeyframe(frame: number): false | BABYLON.IAnimationKey | undefined;
+        getCurrentFrame(frame: number): boolean;
         render(): JSX.Element;
     }
 }
@@ -738,6 +757,7 @@ declare module INSPECTOR {
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
         setNotificationMessage: (message: string) => void;
         changed: () => void;
+        fps: number;
     }
     export class AddAnimation extends React.Component<IAddAnimationProps, {
         animationName: string;
@@ -878,6 +898,7 @@ declare module INSPECTOR {
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
         setNotificationMessage: (message: string) => void;
         selectAnimation: (selected: BABYLON.Animation, axis?: SelectedCoordinate) => void;
+        setFps: (fps: number) => void;
         globalState: GlobalState;
         snippetServer: string;
     }
@@ -890,10 +911,12 @@ declare module INSPECTOR {
         animationsCount: number;
         framesPerSecond: number;
         snippetId: string;
+        loopMode: number;
     }> {
         constructor(props: IEditorControlsProps);
         animationAdded(): void;
         recountAnimations(): number;
+        changeLoopBehavior(): void;
         handleTabs(tab: number): void;
         handleChangeFps(fps: number): void;
         emptiedList(): void;
@@ -941,6 +964,8 @@ declare module INSPECTOR {
         isPlaying: boolean;
         selectedPathData: ICurveData[] | undefined;
         selectedCoordinate: number;
+        animationLimit: number;
+        fps: number;
     }> {
         private _snippetUrl;
         private _heightScale;
@@ -1030,11 +1055,13 @@ declare module INSPECTOR {
          * This section controls the timeline.
          */
         changeCurrentFrame(frame: number): void;
+        changeAnimationLimit(limit: number): void;
         updateFrameInKeyFrame(frame: number, index: number): void;
         playPause(direction: number): void;
         moveFrameTo(e: React.MouseEvent<SVGRectElement, MouseEvent>): void;
         registerObs(): void;
         componentWillUnmount(): void;
+        isCurrentFrame(frame: number): boolean;
         render(): JSX.Element;
     }
 }

+ 54 - 0
dist/preview release/inspector/babylon.inspector.module.d.ts

@@ -719,25 +719,38 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         selected: IAnimationKey | null;
         currentFrame: number;
         onCurrentFrameChange: (frame: number) => void;
+        onAnimationLimitChange: (limit: number) => void;
         dragKeyframe: (frame: number, index: number) => void;
         playPause: (direction: number) => void;
         isPlaying: boolean;
+        animationLimit: number;
+        fps: number;
     }
     export class Timeline extends React.Component<ITimelineProps, {
         selected: IAnimationKey;
         activeKeyframe: number | null;
+        start: number;
+        end: number;
+        scrollWidth: number | undefined;
+        selectionLength: number[];
     }> {
         readonly _frames: object[];
         private _scrollable;
         private _scrollbarHandle;
+        private _scrollContainer;
         private _direction;
         private _scrolling;
         private _shiftX;
+        private _active;
         constructor(props: ITimelineProps);
+        componentDidMount(): void;
+        calculateScrollWidth(start: number, end: number): number | undefined;
         playBackwards(event: React.MouseEvent<HTMLDivElement>): void;
         play(event: React.MouseEvent<HTMLDivElement>): void;
         pause(event: React.MouseEvent<HTMLDivElement>): void;
         handleInputChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        setCurrentFrame(event: React.MouseEvent<HTMLDivElement>): void;
+        handleLimitChange(event: React.ChangeEvent<HTMLInputElement>): void;
         nextFrame(event: React.MouseEvent<HTMLDivElement>): void;
         previousFrame(event: React.MouseEvent<HTMLDivElement>): void;
         nextKeyframe(event: React.MouseEvent<HTMLDivElement>): void;
@@ -755,6 +768,12 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         scrollDrag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
         scrollDragEnd(e: React.TouchEvent<HTMLDivElement>): void;
         scrollDragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        moveScrollbar(pageX: number): void;
+        resizeScrollbarRight(clientX: number): void;
+        resizeScrollbarLeft(clientX: number): void;
+        range(start: number, end: number): number[];
+        getKeyframe(frame: number): false | IAnimationKey | undefined;
+        getCurrentFrame(frame: number): boolean;
         render(): JSX.Element;
     }
 }
@@ -827,6 +846,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
         setNotificationMessage: (message: string) => void;
         changed: () => void;
+        fps: number;
     }
     export class AddAnimation extends React.Component<IAddAnimationProps, {
         animationName: string;
@@ -998,6 +1018,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
         setNotificationMessage: (message: string) => void;
         selectAnimation: (selected: Animation, axis?: SelectedCoordinate) => void;
+        setFps: (fps: number) => void;
         globalState: GlobalState;
         snippetServer: string;
     }
@@ -1010,10 +1031,12 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         animationsCount: number;
         framesPerSecond: number;
         snippetId: string;
+        loopMode: number;
     }> {
         constructor(props: IEditorControlsProps);
         animationAdded(): void;
         recountAnimations(): number;
+        changeLoopBehavior(): void;
         handleTabs(tab: number): void;
         handleChangeFps(fps: number): void;
         emptiedList(): void;
@@ -1075,6 +1098,8 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
         isPlaying: boolean;
         selectedPathData: ICurveData[] | undefined;
         selectedCoordinate: number;
+        animationLimit: number;
+        fps: number;
     }> {
         private _snippetUrl;
         private _heightScale;
@@ -1164,11 +1189,13 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/ani
          * This section controls the timeline.
          */
         changeCurrentFrame(frame: number): void;
+        changeAnimationLimit(limit: number): void;
         updateFrameInKeyFrame(frame: number, index: number): void;
         playPause(direction: number): void;
         moveFrameTo(e: React.MouseEvent<SVGRectElement, MouseEvent>): void;
         registerObs(): void;
         componentWillUnmount(): void;
+        isCurrentFrame(frame: number): boolean;
         render(): JSX.Element;
     }
 }
@@ -4213,25 +4240,38 @@ declare module INSPECTOR {
         selected: BABYLON.IAnimationKey | null;
         currentFrame: number;
         onCurrentFrameChange: (frame: number) => void;
+        onAnimationLimitChange: (limit: number) => void;
         dragKeyframe: (frame: number, index: number) => void;
         playPause: (direction: number) => void;
         isPlaying: boolean;
+        animationLimit: number;
+        fps: number;
     }
     export class Timeline extends React.Component<ITimelineProps, {
         selected: BABYLON.IAnimationKey;
         activeKeyframe: number | null;
+        start: number;
+        end: number;
+        scrollWidth: number | undefined;
+        selectionLength: number[];
     }> {
         readonly _frames: object[];
         private _scrollable;
         private _scrollbarHandle;
+        private _scrollContainer;
         private _direction;
         private _scrolling;
         private _shiftX;
+        private _active;
         constructor(props: ITimelineProps);
+        componentDidMount(): void;
+        calculateScrollWidth(start: number, end: number): number | undefined;
         playBackwards(event: React.MouseEvent<HTMLDivElement>): void;
         play(event: React.MouseEvent<HTMLDivElement>): void;
         pause(event: React.MouseEvent<HTMLDivElement>): void;
         handleInputChange(event: React.ChangeEvent<HTMLInputElement>): void;
+        setCurrentFrame(event: React.MouseEvent<HTMLDivElement>): void;
+        handleLimitChange(event: React.ChangeEvent<HTMLInputElement>): void;
         nextFrame(event: React.MouseEvent<HTMLDivElement>): void;
         previousFrame(event: React.MouseEvent<HTMLDivElement>): void;
         nextKeyframe(event: React.MouseEvent<HTMLDivElement>): void;
@@ -4249,6 +4289,12 @@ declare module INSPECTOR {
         scrollDrag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
         scrollDragEnd(e: React.TouchEvent<HTMLDivElement>): void;
         scrollDragEnd(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
+        moveScrollbar(pageX: number): void;
+        resizeScrollbarRight(clientX: number): void;
+        resizeScrollbarLeft(clientX: number): void;
+        range(start: number, end: number): number[];
+        getKeyframe(frame: number): false | BABYLON.IAnimationKey | undefined;
+        getCurrentFrame(frame: number): boolean;
         render(): JSX.Element;
     }
 }
@@ -4313,6 +4359,7 @@ declare module INSPECTOR {
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
         setNotificationMessage: (message: string) => void;
         changed: () => void;
+        fps: number;
     }
     export class AddAnimation extends React.Component<IAddAnimationProps, {
         animationName: string;
@@ -4453,6 +4500,7 @@ declare module INSPECTOR {
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
         setNotificationMessage: (message: string) => void;
         selectAnimation: (selected: BABYLON.Animation, axis?: SelectedCoordinate) => void;
+        setFps: (fps: number) => void;
         globalState: GlobalState;
         snippetServer: string;
     }
@@ -4465,10 +4513,12 @@ declare module INSPECTOR {
         animationsCount: number;
         framesPerSecond: number;
         snippetId: string;
+        loopMode: number;
     }> {
         constructor(props: IEditorControlsProps);
         animationAdded(): void;
         recountAnimations(): number;
+        changeLoopBehavior(): void;
         handleTabs(tab: number): void;
         handleChangeFps(fps: number): void;
         emptiedList(): void;
@@ -4516,6 +4566,8 @@ declare module INSPECTOR {
         isPlaying: boolean;
         selectedPathData: ICurveData[] | undefined;
         selectedCoordinate: number;
+        animationLimit: number;
+        fps: number;
     }> {
         private _snippetUrl;
         private _heightScale;
@@ -4605,11 +4657,13 @@ declare module INSPECTOR {
          * This section controls the timeline.
          */
         changeCurrentFrame(frame: number): void;
+        changeAnimationLimit(limit: number): void;
         updateFrameInKeyFrame(frame: number, index: number): void;
         playPause(direction: number): void;
         moveFrameTo(e: React.MouseEvent<SVGRectElement, MouseEvent>): void;
         registerObs(): void;
         componentWillUnmount(): void;
+        isCurrentFrame(frame: number): boolean;
         render(): JSX.Element;
     }
 }

+ 1 - 1
dist/preview release/what's new.md

@@ -9,7 +9,7 @@
 - Reflection probes can now be used to give accurate shading with PBR ([CraigFeldpsar](https://github.com/craigfeldspar) and ([Sebavan](https://github.com/sebavan/)))
 - Added SubSurfaceScattering on PBR materials ([CraigFeldpsar](https://github.com/craigfeldspar) and ([Sebavan](https://github.com/sebavan/)))
 - Added editing of PBR materials, Post processes and Particle fragment shaders in the node material editor ([Popov72](https://github.com/Popov72))
-- Added Curve editor to manage entity's animations and edit animation groups in Inspector ([pixelspace](https://github.com/devpixelspace))
+- Added Curve editor to manage selected entity's animations and edit animation groups in Inspector ([pixelspace](https://github.com/devpixelspace))
 - Added support in `ShadowGenerator` for fast fake soft transparent shadows ([Popov72](https://github.com/Popov72))
 - Added support for **thin instances** for faster mesh instances. [Doc](https://doc.babylonjs.com/how_to/how_to_use_thininstances) ([Popov72](https://github.com/Popov72))
 

+ 2 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/animations/addAnimation.tsx

@@ -15,6 +15,7 @@ interface IAddAnimationProps {
   onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
   setNotificationMessage: (message: string) => void;
   changed: () => void;
+  fps: number;
 }
 
 export class AddAnimation extends React.Component<
@@ -214,7 +215,7 @@ export class AddAnimation extends React.Component<
           let animation = new Animation(
             this.state.animationName,
             this.state.animationTargetProperty,
-            30,
+            this.props.fps,
             animationDataType
           );
 

+ 53 - 8
inspector/src/components/actionTabs/tabs/propertyGrids/animations/animationCurveEditorComponent.tsx

@@ -68,6 +68,8 @@ export class AnimationCurveEditorComponent extends React.Component<
     isPlaying: boolean;
     selectedPathData: ICurveData[] | undefined;
     selectedCoordinate: number;
+    animationLimit: number;
+    fps: number;
   }
 > {
   private _snippetUrl = 'https://snippet.babylonjs.com';
@@ -150,7 +152,7 @@ export class AnimationCurveEditorComponent extends React.Component<
           (this._canvasLength * 10)
         : 0,
       frameAxisLength: new Array(this._canvasLength).fill(0).map((s, i) => {
-        return { value: i * 10, label: i * 10 };
+        return { value: i * 10, label: i };
       }),
       valueAxisLength: new Array(10).fill(0).map((s, i) => {
         return { value: i * 10, label: valueInd[i] };
@@ -162,6 +164,8 @@ export class AnimationCurveEditorComponent extends React.Component<
       isPlaying: this.isAnimationPlaying(),
       selectedPathData: initialPathData,
       selectedCoordinate: 0,
+      animationLimit: 120,
+      fps: 0,
     };
   }
 
@@ -184,7 +188,6 @@ export class AnimationCurveEditorComponent extends React.Component<
    */
   zoom(e: React.WheelEvent<HTMLDivElement>) {
     e.nativeEvent.stopImmediatePropagation();
-    //console.log(e.deltaY);
     let scaleX = 1;
     if (Math.sign(e.deltaY) === -1) {
       scaleX = this.state.scale - 0.01;
@@ -197,7 +200,7 @@ export class AnimationCurveEditorComponent extends React.Component<
 
   setAxesLength() {
     let length = 20;
-    let newlength = Math.round(this._canvasLength * this.state.scale); // Check Undefined, or NaN
+    let newlength = Math.round(this._canvasLength * this.state.scale);
     if (!isNaN(newlength) || newlength !== undefined) {
       length = newlength;
     }
@@ -211,9 +214,9 @@ export class AnimationCurveEditorComponent extends React.Component<
     }
 
     let valueLines = Math.round((this.state.scale * this._heightScale) / 10);
-    console.log(highestFrame);
+
     let newFrameLength = new Array(length).fill(0).map((s, i) => {
-      return { value: i * 10, label: i * 10 };
+      return { value: i * 10, label: i };
     });
     let newValueLength = new Array(valueLines).fill(0).map((s, i) => {
       return { value: i * 10, label: this.getValueLabel(i * 10) };
@@ -1294,6 +1297,12 @@ export class AnimationCurveEditorComponent extends React.Component<
     }
   }
 
+  changeAnimationLimit(limit: number) {
+    this.setState({
+      animationLimit: limit,
+    });
+  }
+
   updateFrameInKeyFrame(frame: number, index: number) {
     if (this.state && this.state.selected) {
       let animation = this.state.selected;
@@ -1382,6 +1391,10 @@ export class AnimationCurveEditorComponent extends React.Component<
     }
   }
 
+  isCurrentFrame(frame: number) {
+    return this.state.currentFrame === frame;
+  }
+
   render() {
     return (
       <div id='animation-curve-editor'>
@@ -1427,6 +1440,9 @@ export class AnimationCurveEditorComponent extends React.Component<
               }}
               globalState={this.props.globalState}
               snippetServer={this._snippetUrl}
+              setFps={(fps: number) => {
+                this.setState({ fps: fps });
+              }}
             />
 
             <div
@@ -1469,7 +1485,7 @@ export class AnimationCurveEditorComponent extends React.Component<
                     <rect
                       x='-4%'
                       y='0%'
-                      width='5%'
+                      width='4%'
                       height='101%'
                       fill='#222'
                     ></rect>
@@ -1508,11 +1524,35 @@ export class AnimationCurveEditorComponent extends React.Component<
                         x={f.value}
                         y='0'
                         dx='2px'
-                        style={{ fontSize: `${0.2 * this.state.scale}em` }}
+                        style={{ fontSize: `${0.17 * this.state.scale}em` }}
                       >
-                        {f.value}
+                        {f.label}
                       </text>
                       <line x1={f.value} y1='0' x2={f.value} y2='5%'></line>
+
+                      {this.isCurrentFrame(f.label) ? (
+                        <svg>
+                          <line
+                            x1={f.value}
+                            y1='0'
+                            x2={f.value}
+                            y2='40'
+                            style={{
+                              stroke: 'rgba(18, 80, 107, 0.26)',
+                              strokeWidth: 6,
+                            }}
+                          />
+                        </svg>
+                      ) : null}
+
+                      {f.value % this.state.fps === 0 && f.value !== 0 ? (
+                        <line
+                          x1={f.value}
+                          y1='-100'
+                          x2={f.value}
+                          y2='5%'
+                        ></line>
+                      ) : null}
                     </svg>
                   ))}
                 </SvgDraggableArea>
@@ -1541,8 +1581,13 @@ export class AnimationCurveEditorComponent extends React.Component<
               onCurrentFrameChange={(frame: number) =>
                 this.changeCurrentFrame(frame)
               }
+              onAnimationLimitChange={(limit: number) =>
+                this.changeAnimationLimit(limit)
+              }
+              animationLimit={this.state.animationLimit}
               keyframes={this.state.selected && this.state.selected.getKeys()}
               selected={this.state.selected && this.state.selected.getKeys()[0]}
+              fps={this.state.fps}
             ></Timeline>
           </div>
         </div>

+ 24 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/animations/curveEditor.scss

@@ -2,6 +2,7 @@
   background-color: rgb(51, 51, 51);
 
   font-family: acumin-pro-condensed;
+  background-color: #333333;
 
   .last {
     margin-left: 3px;
@@ -505,7 +506,7 @@
     align-items: flex-start;
     justify-content: flex-start;
     flex-direction: column;
-    height: 462px;
+    height: 465px;
 
     .row {
       width: 1024px;
@@ -533,12 +534,12 @@
         height: 2.5rem;
 
         .display-line {
-          width: 75vw;
           height: 40px;
           overflow: hidden;
           margin-right: 0px;
           padding-left: 10px;
           padding-right: 10px;
+          width: 782px;
 
           &::-webkit-scrollbar {
             height: 0.4em;
@@ -558,6 +559,9 @@
           width: 60px;
           margin-left: 10px;
           margin-right: 10px;
+          position: absolute;
+          right: 9px;
+          bottom: 11px;
 
           input {
             text-align: center;
@@ -589,6 +593,8 @@
             height: 25px;
             display: flex;
             align-items: center;
+            padding-left: 2px;
+            padding-right: 2px;
             .handle {
               display: flex;
               flex-direction: row;
@@ -607,6 +613,21 @@
                 display: flex;
                 align-items: center;
                 cursor: pointer;
+                .text {
+                  pointer-events: none;
+                }
+              }
+
+              .left-draggable,
+              .right-draggable {
+                display: flex;
+                align-items: center;
+                pointer-events: none;
+                &:active {
+                  .grabber {
+                    background-color: #555555;
+                  }
+                }
               }
 
               .left-grabber {
@@ -634,7 +655,7 @@
         }
 
         .timeline-wrapper {
-          margin-top: -40px;
+          margin-top: -45px;
           margin-left: -2px;
         }
 

+ 33 - 9
inspector/src/components/actionTabs/tabs/propertyGrids/animations/editorControls.tsx

@@ -22,6 +22,7 @@ interface IEditorControlsProps {
   onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
   setNotificationMessage: (message: string) => void;
   selectAnimation: (selected: Animation, axis?: SelectedCoordinate) => void;
+  setFps: (fps: number) => void;
   globalState: GlobalState;
   snippetServer: string;
 }
@@ -37,6 +38,7 @@ export class EditorControls extends React.Component<
     animationsCount: number;
     framesPerSecond: number;
     snippetId: string;
+    loopMode: number;
   }
 > {
   constructor(props: IEditorControlsProps) {
@@ -50,6 +52,7 @@ export class EditorControls extends React.Component<
       isSaveTabOpen: false,
       isLoadTabOpen: false,
       isLoopActive: false,
+      loopMode: Animation.ANIMATIONLOOPMODE_CYCLE,
       animationsCount: count,
       framesPerSecond: 60,
       snippetId: '',
@@ -69,6 +72,25 @@ export class EditorControls extends React.Component<
     return (this.props.entity as IAnimatable).animations?.length ?? 0;
   }
 
+  changeLoopBehavior() {
+    let loopMode = this.state.loopMode;
+    const animation = this.props.selected;
+    if (loopMode === 2) {
+      loopMode = Animation.ANIMATIONLOOPMODE_CYCLE;
+    } else {
+      loopMode = Animation.ANIMATIONLOOPMODE_CONSTANT;
+    }
+    if (animation) {
+      // Notify observers
+      animation.loopMode = loopMode;
+    }
+
+    this.setState({
+      isLoopActive: !this.state.isLoopActive,
+      loopMode: loopMode,
+    });
+  }
+
   handleTabs(tab: number) {
     let state = {
       isAnimationTabOpen: true,
@@ -116,6 +138,7 @@ export class EditorControls extends React.Component<
   }
 
   handleChangeFps(fps: number) {
+    this.props.setFps(fps);
     this.setState({ framesPerSecond: fps });
   }
 
@@ -155,12 +178,14 @@ export class EditorControls extends React.Component<
             icon='medium load'
             onClick={() => this.handleTabs(1)}
           ></IconButtonLineComponent>
-          <IconButtonLineComponent
-            active={this.state.isSaveTabOpen}
-            tooltip='Save Animation'
-            icon='medium save'
-            onClick={() => this.handleTabs(2)}
-          ></IconButtonLineComponent>
+          {this.state.animationsCount === 0 ? null : (
+            <IconButtonLineComponent
+              active={this.state.isSaveTabOpen}
+              tooltip='Save Animation'
+              icon='medium save'
+              onClick={() => this.handleTabs(2)}
+            ></IconButtonLineComponent>
+          )}
           {this.state.animationsCount === 0 ? null : (
             <IconButtonLineComponent
               active={this.state.isEditTabOpen}
@@ -190,9 +215,7 @@ export class EditorControls extends React.Component<
                   ? 'loop-active last'
                   : 'loop-inactive last'
               }`}
-              onClick={() => {
-                this.setState({ isLoopActive: !this.state.isLoopActive });
-              }}
+              onClick={() => this.changeLoopBehavior()}
             ></IconButtonLineComponent>
           ) : null}
         </div>
@@ -208,6 +231,7 @@ export class EditorControls extends React.Component<
             }}
             changed={() => this.animationAdded()}
             onPropertyChangedObservable={this.props.onPropertyChangedObservable}
+            fps={this.state.framesPerSecond}
           />
         )}
 

+ 1 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/animations/graphActionsBar.tsx

@@ -56,7 +56,7 @@ export class GraphActionsBar extends React.Component<IGraphActionsBarProps> {
             onClick={this.props.addKeyframe}
           />
           <IconButtonLineComponent
-            tooltip={'Remove Keyframe'}
+            tooltip={'Frame selected keyframes'}
             icon='frame'
             onClick={this.props.removeKeyframe}
           />

+ 340 - 81
inspector/src/components/actionTabs/tabs/propertyGrids/animations/timeline.tsx

@@ -7,31 +7,82 @@ interface ITimelineProps {
   selected: IAnimationKey | null;
   currentFrame: number;
   onCurrentFrameChange: (frame: number) => void;
+  onAnimationLimitChange: (limit: number) => void;
   dragKeyframe: (frame: number, index: number) => void;
   playPause: (direction: number) => void;
   isPlaying: boolean;
+  animationLimit: number;
+  fps: number;
 }
 
 export class Timeline extends React.Component<
   ITimelineProps,
-  { selected: IAnimationKey; activeKeyframe: number | null }
+  {
+    selected: IAnimationKey;
+    activeKeyframe: number | null;
+    start: number;
+    end: number;
+    scrollWidth: number | undefined;
+    selectionLength: number[];
+  }
 > {
   readonly _frames: object[] = Array(300).fill({});
   private _scrollable: React.RefObject<HTMLDivElement>;
   private _scrollbarHandle: React.RefObject<HTMLDivElement>;
+  private _scrollContainer: React.RefObject<HTMLDivElement>;
   private _direction: number;
   private _scrolling: boolean;
   private _shiftX: number;
+  private _active: string = '';
+
   constructor(props: ITimelineProps) {
     super(props);
-    if (this.props.selected !== null) {
-      this.state = { selected: this.props.selected, activeKeyframe: null };
-    }
+
     this._scrollable = React.createRef();
     this._scrollbarHandle = React.createRef();
+    this._scrollContainer = React.createRef();
     this._direction = 0;
     this._scrolling = false;
     this._shiftX = 0;
+
+    if (this.props.selected !== null) {
+      this.state = {
+        selected: this.props.selected,
+        activeKeyframe: null,
+        start: 0,
+        end: Math.round(this.props.animationLimit / 2),
+        scrollWidth: this.calculateScrollWidth(
+          0,
+          Math.round(this.props.animationLimit / 2)
+        ),
+        selectionLength: this.range(
+          0,
+          Math.round(this.props.animationLimit / 2)
+        ),
+      };
+    }
+  }
+
+  componentDidMount() {
+    this.setState({
+      scrollWidth: this.calculateScrollWidth(this.state.start, this.state.end),
+    });
+  }
+
+  calculateScrollWidth(start: number, end: number) {
+    if (this._scrollContainer.current && this.props.animationLimit !== 0) {
+      const containerWidth = this._scrollContainer.current.clientWidth;
+      const scrollFrameLimit = this.props.animationLimit;
+      const scrollFrameLength = end - start;
+      const widthPercentage = (scrollFrameLength * 100) / scrollFrameLimit;
+      const scrollPixelWidth = (widthPercentage * containerWidth) / 100;
+      if (scrollPixelWidth === Infinity || scrollPixelWidth > containerWidth) {
+        return containerWidth;
+      }
+      return scrollPixelWidth;
+    } else {
+      return undefined;
+    }
   }
 
   playBackwards(event: React.MouseEvent<HTMLDivElement>) {
@@ -53,6 +104,38 @@ export class Timeline extends React.Component<
     event.preventDefault();
   }
 
+  setCurrentFrame(event: React.MouseEvent<HTMLDivElement>) {
+    event.preventDefault();
+    if (this._scrollable.current) {
+      const containerWidth = this._scrollable.current?.clientWidth;
+      const unit = Math.round(
+        containerWidth / this.state.selectionLength.length
+      );
+      const frame = Math.round((event.clientX - 233) / unit) + this.state.start;
+      this.props.onCurrentFrameChange(frame);
+    }
+  }
+
+  handleLimitChange(event: React.ChangeEvent<HTMLInputElement>) {
+    event.preventDefault();
+    let newLimit = parseInt(event.target.value);
+    if (isNaN(newLimit)) {
+      newLimit = 0;
+    }
+    this.setState(
+      {
+        end: newLimit,
+        selectionLength: this.range(this.state.start, newLimit),
+      },
+      () => {
+        this.setState({
+          scrollWidth: this.calculateScrollWidth(this.state.start, newLimit),
+        });
+      }
+    );
+    this.props.onAnimationLimitChange(newLimit);
+  }
+
   nextFrame(event: React.MouseEvent<HTMLDivElement>) {
     event.preventDefault();
     this.props.onCurrentFrameChange(this.props.currentFrame + 1);
@@ -163,11 +246,33 @@ export class Timeline extends React.Component<
   scrollDragStart(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
   scrollDragStart(e: any) {
     e.preventDefault();
-    if ((e.target.class = 'scrollbar') && this._scrollbarHandle.current) {
-      this._scrolling = true;
+    if (e.target.className === 'scrollbar') {
+      if ((e.target.class = 'scrollbar') && this._scrollbarHandle.current) {
+        this._scrolling = true;
+        this._shiftX =
+          e.clientX -
+          this._scrollbarHandle.current.getBoundingClientRect().left;
+        this._scrollbarHandle.current.style.left =
+          e.pageX - this._shiftX + 'px';
+      }
+    }
+
+    if (
+      e.target.className === 'left-grabber' &&
+      this._scrollbarHandle.current
+    ) {
+      this._active = 'leftDraggable';
+      this._shiftX =
+        e.clientX - this._scrollbarHandle.current.getBoundingClientRect().left;
+    }
+
+    if (
+      e.target.className === 'right-grabber' &&
+      this._scrollbarHandle.current
+    ) {
+      this._active = 'rightDraggable';
       this._shiftX =
         e.clientX - this._scrollbarHandle.current.getBoundingClientRect().left;
-      this._scrollbarHandle.current.style.left = e.pageX - this._shiftX + 'px';
     }
   }
 
@@ -175,12 +280,16 @@ export class Timeline extends React.Component<
   scrollDrag(e: React.MouseEvent<HTMLDivElement, MouseEvent>): void;
   scrollDrag(e: any) {
     e.preventDefault();
-    if (this._scrolling && this._scrollbarHandle.current) {
-      let moved = e.pageX - this._shiftX;
-      if (moved > 233 && moved < 630) {
-        this._scrollbarHandle.current.style.left = moved + 'px';
-        (this._scrollable.current as HTMLDivElement).scrollLeft = moved + 10;
-      }
+    if (e.target.className === 'scrollbar') {
+      this.moveScrollbar(e.pageX);
+    }
+
+    if (this._active === 'leftDraggable') {
+      this.resizeScrollbarLeft(e.clientX);
+    }
+
+    if (this._active === 'rightDraggable') {
+      this.resizeScrollbarRight(e.clientX);
     }
   }
 
@@ -189,9 +298,111 @@ export class Timeline extends React.Component<
   scrollDragEnd(e: any) {
     e.preventDefault();
     this._scrolling = false;
+    this._active = '';
     this._shiftX = 0;
   }
 
+  moveScrollbar(pageX: number) {
+    if (
+      this._scrolling &&
+      this._scrollbarHandle.current &&
+      this._scrollContainer.current
+    ) {
+      const moved = pageX - this._shiftX;
+      const scrollContainerWith = this._scrollContainer.current.clientWidth;
+      const startPixel = moved - 233;
+      const limitRight =
+        scrollContainerWith - (this.state.scrollWidth || 0) - 5;
+
+      if (moved > 233 && startPixel < limitRight) {
+        this._scrollbarHandle.current.style.left = moved + 'px';
+        (this._scrollable.current as HTMLDivElement).scrollLeft = moved + 10;
+
+        const startPixelPercent = (startPixel * 100) / scrollContainerWith;
+
+        const selectionStartFrame = Math.round(
+          (startPixelPercent * this.props.animationLimit) / 100
+        );
+
+        const selectionEndFrame =
+          this.state.selectionLength.length + selectionStartFrame;
+
+        this.setState({
+          start: selectionStartFrame,
+          end: selectionEndFrame,
+          selectionLength: this.range(selectionStartFrame, selectionEndFrame),
+        });
+      }
+    }
+  }
+
+  resizeScrollbarRight(clientX: number) {
+    if (this._scrollContainer.current && this._scrollbarHandle.current) {
+      const moving =
+        clientX - this._scrollbarHandle.current.getBoundingClientRect().left;
+
+      const containerWidth = this.state.scrollWidth ?? 0;
+      const resizePercentage = (100 * Math.abs(moving)) / containerWidth;
+      const frameChange = (resizePercentage * this.state.end) / 100;
+      const framesTo = Math.round(frameChange);
+
+      this.setState({
+        end: framesTo,
+        scrollWidth: this.calculateScrollWidth(this.state.start, framesTo),
+        selectionLength: this.range(this.state.start, framesTo),
+      });
+    }
+  }
+
+  resizeScrollbarLeft(clientX: number) {
+    if (this._scrollContainer.current && this._scrollbarHandle.current) {
+      const moving =
+        clientX - this._scrollbarHandle.current.getBoundingClientRect().left;
+      const scrollContainerWith = this._scrollContainer.current.clientWidth;
+      const pixelFrameRatio = scrollContainerWith / this.props.animationLimit;
+      const containerWidth = this.state.scrollWidth ?? 0;
+      const resizePercentage = (100 * Math.abs(moving)) / containerWidth;
+
+      const frameChange = (resizePercentage * this.state.end) / 100;
+
+      let framesTo;
+      if (Math.sign(moving) === 1) {
+        framesTo = this.state.start + Math.round(frameChange);
+      } else {
+        framesTo = this.state.start - Math.round(frameChange);
+      }
+      let Toleft = framesTo * pixelFrameRatio + 233;
+
+      this._scrollbarHandle.current.style.left = Toleft + 'px';
+
+      this.setState({
+        start: framesTo,
+        scrollWidth: this.calculateScrollWidth(framesTo, this.state.end),
+        selectionLength: this.range(framesTo, this.state.end),
+      });
+    }
+  }
+
+  range(start: number, end: number) {
+    return Array.from({ length: end - start }, (_, i) => start + i * 1);
+  }
+
+  getKeyframe(frame: number) {
+    if (this.props.keyframes) {
+      return this.props.keyframes.find((x) => x.frame === frame);
+    } else {
+      return false;
+    }
+  }
+
+  getCurrentFrame(frame: number) {
+    if (this.props.currentFrame === frame) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
   render() {
     return (
       <>
@@ -206,10 +417,17 @@ export class Timeline extends React.Component<
             scrollable={this._scrollable}
           />
           <div className='timeline-wrapper'>
-            <div ref={this._scrollable} className='display-line'>
+            <div
+              ref={this._scrollable}
+              className='display-line'
+              onClick={(e) => this.setCurrentFrame(e)}
+            >
               <svg
-                viewBox='0 0 2010 40'
-                style={{ width: 2000, height: 40, backgroundColor: '#222222' }}
+                style={{
+                  width: '100%',
+                  height: 40,
+                  backgroundColor: '#222222',
+                }}
                 onMouseMove={(e) => this.drag(e)}
                 onTouchMove={(e) => this.drag(e)}
                 onTouchStart={(e) => this.dragStart(e)}
@@ -219,101 +437,142 @@ export class Timeline extends React.Component<
                 onMouseLeave={(e) => this.dragEnd(e)}
                 onDragStart={() => false}
               >
-                <line
-                  x1={this.props.currentFrame * 10}
-                  y1='0'
-                  x2={this.props.currentFrame * 10}
-                  y2='40'
-                  style={{ stroke: '#12506b', strokeWidth: 6 }}
-                />
-
-                {this._frames.map((frame, i) => {
+                {this.state.selectionLength.map((frame, i) => {
                   return (
-                    <svg key={`tl_${i}`}>
-                      {i % 5 === 0 ? (
+                    <svg key={`tl_${frame}`}>
+                      {
                         <>
                           <text
-                            x={i * 5 - 3}
+                            x={
+                              (i * 100) / this.state.selectionLength.length +
+                              '%'
+                            }
                             y='18'
                             style={{ fontSize: 10, fill: '#555555' }}
                           >
-                            {i}
+                            {frame}
                           </text>
                           <line
-                            x1={i * 5}
+                            x1={
+                              (i * 100) / this.state.selectionLength.length +
+                              '%'
+                            }
                             y1='22'
-                            x2={i * 5}
+                            x2={
+                              (i * 100) / this.state.selectionLength.length +
+                              '%'
+                            }
                             y2='40'
                             style={{ stroke: '#555555', strokeWidth: 0.5 }}
                           />
+
+                          {this.getCurrentFrame(frame) ? (
+                            <svg
+                              x={
+                                this._scrollable.current
+                                  ? this._scrollable.current.clientWidth /
+                                    this.state.selectionLength.length /
+                                    2
+                                  : 1
+                              }
+                            >
+                              <line
+                                x1={
+                                  (i * 100) /
+                                    this.state.selectionLength.length +
+                                  '%'
+                                }
+                                y1='0'
+                                x2={
+                                  (i * 100) /
+                                    this.state.selectionLength.length +
+                                  '%'
+                                }
+                                y2='40'
+                                style={{
+                                  stroke: 'rgba(18, 80, 107, 0.26)',
+                                  strokeWidth: this._scrollable.current
+                                    ? this._scrollable.current.clientWidth /
+                                      this.state.selectionLength.length
+                                    : 1,
+                                }}
+                              />
+                            </svg>
+                          ) : null}
+
+                          {this.getKeyframe(frame) ? (
+                            <svg key={`kf_${i}`} tabIndex={i + 40}>
+                              <line
+                                id={`kf_${i.toString()}`}
+                                x1={
+                                  (i * 100) /
+                                    this.state.selectionLength.length +
+                                  '%'
+                                }
+                                y1='0'
+                                x2={
+                                  (i * 100) /
+                                    this.state.selectionLength.length +
+                                  '%'
+                                }
+                                y2='40'
+                                style={{ stroke: '#ffc017', strokeWidth: 1 }}
+                              />
+                            </svg>
+                          ) : null}
                         </>
-                      ) : null}
+                      }
                     </svg>
                   );
                 })}
-
-                {this.props.keyframes &&
-                  this.props.keyframes.map((kf, i) => {
-                    return (
-                      <svg
-                        key={`kf_${i}`}
-                        style={{ cursor: 'pointer' }}
-                        tabIndex={i + 40}
-                      >
-                        <line
-                          id={`kf_${i.toString()}`}
-                          x1={kf.frame * 10}
-                          y1='0'
-                          x2={kf.frame * 10}
-                          y2='40'
-                          style={{ stroke: '#ffc017', strokeWidth: 1 }}
-                        />
-                      </svg>
-                    );
-                  })}
               </svg>
             </div>
 
-            <div className='timeline-scroll-handle'>
-              <div className='scroll-handle'>
+            <div
+              className='timeline-scroll-handle'
+              onMouseMove={(e) => this.scrollDrag(e)}
+              onTouchMove={(e) => this.scrollDrag(e)}
+              onTouchStart={(e) => this.scrollDragStart(e)}
+              onTouchEnd={(e) => this.scrollDragEnd(e)}
+              onMouseDown={(e) => this.scrollDragStart(e)}
+              onMouseUp={(e) => this.scrollDragEnd(e)}
+              onMouseLeave={(e) => this.scrollDragEnd(e)}
+              onDragStart={() => false}
+            >
+              <div className='scroll-handle' ref={this._scrollContainer}>
                 <div
                   className='handle'
                   ref={this._scrollbarHandle}
-                  style={{ width: 300 }}
+                  style={{ width: this.state.scrollWidth }}
                 >
                   <div className='left-grabber'>
-                    <div className='grabber'></div>
-                    <div className='grabber'></div>
-                    <div className='grabber'></div>
-                    <div className='text'>20</div>
+                    <div className='left-draggable'>
+                      <div className='grabber'></div>
+                      <div className='grabber'></div>
+                      <div className='grabber'></div>
+                    </div>
+                    <div className='text'>{this.state.start}</div>
                   </div>
-                  <div
-                    className='scrollbar'
-                    onMouseMove={(e) => this.scrollDrag(e)}
-                    onTouchMove={(e) => this.scrollDrag(e)}
-                    onTouchStart={(e) => this.scrollDragStart(e)}
-                    onTouchEnd={(e) => this.scrollDragEnd(e)}
-                    onMouseDown={(e) => this.scrollDragStart(e)}
-                    onMouseUp={(e) => this.scrollDragEnd(e)}
-                    onMouseLeave={(e) => this.scrollDragEnd(e)}
-                    onDragStart={() => false}
-                  ></div>
+                  <div className='scrollbar'></div>
 
                   <div className='right-grabber'>
-                    <div className='text'>100</div>
-                    <div className='grabber'></div>
-                    <div className='grabber'></div>
-                    <div className='grabber'></div>
+                    <div className='text'>{this.state.end}</div>
+                    <div className='right-draggable'>
+                      <div className='grabber'></div>
+                      <div className='grabber'></div>
+                      <div className='grabber'></div>
+                    </div>
                   </div>
                 </div>
               </div>
-              <div className='input-frame'>
-                <input
-                  type='number'
-                  value={this.props.currentFrame}
-                  onChange={(e) => this.handleInputChange(e)}
-                ></input>
-              </div>
+            </div>
+
+            <div className='input-frame'>
+              <input
+                type='number'
+                value={this.props.animationLimit ?? 0}
+                onChange={(e) => this.handleLimitChange(e)}
+              ></input>
             </div>
           </div>
         </div>