three-story-controls.js 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686
  1. import {Vector3, EventDispatcher, Object3D, PerspectiveCamera, Quaternion, Euler, AnimationMixer, AnimationClip, VectorKeyframeTrack, QuaternionKeyframeTrack} from "./three.js";
  2. import {TweenMax, gsap as gsap2} from "./gsap.js";
  3. class p {
  4. constructor(t) {
  5. this.epsilon = 1e-3, this.values = {}, this.targetValues = {}, this.deltaValues = {}, Object.assign(this.values, t.values), Object.assign(this.targetValues, t.values), this.deltaValues = {};
  6. for (const t2 in this.values)
  7. this.deltaValues[t2] = 0;
  8. this.dampingFactor = t.dampingFactor, t.epsilon && (this.epsilon = t.epsilon), this.hasReached = true;
  9. }
  10. update() {
  11. const t = {};
  12. let e = true;
  13. for (const i in this.values)
  14. t[i] = this.targetValues[i] - this.values[i], e = e && Math.abs(t[i]) < this.epsilon;
  15. if (e) {
  16. for (const e2 in this.values)
  17. this.deltaValues[e2] = t[e2], this.values[e2] = this.targetValues[e2];
  18. this.hasReached = true;
  19. } else
  20. for (const e2 in this.values)
  21. this.deltaValues[e2] = this.dampingFactor * t[e2], this.values[e2] += this.deltaValues[e2];
  22. }
  23. setTarget(t) {
  24. for (const e in t)
  25. this.targetValues[e] = t[e];
  26. this.hasReached = false;
  27. }
  28. addToTarget(t, e) {
  29. this.targetValues[t] += e, this.hasReached = false;
  30. }
  31. resetAll(t) {
  32. for (const e in this.values)
  33. this.targetValues[e] = t, this.values[e] = t, this.deltaValues[e] = 0;
  34. this.hasReached = true;
  35. }
  36. resetData(t) {
  37. for (const e in t)
  38. this.targetValues[e] = t[e], this.values[e] = t[e], this.deltaValues[e] = 0;
  39. this.hasReached = true;
  40. }
  41. getCurrentValues() {
  42. return Object.assign({}, this.values);
  43. }
  44. getDeltaValues() {
  45. return Object.assign({}, this.deltaValues);
  46. }
  47. reachedTarget() {
  48. return this.hasReached;
  49. }
  50. }
  51. var m, u, g;
  52. !function(t) {
  53. t.Pan = "Pan", t.Tilt = "Tilt", t.Roll = "Roll", t.Truck = "Truck", t.Pedestal = "Pedestal", t.Dolly = "Dolly", t.Zoom = "Zoom";
  54. }(m || (m = {})), function(t) {
  55. t.Body = "body", t.Head = "head", t.Eyes = "eyes";
  56. }(u || (u = {})), function(t) {
  57. t.X = "x", t.Y = "y", t.Z = "z";
  58. }(g || (g = {}));
  59. const b = {[g.X]: new Vector3(1, 0, 0), [g.Y]: new Vector3(0, 1, 0), [g.Z]: new Vector3(0, 0, 1)}, y = {[g.X]: {[m.Pan]: g.X, [m.Tilt]: g.Z, [m.Roll]: g.Y}, [g.Y]: {[m.Pan]: g.Y, [m.Tilt]: g.X, [m.Roll]: g.Z}, [g.Z]: {[m.Pan]: g.Z, [m.Tilt]: g.Y, [m.Roll]: g.X}};
  60. class v extends EventDispatcher {
  61. constructor(t, e) {
  62. super(), this.inTransit = false, this.upAxis = g.Y, this.actionAxes = y[this.upAxis], this.hasAnimation = false, this.animationTranslationObjectName = "Translation", this.animationRotationObjectName = "Rotation", this.translateAlong = {[m.Tilt]: false, [m.Pan]: true, [m.Roll]: false}, this.camera = t, this.scene = e, this.body = new Object3D(), this.head = new Object3D(), this.eyes = new Object3D(), this.head.name = this.animationRotationObjectName, this.body.name = this.animationTranslationObjectName, this.body.rotation.order = this.getRotationOrder(), this.head.rotation.order = this.getRotationOrder(), this.eyes.rotation.order = this.getRotationOrder(), this.scene.add(this.body.add(this.head.add(this.eyes.add(this.camera)))), this.cameraIsInRig = true, this.unpackTransform();
  63. }
  64. getAxisFor(t) {
  65. return this.actionAxes[t];
  66. }
  67. getAxisVectorFor(t) {
  68. return b[this.actionAxes[t]];
  69. }
  70. do(t, e, i) {
  71. const n = this[i];
  72. switch (t) {
  73. case m.Pan:
  74. case m.Tilt:
  75. case m.Roll: {
  76. const i2 = this.getAxisVectorFor(t);
  77. n ? n.rotateOnAxis(i2, e) : this.translateAlong[t] ? this.body.rotateOnAxis(i2, e) : this.eyes.rotateOnAxis(i2, e);
  78. break;
  79. }
  80. case m.Truck: {
  81. const t2 = this.getAxisVectorFor(m.Tilt);
  82. (n || this.body).translateOnAxis(t2, e);
  83. break;
  84. }
  85. case m.Pedestal: {
  86. const t2 = this.getAxisVectorFor(m.Pan);
  87. (n || this.body).translateOnAxis(t2, e);
  88. break;
  89. }
  90. case m.Dolly: {
  91. const t2 = this.getAxisVectorFor(m.Roll);
  92. (n || this.body).translateOnAxis(t2, e);
  93. break;
  94. }
  95. case m.Zoom:
  96. this.camera instanceof PerspectiveCamera && (this.camera.fov = e, this.camera.updateProjectionMatrix());
  97. }
  98. }
  99. getWorldCoordinates() {
  100. const e = new Vector3();
  101. this.camera.getWorldPosition(e);
  102. const i = new Quaternion();
  103. return this.camera.getWorldQuaternion(i), {position: e, quaternion: i};
  104. }
  105. setWorldCoordinates({position: t, quaternion: e}) {
  106. const i = new Euler().setFromQuaternion(e, this.getRotationOrder()), s = [m.Pan, m.Tilt, m.Roll];
  107. this.eyes.position.set(0, 0, 0), this.eyes.rotation.set(0, 0, 0), this.head.position.set(0, 0, 0), this.head.rotation.set(0, 0, 0), this.body.position.copy(t), s.forEach((t2) => {
  108. const e2 = this.getAxisFor(t2);
  109. this.translateAlong[t2] ? this.body.rotation[e2] = i[e2] : this.eyes.rotation[e2] = i[e2];
  110. }), this.camera.rotation.set(0, 0, 0), this.camera.position.set(0, 0, 0);
  111. }
  112. packTransform() {
  113. const {position: t, quaternion: e} = this.getWorldCoordinates();
  114. this.body.position.copy(t), this.body.rotation.set(0, 0, 0), this.head.quaternion.copy(e), this.head.position.set(0, 0, 0), this.eyes.position.set(0, 0, 0), this.eyes.rotation.set(0, 0, 0);
  115. }
  116. unpackTransform() {
  117. const {position: t, quaternion: e} = this.getWorldCoordinates();
  118. this.setWorldCoordinates({position: t, quaternion: e});
  119. }
  120. disassemble() {
  121. this.cameraIsInRig && (this.scene.attach(this.camera), this.cameraIsInRig = false);
  122. }
  123. assemble() {
  124. this.cameraIsInRig || (this.eyes.attach(this.camera), this.unpackTransform(), this.cameraIsInRig = true);
  125. }
  126. getRotationOrder() {
  127. return Object.values(this.actionAxes).join("").toUpperCase();
  128. }
  129. isInRig() {
  130. return this.cameraIsInRig;
  131. }
  132. isMoving() {
  133. return this.inTransit;
  134. }
  135. setUpAxis(t) {
  136. this.upAxis = t, this.actionAxes = y[this.upAxis], this.body.rotation.order = this.getRotationOrder();
  137. }
  138. setAnimationClip(t, e, i) {
  139. this.animationClip = t, e && (this.animationTranslationObjectName = e), i && (this.animationRotationObjectName = i), this.hasAnimation = true, this.animationClip.duration += 0.01, this.mixer = new AnimationMixer(this.body);
  140. const s = this.mixer.clipAction(this.animationClip);
  141. s.clampWhenFinished = true, s.play();
  142. }
  143. flyTo(t, e, i = 1, s = "power1", n = true) {
  144. if (!this.isMoving()) {
  145. const a = this.getWorldCoordinates(), o = {px: a.position.x, py: a.position.y, pz: a.position.z, qx: a.quaternion.x, qy: a.quaternion.y, qz: a.quaternion.z, qw: a.quaternion.w, slerpAmt: 0}, r = {px: t.x, py: t.y, pz: t.z, qx: e.x, qy: e.y, qz: e.z, qw: e.w, slerpAmt: 1}, h = () => {
  146. this.inTransit = true, this.packTransform(), this.dispatchEvent({type: "CameraMoveStart"});
  147. }, d = (t2) => {
  148. this.body.position.set(o.px, o.py, o.pz), n ? this.head.quaternion.slerp(e, o.slerpAmt) : this.head.quaternion.set(o.qx, o.qy, o.qz, o.qw), this.dispatchEvent({type: "CameraMoveUpdate", progress: t2.progress()});
  149. }, l = () => {
  150. this.inTransit = false, this.unpackTransform(), this.dispatchEvent({type: "CameraMoveEnd"});
  151. };
  152. TweenMax.to(o, Object.assign(Object.assign({duration: i, ease: s}, r), {onStart: h, onUpdate: function() {
  153. d(this);
  154. }, onComplete: l}));
  155. }
  156. }
  157. flyToKeyframe(t, e = 1, i = "power1") {
  158. if (this.hasAnimation && !this.isMoving()) {
  159. const s = {time: this.mixer.time}, n = {time: this.animationClip.tracks[0].times[t]}, a = () => {
  160. this.inTransit = true, this.dispatchEvent({type: "CameraMoveStart"});
  161. }, o = (t2) => {
  162. this.mixer.setTime(s.time), this.dispatchEvent({type: "CameraMoveUpdate", progress: t2.progress()});
  163. }, r = () => {
  164. this.inTransit = false, this.dispatchEvent({type: "CameraMoveEnd"});
  165. };
  166. TweenMax.to(s, Object.assign(Object.assign({duration: e, ease: i}, n), {onStart: a, onUpdate: function() {
  167. o(this);
  168. }, onComplete: r}));
  169. }
  170. }
  171. setAnimationPercentage(t) {
  172. if (this.hasAnimation) {
  173. const e = Math.max(0, Math.min(t * this.animationClip.duration, this.animationClip.duration - 1e-4));
  174. this.mixer.setTime(e);
  175. }
  176. }
  177. setAnimationTime(t) {
  178. this.hasAnimation && this.mixer.setTime(t);
  179. }
  180. setAnimationKeyframe(t) {
  181. this.hasAnimation && this.mixer.setTime(this.animationClip.tracks[0].times[t]);
  182. }
  183. }
  184. class x extends EventDispatcher {
  185. constructor() {
  186. super();
  187. }
  188. }
  189. const f = {keyMapping: {forward: ["ArrowUp", "w", "W"], backward: ["ArrowDown", "s", "S"], left: ["ArrowLeft", "a", "A"], right: ["ArrowRight", "d", "D"], up: ["u", "U"], down: ["n", "N"]}, dampingFactor: 0.5, incrementor: 1, preventBubbling: true};
  190. class E extends x {
  191. constructor(t) {
  192. super(), Object.assign(this, f, t);
  193. const e = {};
  194. for (const t2 in this.keyMapping)
  195. e[t2] = 0;
  196. this.damper = new p({values: e, dampingFactor: this.dampingFactor}), this.onKeyUp = this.onKeyUp.bind(this), this.onKeyDown = this.onKeyDown.bind(this);
  197. }
  198. connect() {
  199. document.addEventListener("keyup", this.onKeyUp, true), document.addEventListener("keydown", this.onKeyDown, true), this.connected = true;
  200. }
  201. disconnect() {
  202. document.removeEventListener("keyup", this.onKeyUp, true), document.removeEventListener("keydown", this.onKeyDown, true), this.connected = false;
  203. }
  204. update() {
  205. this.type !== "continuous" || this.damper.reachedTarget() || (this.damper.update(), this.dispatchEvent({type: "update", values: this.damper.getCurrentValues(), deltas: this.damper.getDeltaValues()}), this.damper.reachedTarget() && (this.damper.resetAll(0), this.dispatchEvent({type: "inertiacomplete"})));
  206. }
  207. isEnabled() {
  208. return this.connected;
  209. }
  210. onKeyUp(t) {
  211. if (this.type === "discrete") {
  212. for (const e in this.keyMapping)
  213. if (this.keyMapping[e].includes(t.key)) {
  214. this.preventBubbling && t.preventDefault(), this.dispatchEvent({type: "trigger", trigger: e});
  215. break;
  216. }
  217. }
  218. }
  219. onKeyDown(t) {
  220. if (this.type === "continuous") {
  221. for (const e in this.keyMapping)
  222. if (this.keyMapping[e].includes(t.key)) {
  223. this.preventBubbling && t.preventDefault(), this.damper.addToTarget(e, this.incrementor);
  224. break;
  225. }
  226. }
  227. }
  228. }
  229. const w = {domElement: document.body, dampingFactor: 0.5, shouldNormalize: true, normalizeAroundZero: true, multipointerThreshold: 100};
  230. class P extends x {
  231. constructor(t) {
  232. super(), this.domElement = document.body, this.shouldNormalize = true, this.normalizeAroundZero = true, this.pointerCount = 0, this.recordedPosition = false, this.cache = [], this.lastDownTime = 0, this.lastUpTime = 0, Object.assign(this, w, t), this.damper = new p({values: {x: null, y: null}, dampingFactor: this.dampingFactor}), this.setDimensions(), this.onPointerMove = this.onPointerMove.bind(this), this.onPointerUp = this.onPointerUp.bind(this), this.onPointerDown = this.onPointerDown.bind(this), this.onResize = this.onResize.bind(this);
  233. }
  234. connect() {
  235. this.domElement.addEventListener("pointermove", this.onPointerMove, {passive: true}), this.domElement.addEventListener("pointerdown", this.onPointerDown, {passive: true}), this.domElement.addEventListener("pointerleave", this.onPointerUp, {passive: true}), this.domElement.addEventListener("pointerup", this.onPointerUp, {passive: true}), window.addEventListener("resize", this.onResize), this.connected = true;
  236. }
  237. disconnect() {
  238. this.domElement.removeEventListener("pointermove", this.onPointerMove), this.domElement.removeEventListener("pointerdown", this.onPointerDown), this.domElement.removeEventListener("pointerleave", this.onPointerUp), this.domElement.removeEventListener("pointerup", this.onPointerUp), this.connected = false;
  239. }
  240. update(t) {
  241. this.pointerCount !== this.cache.length && t - this.lastDownTime > this.multipointerThreshold && t - this.lastUpTime > this.multipointerThreshold && (this.pointerCount = this.cache.length, this.pointerCount === 0 ? (this.damper.resetAll(null), this.recordedPosition = false) : (this.damper.resetData(this.getPointerPosition(this.cache[0])), this.recordedPosition = true)), this.damper.reachedTarget() || (this.damper.update(), this.dispatchEvent({type: "update", values: this.shouldNormalize ? this.normalize(this.damper.getCurrentValues(), this.normalizeAroundZero) : this.damper.getCurrentValues(), deltas: this.shouldNormalize ? this.normalize(this.damper.getDeltaValues(), false) : this.damper.getDeltaValues(), pointerCount: this.pointerCount}), this.damper.reachedTarget() && this.dispatchEvent({type: "inertiacomplete"}));
  242. }
  243. isEnabled() {
  244. return this.connected;
  245. }
  246. setDimensions() {
  247. this.width = this.domElement.getBoundingClientRect().width, this.height = this.domElement.getBoundingClientRect().height;
  248. }
  249. getPointerPosition(t) {
  250. return {x: Math.max(0, Math.min(this.width, t.x - this.domElement.offsetLeft)), y: Math.max(0, Math.min(this.height, t.y - this.domElement.offsetTop))};
  251. }
  252. normalize(t, e) {
  253. let i = t.x / this.width, s = t.y / this.height;
  254. return e && (i = 2 * i - 1, s = 2 * s - 1), {x: i, y: s};
  255. }
  256. onPointerMove(t) {
  257. this.pointerCount === this.cache.length && (this.cache.length === 0 ? this.recordedPosition ? this.damper.setTarget(this.getPointerPosition(t)) : (this.damper.resetData(this.getPointerPosition(t)), this.recordedPosition = true) : t.pointerId === this.cache[0].pointerId && this.damper.setTarget(this.getPointerPosition(t)));
  258. }
  259. onPointerDown(t) {
  260. t.button === 0 && (this.cache.push(t), this.lastDownTime = window.performance.now());
  261. }
  262. onPointerUp(t) {
  263. if (t.button === 0 || t.type === "pointerleave") {
  264. for (let e = 0; e < this.cache.length; e++)
  265. if (this.cache[e].pointerId == t.pointerId) {
  266. this.cache.splice(e, 1);
  267. break;
  268. }
  269. this.lastUpTime = window.performance.now();
  270. }
  271. }
  272. onResize() {
  273. this.setDimensions();
  274. }
  275. }
  276. const A = {startOffset: "0px", endOffset: "0px", buffer: 0.1, dampingFactor: 0.5};
  277. class T extends x {
  278. constructor(t) {
  279. super(), Object.assign(this, A, t), this.lastSeenScrollValue = window.scrollY || -1, this.previousScrollValue = this.lastSeenScrollValue, this.values = {scrollPx: null, scrollPercent: null}, this.damper = new p({values: this.values, dampingFactor: this.dampingFactor}), this.calculateDimensions = this.calculateDimensions.bind(this), this.onScroll = this.onScroll.bind(this), this.resizeObserver = new ResizeObserver(this.calculateDimensions), this.calculateDimensions();
  280. }
  281. connect() {
  282. window.addEventListener("scroll", this.onScroll, {passive: true}), this.resizeObserver.observe(document.body), this.connected = true;
  283. }
  284. disconnect() {
  285. window.removeEventListener("scroll", this.onScroll), this.resizeObserver.unobserve(document.body), this.connected = false;
  286. }
  287. update() {
  288. if (this.lastSeenScrollValue !== this.previousScrollValue && this.lastSeenScrollValue >= this.bufferedStartPosition && this.lastSeenScrollValue <= this.bufferedEndPosition) {
  289. const t = Math.max(0, Math.min(this.distance, this.lastSeenScrollValue - this.startPosition)), e = Math.max(0, Math.min(1, t / this.distance));
  290. this.values = {scrollPx: t, scrollPercent: e}, this.damper.setTarget(this.values), this.previousScrollValue = this.lastSeenScrollValue;
  291. }
  292. this.damper.reachedTarget() || (this.damper.update(), this.dispatchEvent({type: "update", values: this.values, dampenedValues: this.damper.getCurrentValues()}), this.damper.reachedTarget() && this.dispatchEvent({type: "inertiacomplete"}));
  293. }
  294. isEnabled() {
  295. return this.connected;
  296. }
  297. parseOffset(t) {
  298. let e = 0;
  299. return t && (e = parseInt(t), t.indexOf("vh") !== -1 ? e = e * window.innerHeight / 100 : this.distance && t.indexOf("%") !== -1 && (e = e * this.distance / 100)), e;
  300. }
  301. calculateOffset(t) {
  302. return t ? this.calculateOffset(t.offsetParent) + t.offsetTop : 0;
  303. }
  304. calculateDimensions() {
  305. const t = this.scrollElement.clientHeight, e = this.calculateOffset(this.scrollElement);
  306. this.startPosition = e - window.innerHeight + this.parseOffset(this.startOffset), this.endPosition = e + t + this.parseOffset(this.endOffset), this.distance = this.endPosition - this.startPosition, this.bufferedStartPosition = Math.max(0, this.startPosition * (1 - this.buffer)), this.bufferedEndPosition = Math.min(this.endPosition * (1 + this.buffer), document.body.getBoundingClientRect().height);
  307. }
  308. onScroll() {
  309. this.lastSeenScrollValue = window.scrollY;
  310. }
  311. }
  312. const C = {domElement: document.body, thresholdX: 60, thresholdY: 60};
  313. class L extends x {
  314. constructor(t = {}) {
  315. super(), Object.assign(this, C, t), this.onPointerUp = this.onPointerUp.bind(this), this.onPointerDown = this.onPointerDown.bind(this);
  316. }
  317. connect() {
  318. this.domElement.addEventListener("pointerdown", this.onPointerDown, {passive: true}), this.domElement.addEventListener("pointerup", this.onPointerUp, {passive: true}), this.connected = true;
  319. }
  320. disconnect() {
  321. this.domElement.removeEventListener("pointerdown", this.onPointerDown), this.domElement.removeEventListener("pointerup", this.onPointerUp), this.connected = false;
  322. }
  323. update() {
  324. }
  325. isEnabled() {
  326. return this.connected;
  327. }
  328. onPointerDown(t) {
  329. t.pointerType !== "mouse" && t.isPrimary && (this.startX = t.screenX, this.startY = t.screenY);
  330. }
  331. onPointerUp(t) {
  332. if (t.pointerType !== "mouse" && t.isPrimary) {
  333. const e = t.screenX - this.startX, i = t.screenY - this.startY;
  334. (Math.abs(e) >= this.thresholdX || Math.abs(i) >= this.thresholdY) && this.dispatchEvent({type: "trigger", x: Math.abs(e) >= this.thresholdX ? Math.sign(e) : 0, y: Math.abs(i) >= this.thresholdY ? Math.sign(-1 * i) : 0});
  335. }
  336. }
  337. }
  338. const S = {dampingFactor: 0.5, thresholdX: 15, thresholdY: 15, debounceDuration: 700};
  339. class F extends x {
  340. constructor(t) {
  341. super(), this.lastThresholdTrigger = 0, Object.assign(this, S, t), this.damper = new p({values: {x: 0, y: 0}, dampingFactor: this.dampingFactor}), this.onWheel = this.onWheel.bind(this);
  342. }
  343. connect() {
  344. (this.domElement || window).addEventListener("wheel", this.onWheel, {passive: true}), this.connected = true;
  345. }
  346. disconnect() {
  347. (this.domElement || window).removeEventListener("wheel", this.onWheel), this.connected = false;
  348. }
  349. update() {
  350. this.type !== "continuous" || this.damper.reachedTarget() || (this.damper.update(), this.dispatchEvent({type: "update", values: this.damper.getCurrentValues(), deltas: this.damper.getDeltaValues()}), this.damper.reachedTarget() && (this.damper.resetAll(0), this.dispatchEvent({type: "inertiacomplete"})));
  351. }
  352. isEnabled() {
  353. return this.connected;
  354. }
  355. onWheel(t) {
  356. if (this.type === "continuous")
  357. this.damper.addToTarget("x", t.deltaX), this.damper.addToTarget("y", t.deltaY);
  358. else if (this.type === "discrete" && (Math.abs(t.deltaX) >= this.thresholdX || Math.abs(t.deltaY) >= this.thresholdY)) {
  359. const e = window.performance.now();
  360. e - this.lastThresholdTrigger > this.debounceDuration && (this.lastThresholdTrigger = e, this.dispatchEvent({type: "trigger", x: Math.abs(t.deltaX) >= this.thresholdX ? Math.sign(t.deltaX) : 0, y: Math.abs(t.deltaY) >= this.thresholdY ? Math.sign(t.deltaY) : 0}));
  361. }
  362. }
  363. }
  364. const R = {domElement: document.body, pointerDampFactor: 0.3, pointerScaleFactor: 4, keyboardDampFactor: 0.5, keyboardScaleFactor: 0.5, wheelDampFactor: 0.25, wheelScaleFactor: 0.05, panDegreeFactor: Math.PI / 4, tiltDegreeFactor: Math.PI / 10};
  365. class k {
  366. constructor(t, e = {}) {
  367. this.enabled = false, this.cameraRig = t, this.wheelScaleFactor = e.wheelScaleFactor || R.wheelScaleFactor, this.pointerScaleFactor = e.pointerScaleFactor || R.pointerScaleFactor, this.panDegreeFactor = e.panDegreeFactor || R.panDegreeFactor, this.tiltDegreeFactor = e.tiltDegreeFactor || R.tiltDegreeFactor, this.keyboardAdaptor = new E({type: "continuous", dampingFactor: e.keyboardDampFactor || R.keyboardDampFactor, incrementor: e.keyboardScaleFactor || R.keyboardScaleFactor}), this.wheelAdaptor = new F({type: "continuous", dampingFactor: e.wheelDampFactor || R.wheelDampFactor, domElement: e.domElement || R.domElement}), this.pointerAdaptor = new P({domElement: e.domElement || R.domElement, dampingFactor: e.pointerDampFactor || R.pointerDampFactor}), this.onWheel = this.onWheel.bind(this), this.onKey = this.onKey.bind(this), this.onPointer = this.onPointer.bind(this);
  368. }
  369. isEnabled() {
  370. return this.enabled;
  371. }
  372. enable() {
  373. this.wheelAdaptor.connect(), this.keyboardAdaptor.connect(), this.pointerAdaptor.connect(), this.wheelAdaptor.addEventListener("update", this.onWheel), this.keyboardAdaptor.addEventListener("update", this.onKey), this.pointerAdaptor.addEventListener("update", this.onPointer), this.enabled = true;
  374. }
  375. disable() {
  376. this.wheelAdaptor.disconnect(), this.keyboardAdaptor.disconnect(), this.pointerAdaptor.disconnect(), this.wheelAdaptor.removeEventListener("update", this.onWheel), this.keyboardAdaptor.removeEventListener("update", this.onKey), this.pointerAdaptor.removeEventListener("update", this.onPointer), this.enabled = false;
  377. }
  378. onWheel(t) {
  379. this.cameraRig.do(m.Dolly, t.deltas.y * this.wheelScaleFactor), this.cameraRig.do(m.Truck, t.deltas.x * this.wheelScaleFactor);
  380. }
  381. onKey(t) {
  382. this.cameraRig.do(m.Dolly, t.values.backward - t.values.forward), this.cameraRig.do(m.Truck, t.values.right - t.values.left), this.cameraRig.do(m.Pedestal, t.values.up - t.values.down);
  383. }
  384. onPointer(t) {
  385. switch (t.pointerCount) {
  386. case 1:
  387. this.cameraRig.do(m.Pan, t.deltas.x * this.panDegreeFactor), this.cameraRig.do(m.Tilt, t.deltas.y * this.tiltDegreeFactor);
  388. break;
  389. case 2:
  390. this.cameraRig.do(m.Dolly, -t.deltas.y * this.pointerScaleFactor), this.cameraRig.do(m.Truck, -t.deltas.x * this.pointerScaleFactor);
  391. }
  392. }
  393. update(t) {
  394. this.enabled && (this.keyboardAdaptor.update(), this.wheelAdaptor.update(), this.pointerAdaptor.update(t));
  395. }
  396. }
  397. const O = {startOffset: "0px", endOffset: "0px", dampingFactor: 1, buffer: 0.1, cameraStart: "0%", cameraEnd: "100%", scrollActions: []}, M = (t, e, i, s, n) => Math.max(s, Math.min(n, (n - s) / (i - e) * (t - e) + s));
  398. class I {
  399. constructor(t, e) {
  400. this.enabled = false, this.cameraRig = t, this.cameraRig.setAnimationTime(0), this.scrollAdaptor = new T({scrollElement: e.scrollElement, dampingFactor: e.dampingFactor || O.dampingFactor, startOffset: e.startOffset || O.startOffset, endOffset: e.endOffset || O.endOffset, buffer: e.buffer || O.buffer}), this.cameraStart = e.cameraStart || O.cameraStart, this.cameraEnd = e.cameraEnd || O.cameraEnd, this.scrollActions = e.scrollActions || O.scrollActions, this.buffer = e.buffer || O.buffer, this.calculateStops(), this.onScroll = this.onScroll.bind(this);
  401. }
  402. isEnabled() {
  403. return this.enabled;
  404. }
  405. enable() {
  406. this.scrollAdaptor.connect(), this.scrollAdaptor.addEventListener("update", this.onScroll), this.enabled = true;
  407. }
  408. disable() {
  409. this.scrollAdaptor.disconnect(), this.scrollAdaptor.removeEventListener("update", this.onScroll), this.enabled = false;
  410. }
  411. update() {
  412. this.enabled && this.scrollAdaptor.update();
  413. }
  414. calculateStops() {
  415. this.cameraStartPx = this.scrollAdaptor.parseOffset(this.cameraStart), this.cameraEndPx = this.scrollAdaptor.parseOffset(this.cameraEnd), this.cameraBufferedStartPx = this.cameraStartPx * (1 - this.buffer), this.cameraBufferedEndPx = this.cameraEndPx * (1 + this.buffer), this.scrollActions.forEach((t) => {
  416. t.startPx = this.scrollAdaptor.parseOffset(t.start), t.endPx = this.scrollAdaptor.parseOffset(t.end), t.bufferedStartPx = t.startPx * (1 - this.buffer), t.bufferedEndPx = t.endPx * (1 + this.buffer);
  417. });
  418. }
  419. onScroll(t) {
  420. const e = t.dampenedValues.scrollPx;
  421. e >= this.cameraBufferedStartPx && e <= this.cameraBufferedEndPx && this.cameraRig.setAnimationPercentage(M(e, this.cameraStartPx, this.cameraEndPx, 0, 1)), this.scrollActions.forEach((t2) => {
  422. e >= t2.bufferedStartPx && e <= t2.bufferedEndPx && t2.callback(M(e, t2.startPx, t2.endPx, 0, 1));
  423. });
  424. }
  425. }
  426. const D = {cycle: false, useKeyboard: true};
  427. class q extends EventDispatcher {
  428. constructor(t, e = [], i = {}) {
  429. super(), this.currentIndex = null, this.upcomingIndex = null, this.enabled = false, this.cameraRig = t, this.pois = e, Object.assign(this, D, i), this.useKeyboard && (this.keyboardAdaptor = new E({type: "discrete", keyMapping: {next: ["ArrowDown", "ArrowRight"], prev: ["ArrowUp", "ArrowLeft"]}}), this.onKey = this.onKey.bind(this)), this.onCameraStart = this.onCameraStart.bind(this), this.onCameraUpdate = this.onCameraUpdate.bind(this), this.onCameraEnd = this.onCameraEnd.bind(this);
  430. }
  431. getCurrentIndex() {
  432. return this.currentIndex;
  433. }
  434. nextPOI() {
  435. const t = this.currentIndex + 1;
  436. t >= this.pois.length && !this.cycle ? this.dispatchEvent({type: "ExitPOIs", exitFrom: "end"}) : this.goToPOI(t % this.pois.length);
  437. }
  438. prevPOI() {
  439. const t = this.currentIndex - 1;
  440. t < 0 && !this.cycle ? this.dispatchEvent({type: "ExitPOIs", exitFrom: "start"}) : this.goToPOI((t + this.pois.length) % this.pois.length);
  441. }
  442. goToPOI(t) {
  443. this.upcomingIndex = t;
  444. const e = this.pois[this.upcomingIndex];
  445. this.cameraRig.flyTo(e.position, e.quaternion, e.duration, e.ease);
  446. }
  447. enable() {
  448. this.useKeyboard && (this.keyboardAdaptor.connect(), this.keyboardAdaptor.addEventListener("trigger", this.onKey)), this.cameraRig.addEventListener("CameraMoveStart", this.onCameraStart), this.cameraRig.addEventListener("CameraMoveUpdate", this.onCameraUpdate), this.cameraRig.addEventListener("CameraMoveEnd", this.onCameraEnd), this.enabled = true;
  449. }
  450. disable() {
  451. this.useKeyboard && (this.keyboardAdaptor.disconnect(), this.keyboardAdaptor.removeEventListener("trigger", this.onKey)), this.cameraRig.removeEventListener("CameraMoveStart", this.onCameraStart), this.cameraRig.removeEventListener("CameraMoveUpdate", this.onCameraUpdate), this.cameraRig.removeEventListener("CameraMoveEnd", this.onCameraEnd), this.enabled = false;
  452. }
  453. update() {
  454. }
  455. isEnabled() {
  456. return this.enabled;
  457. }
  458. updatePois(t) {
  459. this.dispatchEvent({type: "update", currentIndex: this.currentIndex, upcomingIndex: this.upcomingIndex, progress: t});
  460. }
  461. onCameraStart() {
  462. this.updatePois(0);
  463. }
  464. onCameraUpdate(t) {
  465. this.updatePois(t.progress);
  466. }
  467. onCameraEnd() {
  468. this.currentIndex = this.upcomingIndex, this.upcomingIndex = null;
  469. }
  470. onKey(t) {
  471. t.trigger === "next" ? this.nextPOI() : t.trigger === "prev" && this.prevPOI();
  472. }
  473. }
  474. const z = {wheelThreshold: 15, swipeThreshold: 60, duration: 1, ease: "power1", useKeyboard: true};
  475. class U extends EventDispatcher {
  476. constructor(t, e = [], i = {}) {
  477. super(), this.currentIndex = 0, this.upcomingIndex = null, this.enabled = false, this.cameraRig = t, this.pois = e, Object.assign(this, z, i), this.wheelAdaptor = new F({type: "discrete", thresholdY: this.wheelThreshold}), this.swipeAdaptor = new L({thresholdY: this.swipeThreshold}), this.useKeyboard && (this.keyboardAdaptor = new E({type: "discrete", keyMapping: {next: ["ArrowDown", "ArrowRight"], prev: ["ArrowUp", "ArrowLeft"]}}), this.onKey = this.onKey.bind(this)), this.onCameraStart = this.onCameraStart.bind(this), this.onCameraUpdate = this.onCameraUpdate.bind(this), this.onCameraEnd = this.onCameraEnd.bind(this), this.onTrigger = this.onTrigger.bind(this);
  478. }
  479. getCurrentIndex() {
  480. return this.currentIndex;
  481. }
  482. enable() {
  483. this.useKeyboard && (this.keyboardAdaptor.addEventListener("trigger", this.onKey), this.keyboardAdaptor.connect()), this.wheelAdaptor.addEventListener("trigger", this.onTrigger), this.swipeAdaptor.addEventListener("trigger", this.onTrigger), this.cameraRig.addEventListener("CameraMoveStart", this.onCameraStart), this.cameraRig.addEventListener("CameraMoveUpdate", this.onCameraUpdate), this.cameraRig.addEventListener("CameraMoveEnd", this.onCameraEnd), this.wheelAdaptor.connect(), this.swipeAdaptor.connect(), this.enabled = true;
  484. }
  485. disable() {
  486. this.useKeyboard && (this.keyboardAdaptor.removeEventListener("trigger", this.onKey), this.keyboardAdaptor.disconnect()), this.wheelAdaptor.removeEventListener("trigger", this.onTrigger), this.swipeAdaptor.removeEventListener("trigger", this.onTrigger), this.cameraRig.removeEventListener("CameraMoveStart", this.onCameraStart), this.cameraRig.removeEventListener("CameraMoveUpdate", this.onCameraUpdate), this.cameraRig.removeEventListener("CameraMoveEnd", this.onCameraEnd), this.wheelAdaptor.disconnect(), this.swipeAdaptor.disconnect(), this.enabled = false;
  487. }
  488. update() {
  489. }
  490. isEnabled() {
  491. return this.enabled;
  492. }
  493. onKey(t) {
  494. switch (t.trigger) {
  495. case "prev":
  496. this.onTrigger({y: -1});
  497. break;
  498. case "next":
  499. this.onTrigger({y: 1});
  500. }
  501. }
  502. onTrigger(t) {
  503. const e = this.currentIndex + t.y;
  504. e >= this.pois.length ? this.dispatchEvent({type: "ExitPOIs", exitFrom: "end"}) : e < 0 ? this.dispatchEvent({type: "ExitPOIs", exitFrom: "start"}) : (this.upcomingIndex = e, this.cameraRig.flyToKeyframe(this.pois[this.upcomingIndex].frame, this.duration, this.ease));
  505. }
  506. updatePois(t) {
  507. this.dispatchEvent({type: "update", currentIndex: this.currentIndex, upcomingIndex: this.upcomingIndex, progress: t});
  508. }
  509. onCameraStart() {
  510. this.updatePois(0);
  511. }
  512. onCameraUpdate(t) {
  513. this.updatePois(t.progress);
  514. }
  515. onCameraEnd() {
  516. this.currentIndex = this.upcomingIndex, this.upcomingIndex = null;
  517. }
  518. }
  519. const V = {domElement: document.body, panFactor: Math.PI / 20, tiltFactor: Math.PI / 20, truckFactor: 1, pedestalFactor: 1, dampingFactor: 0.7};
  520. class K {
  521. constructor(t, e = {}) {
  522. this.enabled = false, this.cameraRig = t, Object.assign(this, V, e), this.pointerAdaptor = new P({domElement: e.domElement || V.domElement, dampingFactor: e.dampingFactor || V.dampingFactor}), this.onPointerMove = this.onPointerMove.bind(this);
  523. }
  524. isEnabled() {
  525. return this.enabled;
  526. }
  527. enable() {
  528. this.pointerAdaptor.connect(), this.pointerAdaptor.addEventListener("update", this.onPointerMove), this.enabled = true;
  529. }
  530. disable() {
  531. this.pointerAdaptor.disconnect(), this.pointerAdaptor.removeEventListener("update", this.onPointerMove), this.enabled = false;
  532. }
  533. update(t) {
  534. this.enabled && this.pointerAdaptor.update(t);
  535. }
  536. onPointerMove(t) {
  537. t.pointerCount === 0 && (this.cameraRig.do(m.Pan, -t.deltas.x * this.panFactor, u.Eyes), this.cameraRig.do(m.Tilt, -t.deltas.y * this.tiltFactor, u.Eyes), this.cameraRig.do(m.Truck, t.deltas.x * this.truckFactor, u.Eyes), this.cameraRig.do(m.Pedestal, t.deltas.y * this.pedestalFactor, u.Eyes));
  538. }
  539. }
  540. !function(t, e) {
  541. e === void 0 && (e = {});
  542. var i = e.insertAt;
  543. if (t && typeof document != "undefined") {
  544. var s = document.head || document.getElementsByTagName("head")[0], n = document.createElement("style");
  545. n.type = "text/css", i === "top" && s.firstChild ? s.insertBefore(n, s.firstChild) : s.appendChild(n), n.styleSheet ? n.styleSheet.cssText = t : n.appendChild(document.createTextNode(t));
  546. }
  547. }(".tb-ch {\n width: 350px;\n height: 100%;\n position: fixed;\n top: 0;\n left: 0;\n z-index: 99999;\n background-color: rgba(255, 255, 255, 0.8);\n box-sizing: border-box;\n overflow-x: visible;\n transition: all 0.2s ease-in-out;\n}\n .tb-ch.collapsed {\n left: -350px;\n }\n .tb-ch * {\n box-sizing: border-box;\n }\n .tb-ch button {\n text-transform: capitalize;\n cursor: pointer;\n }\n .tb-ch .btn-round {\n font-size: 1.8rem;\n line-height: 1;\n width: 2.5rem;\n height: 2.5rem;\n position: absolute;\n right: -3rem;\n bottom: 0.5rem;\n }\n .tb-ch .btn-round.collapse {\n bottom: 3.5rem;\n }\n .tb-ch .controls {\n position: absolute;\n bottom: 0;\n height: 185px;\n border-top: 1px solid black;\n padding: 0.5rem;\n width: 100%;\n display: flex;\n flex-direction: column;\n justify-content: space-between;\n }\n .tb-ch .btn-text {\n padding: 0.5rem;\n text-align: center;\n width: 100%;\n }\n .tb-ch input[type='range'] {\n width: 100%;\n }\n .tb-ch .pois {\n height: calc(100vh - 185px - 1rem);\n overflow: scroll;\n padding: 1rem 1rem 0;\n }\n .tb-ch .poi {\n margin-bottom: 1rem;\n }\n .tb-ch .poi h2 {\n font-size: 1rem;\n }\n .tb-ch .poi .wrapper {\n display: flex;\n flex-direction: row;\n }\n .tb-ch .poi img {\n display: block;\n max-width: 100%;\n min-width: 0;\n margin-right: 0.5rem;\n }\n .tb-ch .poi .poi-controls {\n display: flex;\n flex-direction: column;\n }\n .tb-ch .poi .poi-controls button {\n padding: 0.5rem;\n width: 2rem;\n height: 2rem;\n margin-bottom: 0.25rem;\n }\n .tb-ch .poi .poi-params {\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n width: calc(100% - 2.5rem);\n }\n .tb-ch .poi label,\n .tb-ch .poi input,\n .tb-ch .poi select {\n width: 50%;\n font-size: 0.7rem;\n font-family: monospace;\n margin: 0.25rem 0;\n }\n .tb-ch .poi input {\n text-align: center;\n }\n");
  548. const j = ["none", "power1", "power2", "power3", "power4", "sine", "expo", "circ"], Y = "visit", W = "remove", B = "duration", X = "ease", N = "move-up", Z = "move-down";
  549. class H {
  550. constructor(t, e, i, s) {
  551. this.useSlerp = true, this.rig = t, this.controls = e, this.canvas = i, this.pois = [], this.currentIndex = null, this.doCapture = false, this.isPlaying = false, this.initUI(s);
  552. }
  553. capture() {
  554. this.doCapture = true;
  555. }
  556. update(t) {
  557. if (this.doCapture) {
  558. const t2 = this.canvas.toDataURL();
  559. this.addPoi(t2), this.doCapture = false;
  560. }
  561. if (this.isPlaying) {
  562. this.playStartTime || (this.playStartTime = t, this.controls.disable(), this.rig.packTransform());
  563. const e = (t - this.playStartTime) / 1e3;
  564. this.rig.setAnimationTime(e), e > this.animationClip.duration && (this.isPlaying = false, this.playStartTime = null, this.controls.enable(), this.rig.unpackTransform());
  565. }
  566. }
  567. addPoi(t) {
  568. this.pois.push(Object.assign(Object.assign({}, this.rig.getWorldCoordinates()), {duration: 1, ease: "power1", image: t})), this.currentIndex = this.pois.length - 1, this.createClip(), this.render();
  569. }
  570. updatePoi(t, e) {
  571. this.pois[t] = Object.assign(Object.assign({}, this.pois[t]), e);
  572. }
  573. movePoi(t, e) {
  574. if (t + e >= 0 && t + e < this.pois.length) {
  575. const i = this.pois[t];
  576. this.pois[t] = this.pois[t + e], this.pois[t + e] = i, this.render();
  577. }
  578. }
  579. removePoi(t) {
  580. this.pois.splice(t, 1), this.render();
  581. }
  582. goToPoi(t) {
  583. const e = this.pois[t];
  584. this.rig.flyTo(e.position, e.quaternion, e.duration, e.ease, this.useSlerp);
  585. }
  586. createClip() {
  587. if (this.pois.length > 0) {
  588. const e = [], i = [], s = [], a = new Vector3(), o = new Quaternion(), c = 10;
  589. let p2 = 0;
  590. for (let t = 0; t < this.pois.length - 1; t++) {
  591. const n = this.pois[t], r = this.pois[t + 1], h = {px: n.position.x, py: n.position.y, pz: n.position.z, qx: n.quaternion.x, qy: n.quaternion.y, qz: n.quaternion.z, qw: n.quaternion.w, slerpAmount: 0}, d = {px: r.position.x, py: r.position.y, pz: r.position.z, qx: r.quaternion.x, qy: r.quaternion.y, qz: r.quaternion.z, qw: r.quaternion.w, slerpAmount: 1, duration: r.duration, ease: r.ease}, m3 = gsap2.to(h, d);
  592. for (let t2 = 0; t2 < c; t2++) {
  593. const d2 = r.duration * (t2 / c);
  594. e.push(p2 + d2), m3.seek(d2), this.useSlerp ? o.slerpQuaternions(n.quaternion, r.quaternion, h.slerpAmount) : o.set(h.qx, h.qy, h.qz, h.qw), a.set(h.px, h.py, h.pz), o.toArray(s, s.length), a.toArray(i, i.length);
  595. }
  596. p2 += r.duration;
  597. }
  598. const m2 = this.pois[this.pois.length - 1];
  599. m2.quaternion.toArray(s, s.length), m2.position.toArray(i, i.length), e.push(p2), this.animationClip = new AnimationClip(null, p2, [new VectorKeyframeTrack("Translation.position", e, i), new QuaternionKeyframeTrack("Rotation.quaternion", e, s)]), this.rig.setAnimationClip(this.animationClip);
  600. }
  601. }
  602. scrubClip(t) {
  603. this.pois.length > 0 && this.rig.setAnimationPercentage(t);
  604. }
  605. playClip() {
  606. this.pois.length > 0 && (this.isPlaying = true);
  607. }
  608. export() {
  609. if (this.pois.length > 0) {
  610. const t = {};
  611. t.pois = this.pois.map((t2) => ({position: [t2.position.x, t2.position.y, t2.position.z], quaternion: [t2.quaternion.x, t2.quaternion.y, t2.quaternion.z, t2.quaternion.w], duration: t2.duration, ease: t2.ease})), this.animationClip && (t.animationClip = AnimationClip.toJSON(this.animationClip));
  612. const e = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(t)), i = document.createElement("a");
  613. i.href = "data:" + e, i.download = "camera-data.json", document.body.appendChild(i), i.click(), i.remove();
  614. }
  615. }
  616. exportImages() {
  617. const t = document.createElement("a");
  618. document.body.appendChild(t), this.pois.forEach((e, i) => {
  619. t.href = e.image, t.download = `camera-poi-${i}.png`, t.click();
  620. }), t.remove();
  621. }
  622. initUI(t) {
  623. this.drawer = document.createElement("div"), this.drawer.classList.add("tb-ch");
  624. const e = document.createElement("button");
  625. e.classList.add("btn-round", "add"), e.innerText = "+", e.onclick = this.capture.bind(this), this.collapseBtn = document.createElement("button"), this.collapseBtn.classList.add("btn-round", "collapse"), this.collapseBtn.innerText = "<", this.collapseBtn.onclick = this.collapse.bind(this);
  626. const i = document.createElement("div");
  627. i.classList.add("controls");
  628. const s = document.createElement("button");
  629. s.classList.add("btn-text", "export"), s.innerText = "export JSON", s.onclick = this.export.bind(this);
  630. const n = document.createElement("button");
  631. n.classList.add("btn-text", "export-images"), n.innerHTML = "export images", n.onclick = this.exportImages.bind(this);
  632. const a = document.createElement("button");
  633. a.classList.add("btn-text", "play"), a.innerText = "play", a.onclick = this.playClip.bind(this);
  634. const o = document.createElement("input");
  635. o.type = "range", o.min = "0", o.max = "1000", o.step = "0.1", o.value = "0";
  636. const r = this.scrubClip.bind(this);
  637. o.onmousedown = () => this.rig.packTransform(), o.onmouseup = () => this.rig.unpackTransform(), o.oninput = (t2) => r(parseInt(t2.target.value) / 1e3), this.domList = document.createElement("div"), this.domList.classList.add("pois"), this.domList.onclick = this.handleEvents.bind(this), this.domList.onchange = this.handleEvents.bind(this), i.append(a, o, n, s), this.drawer.append(e, this.collapseBtn, this.domList, i);
  638. (t || document.body).append(this.drawer);
  639. }
  640. handleEvents(t) {
  641. const e = t.target.dataset.index;
  642. e && (t.target.classList.contains(Y) ? this.goToPoi(parseInt(e)) : t.target.classList.contains(W) ? this.removePoi(parseInt(e)) : t.target.classList.contains(B) ? this.updatePoi(parseInt(e), {duration: parseFloat(t.target.value)}) : t.target.classList.contains(X) ? this.updatePoi(parseInt(e), {ease: t.target.value}) : t.target.classList.contains(N) ? this.movePoi(parseInt(e), -1) : t.target.classList.contains(Z) && this.movePoi(parseInt(e), 1), this.createClip());
  643. }
  644. collapse() {
  645. this.drawer.classList.contains("collapsed") ? (this.drawer.classList.remove("collapsed"), this.collapseBtn.innerText = "<") : (this.drawer.classList.add("collapsed"), this.collapseBtn.innerText = ">");
  646. }
  647. render() {
  648. this.domList.innerHTML = "", this.pois.forEach((t, e) => {
  649. const i = document.createElement("div");
  650. i.classList.add("poi");
  651. const s = document.createElement("h2");
  652. s.innerText = `${e + 1}.`;
  653. const n = document.createElement("div");
  654. n.classList.add("wrapper");
  655. const a = document.createElement("div");
  656. a.classList.add("poi-controls");
  657. const o = document.createElement("div");
  658. o.classList.add("poi-params");
  659. const r = new Image();
  660. r.src = t.image;
  661. const h = document.createElement("label");
  662. h.innerText = "Duration";
  663. const d = document.createElement("input");
  664. d.classList.add(B), d.dataset.index = `${e}`, d.type = "number", d.value = String(t.duration);
  665. const c = document.createElement("label");
  666. c.innerText = "Easing";
  667. const l = document.createElement("select");
  668. l.classList.add(X), l.dataset.index = `${e}`;
  669. const p2 = j.map((e2) => {
  670. const i2 = document.createElement("option");
  671. return i2.innerText = e2, i2.value = e2, i2.selected = e2 === t.ease, i2;
  672. });
  673. l.append(...p2);
  674. const m2 = document.createElement("button");
  675. m2.classList.add(W), m2.title = "Remove", m2.dataset.index = `${e}`, m2.innerText = "x";
  676. const u2 = document.createElement("button");
  677. u2.classList.add(Y), u2.title = "Visit", u2.dataset.index = `${e}`, u2.innerHTML = "&rarr;";
  678. const g2 = document.createElement("button");
  679. g2.classList.add(N), g2.title = "Move up", g2.dataset.index = `${e}`, g2.innerHTML = "&uarr;";
  680. const b2 = document.createElement("button");
  681. b2.classList.add(Z), b2.title = "Move down", b2.dataset.index = `${e}`, b2.innerHTML = "&darr;", a.append(m2, u2, g2, b2), o.append(h, d, c, l), n.append(r, a), i.append(s, n, o), this.domList.appendChild(i);
  682. });
  683. }
  684. }
  685. export {g as Axis, x as BaseAdaptor, m as CameraAction, H as CameraHelper, v as CameraRig, p as Damper, k as FreeMovementControls, E as KeyboardAdaptor, U as PathPointsControls, P as PointerAdaptor, u as RigComponent, T as ScrollAdaptor, I as ScrollControls, q as StoryPointsControls, L as SwipeAdaptor, K as ThreeDOFControls, F as WheelAdaptor};
  686. export default null;