123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686 |
- import {Vector3, EventDispatcher, Object3D, PerspectiveCamera, Quaternion, Euler, AnimationMixer, AnimationClip, VectorKeyframeTrack, QuaternionKeyframeTrack} from "./three.js";
- import {TweenMax, gsap as gsap2} from "./gsap.js";
- class p {
- constructor(t) {
- this.epsilon = 1e-3, this.values = {}, this.targetValues = {}, this.deltaValues = {}, Object.assign(this.values, t.values), Object.assign(this.targetValues, t.values), this.deltaValues = {};
- for (const t2 in this.values)
- this.deltaValues[t2] = 0;
- this.dampingFactor = t.dampingFactor, t.epsilon && (this.epsilon = t.epsilon), this.hasReached = true;
- }
- update() {
- const t = {};
- let e = true;
- for (const i in this.values)
- t[i] = this.targetValues[i] - this.values[i], e = e && Math.abs(t[i]) < this.epsilon;
- if (e) {
- for (const e2 in this.values)
- this.deltaValues[e2] = t[e2], this.values[e2] = this.targetValues[e2];
- this.hasReached = true;
- } else
- for (const e2 in this.values)
- this.deltaValues[e2] = this.dampingFactor * t[e2], this.values[e2] += this.deltaValues[e2];
- }
- setTarget(t) {
- for (const e in t)
- this.targetValues[e] = t[e];
- this.hasReached = false;
- }
- addToTarget(t, e) {
- this.targetValues[t] += e, this.hasReached = false;
- }
- resetAll(t) {
- for (const e in this.values)
- this.targetValues[e] = t, this.values[e] = t, this.deltaValues[e] = 0;
- this.hasReached = true;
- }
- resetData(t) {
- for (const e in t)
- this.targetValues[e] = t[e], this.values[e] = t[e], this.deltaValues[e] = 0;
- this.hasReached = true;
- }
- getCurrentValues() {
- return Object.assign({}, this.values);
- }
- getDeltaValues() {
- return Object.assign({}, this.deltaValues);
- }
- reachedTarget() {
- return this.hasReached;
- }
- }
- var m, u, g;
- !function(t) {
- t.Pan = "Pan", t.Tilt = "Tilt", t.Roll = "Roll", t.Truck = "Truck", t.Pedestal = "Pedestal", t.Dolly = "Dolly", t.Zoom = "Zoom";
- }(m || (m = {})), function(t) {
- t.Body = "body", t.Head = "head", t.Eyes = "eyes";
- }(u || (u = {})), function(t) {
- t.X = "x", t.Y = "y", t.Z = "z";
- }(g || (g = {}));
- 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}};
- class v extends EventDispatcher {
- constructor(t, e) {
- 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();
- }
- getAxisFor(t) {
- return this.actionAxes[t];
- }
- getAxisVectorFor(t) {
- return b[this.actionAxes[t]];
- }
- do(t, e, i) {
- const n = this[i];
- switch (t) {
- case m.Pan:
- case m.Tilt:
- case m.Roll: {
- const i2 = this.getAxisVectorFor(t);
- n ? n.rotateOnAxis(i2, e) : this.translateAlong[t] ? this.body.rotateOnAxis(i2, e) : this.eyes.rotateOnAxis(i2, e);
- break;
- }
- case m.Truck: {
- const t2 = this.getAxisVectorFor(m.Tilt);
- (n || this.body).translateOnAxis(t2, e);
- break;
- }
- case m.Pedestal: {
- const t2 = this.getAxisVectorFor(m.Pan);
- (n || this.body).translateOnAxis(t2, e);
- break;
- }
- case m.Dolly: {
- const t2 = this.getAxisVectorFor(m.Roll);
- (n || this.body).translateOnAxis(t2, e);
- break;
- }
- case m.Zoom:
- this.camera instanceof PerspectiveCamera && (this.camera.fov = e, this.camera.updateProjectionMatrix());
- }
- }
- getWorldCoordinates() {
- const e = new Vector3();
- this.camera.getWorldPosition(e);
- const i = new Quaternion();
- return this.camera.getWorldQuaternion(i), {position: e, quaternion: i};
- }
- setWorldCoordinates({position: t, quaternion: e}) {
- const i = new Euler().setFromQuaternion(e, this.getRotationOrder()), s = [m.Pan, m.Tilt, m.Roll];
- 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) => {
- const e2 = this.getAxisFor(t2);
- this.translateAlong[t2] ? this.body.rotation[e2] = i[e2] : this.eyes.rotation[e2] = i[e2];
- }), this.camera.rotation.set(0, 0, 0), this.camera.position.set(0, 0, 0);
- }
- packTransform() {
- const {position: t, quaternion: e} = this.getWorldCoordinates();
- 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);
- }
- unpackTransform() {
- const {position: t, quaternion: e} = this.getWorldCoordinates();
- this.setWorldCoordinates({position: t, quaternion: e});
- }
- disassemble() {
- this.cameraIsInRig && (this.scene.attach(this.camera), this.cameraIsInRig = false);
- }
- assemble() {
- this.cameraIsInRig || (this.eyes.attach(this.camera), this.unpackTransform(), this.cameraIsInRig = true);
- }
- getRotationOrder() {
- return Object.values(this.actionAxes).join("").toUpperCase();
- }
- isInRig() {
- return this.cameraIsInRig;
- }
- isMoving() {
- return this.inTransit;
- }
- setUpAxis(t) {
- this.upAxis = t, this.actionAxes = y[this.upAxis], this.body.rotation.order = this.getRotationOrder();
- }
- setAnimationClip(t, e, i) {
- 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);
- const s = this.mixer.clipAction(this.animationClip);
- s.clampWhenFinished = true, s.play();
- }
- flyTo(t, e, i = 1, s = "power1", n = true) {
- if (!this.isMoving()) {
- 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 = () => {
- this.inTransit = true, this.packTransform(), this.dispatchEvent({type: "CameraMoveStart"});
- }, d = (t2) => {
- 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()});
- }, l = () => {
- this.inTransit = false, this.unpackTransform(), this.dispatchEvent({type: "CameraMoveEnd"});
- };
- TweenMax.to(o, Object.assign(Object.assign({duration: i, ease: s}, r), {onStart: h, onUpdate: function() {
- d(this);
- }, onComplete: l}));
- }
- }
- flyToKeyframe(t, e = 1, i = "power1") {
- if (this.hasAnimation && !this.isMoving()) {
- const s = {time: this.mixer.time}, n = {time: this.animationClip.tracks[0].times[t]}, a = () => {
- this.inTransit = true, this.dispatchEvent({type: "CameraMoveStart"});
- }, o = (t2) => {
- this.mixer.setTime(s.time), this.dispatchEvent({type: "CameraMoveUpdate", progress: t2.progress()});
- }, r = () => {
- this.inTransit = false, this.dispatchEvent({type: "CameraMoveEnd"});
- };
- TweenMax.to(s, Object.assign(Object.assign({duration: e, ease: i}, n), {onStart: a, onUpdate: function() {
- o(this);
- }, onComplete: r}));
- }
- }
- setAnimationPercentage(t) {
- if (this.hasAnimation) {
- const e = Math.max(0, Math.min(t * this.animationClip.duration, this.animationClip.duration - 1e-4));
- this.mixer.setTime(e);
- }
- }
- setAnimationTime(t) {
- this.hasAnimation && this.mixer.setTime(t);
- }
- setAnimationKeyframe(t) {
- this.hasAnimation && this.mixer.setTime(this.animationClip.tracks[0].times[t]);
- }
- }
- class x extends EventDispatcher {
- constructor() {
- super();
- }
- }
- 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};
- class E extends x {
- constructor(t) {
- super(), Object.assign(this, f, t);
- const e = {};
- for (const t2 in this.keyMapping)
- e[t2] = 0;
- this.damper = new p({values: e, dampingFactor: this.dampingFactor}), this.onKeyUp = this.onKeyUp.bind(this), this.onKeyDown = this.onKeyDown.bind(this);
- }
- connect() {
- document.addEventListener("keyup", this.onKeyUp, true), document.addEventListener("keydown", this.onKeyDown, true), this.connected = true;
- }
- disconnect() {
- document.removeEventListener("keyup", this.onKeyUp, true), document.removeEventListener("keydown", this.onKeyDown, true), this.connected = false;
- }
- update() {
- 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"})));
- }
- isEnabled() {
- return this.connected;
- }
- onKeyUp(t) {
- if (this.type === "discrete") {
- for (const e in this.keyMapping)
- if (this.keyMapping[e].includes(t.key)) {
- this.preventBubbling && t.preventDefault(), this.dispatchEvent({type: "trigger", trigger: e});
- break;
- }
- }
- }
- onKeyDown(t) {
- if (this.type === "continuous") {
- for (const e in this.keyMapping)
- if (this.keyMapping[e].includes(t.key)) {
- this.preventBubbling && t.preventDefault(), this.damper.addToTarget(e, this.incrementor);
- break;
- }
- }
- }
- }
- const w = {domElement: document.body, dampingFactor: 0.5, shouldNormalize: true, normalizeAroundZero: true, multipointerThreshold: 100};
- class P extends x {
- constructor(t) {
- 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);
- }
- connect() {
- 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;
- }
- disconnect() {
- 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;
- }
- update(t) {
- 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"}));
- }
- isEnabled() {
- return this.connected;
- }
- setDimensions() {
- this.width = this.domElement.getBoundingClientRect().width, this.height = this.domElement.getBoundingClientRect().height;
- }
- getPointerPosition(t) {
- 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))};
- }
- normalize(t, e) {
- let i = t.x / this.width, s = t.y / this.height;
- return e && (i = 2 * i - 1, s = 2 * s - 1), {x: i, y: s};
- }
- onPointerMove(t) {
- 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)));
- }
- onPointerDown(t) {
- t.button === 0 && (this.cache.push(t), this.lastDownTime = window.performance.now());
- }
- onPointerUp(t) {
- if (t.button === 0 || t.type === "pointerleave") {
- for (let e = 0; e < this.cache.length; e++)
- if (this.cache[e].pointerId == t.pointerId) {
- this.cache.splice(e, 1);
- break;
- }
- this.lastUpTime = window.performance.now();
- }
- }
- onResize() {
- this.setDimensions();
- }
- }
- const A = {startOffset: "0px", endOffset: "0px", buffer: 0.1, dampingFactor: 0.5};
- class T extends x {
- constructor(t) {
- 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();
- }
- connect() {
- window.addEventListener("scroll", this.onScroll, {passive: true}), this.resizeObserver.observe(document.body), this.connected = true;
- }
- disconnect() {
- window.removeEventListener("scroll", this.onScroll), this.resizeObserver.unobserve(document.body), this.connected = false;
- }
- update() {
- if (this.lastSeenScrollValue !== this.previousScrollValue && this.lastSeenScrollValue >= this.bufferedStartPosition && this.lastSeenScrollValue <= this.bufferedEndPosition) {
- const t = Math.max(0, Math.min(this.distance, this.lastSeenScrollValue - this.startPosition)), e = Math.max(0, Math.min(1, t / this.distance));
- this.values = {scrollPx: t, scrollPercent: e}, this.damper.setTarget(this.values), this.previousScrollValue = this.lastSeenScrollValue;
- }
- this.damper.reachedTarget() || (this.damper.update(), this.dispatchEvent({type: "update", values: this.values, dampenedValues: this.damper.getCurrentValues()}), this.damper.reachedTarget() && this.dispatchEvent({type: "inertiacomplete"}));
- }
- isEnabled() {
- return this.connected;
- }
- parseOffset(t) {
- let e = 0;
- 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;
- }
- calculateOffset(t) {
- return t ? this.calculateOffset(t.offsetParent) + t.offsetTop : 0;
- }
- calculateDimensions() {
- const t = this.scrollElement.clientHeight, e = this.calculateOffset(this.scrollElement);
- 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);
- }
- onScroll() {
- this.lastSeenScrollValue = window.scrollY;
- }
- }
- const C = {domElement: document.body, thresholdX: 60, thresholdY: 60};
- class L extends x {
- constructor(t = {}) {
- super(), Object.assign(this, C, t), this.onPointerUp = this.onPointerUp.bind(this), this.onPointerDown = this.onPointerDown.bind(this);
- }
- connect() {
- this.domElement.addEventListener("pointerdown", this.onPointerDown, {passive: true}), this.domElement.addEventListener("pointerup", this.onPointerUp, {passive: true}), this.connected = true;
- }
- disconnect() {
- this.domElement.removeEventListener("pointerdown", this.onPointerDown), this.domElement.removeEventListener("pointerup", this.onPointerUp), this.connected = false;
- }
- update() {
- }
- isEnabled() {
- return this.connected;
- }
- onPointerDown(t) {
- t.pointerType !== "mouse" && t.isPrimary && (this.startX = t.screenX, this.startY = t.screenY);
- }
- onPointerUp(t) {
- if (t.pointerType !== "mouse" && t.isPrimary) {
- const e = t.screenX - this.startX, i = t.screenY - this.startY;
- (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});
- }
- }
- }
- const S = {dampingFactor: 0.5, thresholdX: 15, thresholdY: 15, debounceDuration: 700};
- class F extends x {
- constructor(t) {
- 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);
- }
- connect() {
- (this.domElement || window).addEventListener("wheel", this.onWheel, {passive: true}), this.connected = true;
- }
- disconnect() {
- (this.domElement || window).removeEventListener("wheel", this.onWheel), this.connected = false;
- }
- update() {
- 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"})));
- }
- isEnabled() {
- return this.connected;
- }
- onWheel(t) {
- if (this.type === "continuous")
- this.damper.addToTarget("x", t.deltaX), this.damper.addToTarget("y", t.deltaY);
- else if (this.type === "discrete" && (Math.abs(t.deltaX) >= this.thresholdX || Math.abs(t.deltaY) >= this.thresholdY)) {
- const e = window.performance.now();
- 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}));
- }
- }
- }
- 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};
- class k {
- constructor(t, e = {}) {
- 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);
- }
- isEnabled() {
- return this.enabled;
- }
- enable() {
- 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;
- }
- disable() {
- 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;
- }
- onWheel(t) {
- this.cameraRig.do(m.Dolly, t.deltas.y * this.wheelScaleFactor), this.cameraRig.do(m.Truck, t.deltas.x * this.wheelScaleFactor);
- }
- onKey(t) {
- 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);
- }
- onPointer(t) {
- switch (t.pointerCount) {
- case 1:
- this.cameraRig.do(m.Pan, t.deltas.x * this.panDegreeFactor), this.cameraRig.do(m.Tilt, t.deltas.y * this.tiltDegreeFactor);
- break;
- case 2:
- this.cameraRig.do(m.Dolly, -t.deltas.y * this.pointerScaleFactor), this.cameraRig.do(m.Truck, -t.deltas.x * this.pointerScaleFactor);
- }
- }
- update(t) {
- this.enabled && (this.keyboardAdaptor.update(), this.wheelAdaptor.update(), this.pointerAdaptor.update(t));
- }
- }
- 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));
- class I {
- constructor(t, e) {
- 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);
- }
- isEnabled() {
- return this.enabled;
- }
- enable() {
- this.scrollAdaptor.connect(), this.scrollAdaptor.addEventListener("update", this.onScroll), this.enabled = true;
- }
- disable() {
- this.scrollAdaptor.disconnect(), this.scrollAdaptor.removeEventListener("update", this.onScroll), this.enabled = false;
- }
- update() {
- this.enabled && this.scrollAdaptor.update();
- }
- calculateStops() {
- 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) => {
- 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);
- });
- }
- onScroll(t) {
- const e = t.dampenedValues.scrollPx;
- e >= this.cameraBufferedStartPx && e <= this.cameraBufferedEndPx && this.cameraRig.setAnimationPercentage(M(e, this.cameraStartPx, this.cameraEndPx, 0, 1)), this.scrollActions.forEach((t2) => {
- e >= t2.bufferedStartPx && e <= t2.bufferedEndPx && t2.callback(M(e, t2.startPx, t2.endPx, 0, 1));
- });
- }
- }
- const D = {cycle: false, useKeyboard: true};
- class q extends EventDispatcher {
- constructor(t, e = [], i = {}) {
- 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);
- }
- getCurrentIndex() {
- return this.currentIndex;
- }
- nextPOI() {
- const t = this.currentIndex + 1;
- t >= this.pois.length && !this.cycle ? this.dispatchEvent({type: "ExitPOIs", exitFrom: "end"}) : this.goToPOI(t % this.pois.length);
- }
- prevPOI() {
- const t = this.currentIndex - 1;
- t < 0 && !this.cycle ? this.dispatchEvent({type: "ExitPOIs", exitFrom: "start"}) : this.goToPOI((t + this.pois.length) % this.pois.length);
- }
- goToPOI(t) {
- this.upcomingIndex = t;
- const e = this.pois[this.upcomingIndex];
- this.cameraRig.flyTo(e.position, e.quaternion, e.duration, e.ease);
- }
- enable() {
- 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;
- }
- disable() {
- 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;
- }
- update() {
- }
- isEnabled() {
- return this.enabled;
- }
- updatePois(t) {
- this.dispatchEvent({type: "update", currentIndex: this.currentIndex, upcomingIndex: this.upcomingIndex, progress: t});
- }
- onCameraStart() {
- this.updatePois(0);
- }
- onCameraUpdate(t) {
- this.updatePois(t.progress);
- }
- onCameraEnd() {
- this.currentIndex = this.upcomingIndex, this.upcomingIndex = null;
- }
- onKey(t) {
- t.trigger === "next" ? this.nextPOI() : t.trigger === "prev" && this.prevPOI();
- }
- }
- const z = {wheelThreshold: 15, swipeThreshold: 60, duration: 1, ease: "power1", useKeyboard: true};
- class U extends EventDispatcher {
- constructor(t, e = [], i = {}) {
- 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);
- }
- getCurrentIndex() {
- return this.currentIndex;
- }
- enable() {
- 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;
- }
- disable() {
- 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;
- }
- update() {
- }
- isEnabled() {
- return this.enabled;
- }
- onKey(t) {
- switch (t.trigger) {
- case "prev":
- this.onTrigger({y: -1});
- break;
- case "next":
- this.onTrigger({y: 1});
- }
- }
- onTrigger(t) {
- const e = this.currentIndex + t.y;
- 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));
- }
- updatePois(t) {
- this.dispatchEvent({type: "update", currentIndex: this.currentIndex, upcomingIndex: this.upcomingIndex, progress: t});
- }
- onCameraStart() {
- this.updatePois(0);
- }
- onCameraUpdate(t) {
- this.updatePois(t.progress);
- }
- onCameraEnd() {
- this.currentIndex = this.upcomingIndex, this.upcomingIndex = null;
- }
- }
- const V = {domElement: document.body, panFactor: Math.PI / 20, tiltFactor: Math.PI / 20, truckFactor: 1, pedestalFactor: 1, dampingFactor: 0.7};
- class K {
- constructor(t, e = {}) {
- 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);
- }
- isEnabled() {
- return this.enabled;
- }
- enable() {
- this.pointerAdaptor.connect(), this.pointerAdaptor.addEventListener("update", this.onPointerMove), this.enabled = true;
- }
- disable() {
- this.pointerAdaptor.disconnect(), this.pointerAdaptor.removeEventListener("update", this.onPointerMove), this.enabled = false;
- }
- update(t) {
- this.enabled && this.pointerAdaptor.update(t);
- }
- onPointerMove(t) {
- 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));
- }
- }
- !function(t, e) {
- e === void 0 && (e = {});
- var i = e.insertAt;
- if (t && typeof document != "undefined") {
- var s = document.head || document.getElementsByTagName("head")[0], n = document.createElement("style");
- 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));
- }
- }(".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");
- const j = ["none", "power1", "power2", "power3", "power4", "sine", "expo", "circ"], Y = "visit", W = "remove", B = "duration", X = "ease", N = "move-up", Z = "move-down";
- class H {
- constructor(t, e, i, s) {
- 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);
- }
- capture() {
- this.doCapture = true;
- }
- update(t) {
- if (this.doCapture) {
- const t2 = this.canvas.toDataURL();
- this.addPoi(t2), this.doCapture = false;
- }
- if (this.isPlaying) {
- this.playStartTime || (this.playStartTime = t, this.controls.disable(), this.rig.packTransform());
- const e = (t - this.playStartTime) / 1e3;
- this.rig.setAnimationTime(e), e > this.animationClip.duration && (this.isPlaying = false, this.playStartTime = null, this.controls.enable(), this.rig.unpackTransform());
- }
- }
- addPoi(t) {
- 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();
- }
- updatePoi(t, e) {
- this.pois[t] = Object.assign(Object.assign({}, this.pois[t]), e);
- }
- movePoi(t, e) {
- if (t + e >= 0 && t + e < this.pois.length) {
- const i = this.pois[t];
- this.pois[t] = this.pois[t + e], this.pois[t + e] = i, this.render();
- }
- }
- removePoi(t) {
- this.pois.splice(t, 1), this.render();
- }
- goToPoi(t) {
- const e = this.pois[t];
- this.rig.flyTo(e.position, e.quaternion, e.duration, e.ease, this.useSlerp);
- }
- createClip() {
- if (this.pois.length > 0) {
- const e = [], i = [], s = [], a = new Vector3(), o = new Quaternion(), c = 10;
- let p2 = 0;
- for (let t = 0; t < this.pois.length - 1; t++) {
- 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);
- for (let t2 = 0; t2 < c; t2++) {
- const d2 = r.duration * (t2 / c);
- 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);
- }
- p2 += r.duration;
- }
- const m2 = this.pois[this.pois.length - 1];
- 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);
- }
- }
- scrubClip(t) {
- this.pois.length > 0 && this.rig.setAnimationPercentage(t);
- }
- playClip() {
- this.pois.length > 0 && (this.isPlaying = true);
- }
- export() {
- if (this.pois.length > 0) {
- const t = {};
- 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));
- const e = "text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(t)), i = document.createElement("a");
- i.href = "data:" + e, i.download = "camera-data.json", document.body.appendChild(i), i.click(), i.remove();
- }
- }
- exportImages() {
- const t = document.createElement("a");
- document.body.appendChild(t), this.pois.forEach((e, i) => {
- t.href = e.image, t.download = `camera-poi-${i}.png`, t.click();
- }), t.remove();
- }
- initUI(t) {
- this.drawer = document.createElement("div"), this.drawer.classList.add("tb-ch");
- const e = document.createElement("button");
- 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);
- const i = document.createElement("div");
- i.classList.add("controls");
- const s = document.createElement("button");
- s.classList.add("btn-text", "export"), s.innerText = "export JSON", s.onclick = this.export.bind(this);
- const n = document.createElement("button");
- n.classList.add("btn-text", "export-images"), n.innerHTML = "export images", n.onclick = this.exportImages.bind(this);
- const a = document.createElement("button");
- a.classList.add("btn-text", "play"), a.innerText = "play", a.onclick = this.playClip.bind(this);
- const o = document.createElement("input");
- o.type = "range", o.min = "0", o.max = "1000", o.step = "0.1", o.value = "0";
- const r = this.scrubClip.bind(this);
- 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);
- (t || document.body).append(this.drawer);
- }
- handleEvents(t) {
- const e = t.target.dataset.index;
- 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());
- }
- collapse() {
- this.drawer.classList.contains("collapsed") ? (this.drawer.classList.remove("collapsed"), this.collapseBtn.innerText = "<") : (this.drawer.classList.add("collapsed"), this.collapseBtn.innerText = ">");
- }
- render() {
- this.domList.innerHTML = "", this.pois.forEach((t, e) => {
- const i = document.createElement("div");
- i.classList.add("poi");
- const s = document.createElement("h2");
- s.innerText = `${e + 1}.`;
- const n = document.createElement("div");
- n.classList.add("wrapper");
- const a = document.createElement("div");
- a.classList.add("poi-controls");
- const o = document.createElement("div");
- o.classList.add("poi-params");
- const r = new Image();
- r.src = t.image;
- const h = document.createElement("label");
- h.innerText = "Duration";
- const d = document.createElement("input");
- d.classList.add(B), d.dataset.index = `${e}`, d.type = "number", d.value = String(t.duration);
- const c = document.createElement("label");
- c.innerText = "Easing";
- const l = document.createElement("select");
- l.classList.add(X), l.dataset.index = `${e}`;
- const p2 = j.map((e2) => {
- const i2 = document.createElement("option");
- return i2.innerText = e2, i2.value = e2, i2.selected = e2 === t.ease, i2;
- });
- l.append(...p2);
- const m2 = document.createElement("button");
- m2.classList.add(W), m2.title = "Remove", m2.dataset.index = `${e}`, m2.innerText = "x";
- const u2 = document.createElement("button");
- u2.classList.add(Y), u2.title = "Visit", u2.dataset.index = `${e}`, u2.innerHTML = "→";
- const g2 = document.createElement("button");
- g2.classList.add(N), g2.title = "Move up", g2.dataset.index = `${e}`, g2.innerHTML = "↑";
- const b2 = document.createElement("button");
- b2.classList.add(Z), b2.title = "Move down", b2.dataset.index = `${e}`, b2.innerHTML = "↓", 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);
- });
- }
- }
- 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};
- export default null;
|