diff --git a/src/common/experiences/navigation.model.ts b/src/common/experiences/navigation.model.ts index 80d2f3c..736733a 100644 --- a/src/common/experiences/navigation.model.ts +++ b/src/common/experiences/navigation.model.ts @@ -2,6 +2,7 @@ import type { Spherical, Vector3 } from "three"; export interface NavigationView { enabled?: boolean; + controls?: boolean; center?: Vector3; spherical?: { smoothed: Spherical; diff --git a/src/config/common.config.ts b/src/config/common.config.ts index ac1d616..26a9820 100644 --- a/src/config/common.config.ts +++ b/src/config/common.config.ts @@ -5,7 +5,7 @@ export abstract class CommonConfig { "M0,0 C0.001,0.001 0.002,0.003 0.003,0.004 0.142,0.482 0.284,0.75 0.338,0.836 0.388,0.924 0.504,1 1,1"; static readonly DEBUG = (() => { try { - return useRuntimeConfig().public.env === "development"; + return useRuntimeConfig().public.env !== "development"; } catch (_) { return false; } diff --git a/src/experiences/home/camera-aninmation.ts b/src/experiences/home/camera-aninmation.ts new file mode 100644 index 0000000..33a1dc3 --- /dev/null +++ b/src/experiences/home/camera-aninmation.ts @@ -0,0 +1,177 @@ +import { CatmullRomCurve3, Vector3 } from "three"; +import { gsap } from "gsap"; + +// EXPERIENCES +import { HomeExperience } from "."; + +// BLUEPRINTS +import { ExperienceBasedBlueprint } from "~/blueprints/experiences/experience-based.blueprint"; +import { Config } from "~/config"; + +export const defaultCameraPath = new CatmullRomCurve3([ + new Vector3(0, 5.5, 21), + new Vector3(12, 10, 12), + new Vector3(21, 5.5, 0), + new Vector3(12, 3.7, 12), + new Vector3(0, 5.5, 21), +]); +export const defaultCameraTarget = new Vector3(0, 2, 0); + +export class CameraAnimation extends ExperienceBasedBlueprint { + protected readonly _experience = new HomeExperience(); + + private readonly _appSizes = this._experience.app.sizes; + private readonly _appCamera = this._experience.app.camera; + private readonly _camera = this._experience.camera; + private readonly _navigation = this._experience.navigation; + + public enabled = false; + public cameraPath = defaultCameraPath; + public cameraTarget = defaultCameraTarget; + public progress = { + current: 0, + target: 0, + ease: 0.1, + }; + public positionInCurve = new Vector3(); + public reversed = false; + public timeline = gsap.timeline(); + public mouseDowned = false; + public cursorCoordinate = { x: 0, y: 0 }; + public normalizedCursorCoordinate = { x: 0, y: 0 }; + + private _onWheel?: (e: WheelEvent) => unknown; + private _onMousemove?: (e: MouseEvent) => unknown; + private _onMousedown?: (e: MouseEvent) => unknown; + private _onMouseUp?: (e: MouseEvent) => unknown; + + private _wheelEvent(e: WheelEvent) { + if (!this.enabled) return; + + if (e.deltaY < 0) { + this.progress.target += 0.05; + this.reversed = false; + + return; + } + + this.progress.target -= 0.05; + this.reversed = true; + } + + private _mouseMoveEvent(e: MouseEvent) { + if (this.enabled && this.mouseDowned) { + if (e.clientX < this.cursorCoordinate.x) { + this.progress.target += 0.002; + this.reversed = false; + } else if (e.clientX > this.cursorCoordinate.x) { + this.progress.target -= 0.002; + this.reversed = true; + } + } + + if (!this.enabled) { + this.normalizedCursorCoordinate.x = + e.clientX / this._appSizes?.width - 0.5; + this.normalizedCursorCoordinate.y = + e.clientY / this._appSizes?.height - 0.5; + } + + this.cursorCoordinate = { x: e.clientX, y: e.clientY }; + } + + private _mouseDownEvent(e: MouseEvent) { + this.mouseDowned = true; + // if (this.focusedPosition && !this.mouseOverBubble) + // this._camera?.cameraZoomIn(); + } + + private _mouseUpEvent(e: MouseEvent) { + this.mouseDowned = false; + // if (this.focusedPosition && !this.mouseOverBubble) + // this._experience.camera?.cameraZoomOut(); + } + + public construct() { + this._onWheel = (e) => this._wheelEvent(e); + this._onMousemove = (e) => this._mouseMoveEvent(e); + this._onMousedown = (e) => this._mouseDownEvent(e); + this._onMouseUp = (e) => this._mouseUpEvent(e); + + window.addEventListener("wheel", this._onWheel); + window.addEventListener("mousemove", this._onMousemove); + window.addEventListener("mousedown", this._onMousedown); + window.addEventListener("mouseup", this._onMouseUp); + } + + public destruct() { + this._onWheel && window.removeEventListener("wheel", this._onWheel); + this._onMousemove && + window.removeEventListener("mousemove", this._onMousemove); + this._onMousedown && + window.removeEventListener("mousedown", this._onMousedown); + this._onMouseUp && window.removeEventListener("mouseup", this._onMouseUp); + } + + public enable() { + if (this.enabled) return; + if (this._navigation?.view) this._navigation.view.controls = false; + + const toPosition = this.cameraPath.getPointAt( + this.progress.current, + this.positionInCurve + ); + + this._navigation + ?.updateCameraPosition(toPosition, this.cameraTarget) + .then(() => { + this.enabled = true; + }); + } + + public disable() { + if (!this.enabled) return; + this.enabled = false; + + if (this.timeline.isActive()) this.timeline.progress(1); + + this._navigation + ?.updateCameraPosition( + this.positionInCurve.setY(2), + this.cameraTarget, + Config.GSAP_ANIMATION_DURATION * 0.5 + ) + .then(() => { + if (this._navigation?.view) this._navigation.view.controls = true; + }); + } + + public update(): void { + if (!this.enabled || this.timeline.isActive()) return; + + this.progress.current = gsap.utils.interpolate( + this.progress.current, + this.progress.target, + this.progress.ease + ); + this.progress.target = + this.progress.target + (this.reversed ? -0.0001 : 0.0001); + + if (this.progress.target > 1) { + setTimeout(() => { + this.reversed = true; + }, 1000); + } + + if (this.progress.target < 0) { + setTimeout(() => { + this.reversed = false; + }, 1000); + } + this.progress.target = gsap.utils.clamp(0, 1, this.progress.target); + this.progress.current = gsap.utils.clamp(0, 1, this.progress.current); + this.cameraPath.getPointAt(this.progress.current, this.positionInCurve); + + this._navigation?.setPositionInSphere(this.positionInCurve); + } +} diff --git a/src/experiences/home/camera.ts b/src/experiences/home/camera.ts index 3560ee5..f13f245 100644 --- a/src/experiences/home/camera.ts +++ b/src/experiences/home/camera.ts @@ -3,7 +3,6 @@ import gsap from "gsap"; // EXPERIENCES import { HomeExperience } from "."; -import { Navigation } from "./navigation"; // BLUEPRINTS import { ExperienceBasedBlueprint } from "~/blueprints/experiences/experience-based.blueprint"; @@ -78,9 +77,6 @@ export class Camera extends ExperienceBasedBlueprint { this._appDebug?.cameraHelper?.dispose(); } - if (this._experience.app.debug?.cameraControls) - this._experience.app.debug.cameraControls.enabled = false; - if (!(this._appCameraInstance instanceof PerspectiveCamera)) return; this.correctAspect(); diff --git a/src/experiences/home/debug.ts b/src/experiences/home/debug.ts index faf6302..bedd872 100644 --- a/src/experiences/home/debug.ts +++ b/src/experiences/home/debug.ts @@ -28,6 +28,7 @@ export class Debug extends ExperienceBasedBlueprint { protected readonly _appDebug = this._experience.app.debug; protected readonly _appCamera = this._experience.app.camera; protected readonly _camera = this._experience.camera; + protected readonly _cameraAnimation = this._experience.cameraAnimation; protected readonly _worldCameraHelpers?: CameraHelper[] = []; protected _gui?: GUI; @@ -44,12 +45,16 @@ export class Debug extends ExperienceBasedBlueprint { if (this._gui) this.destruct(); this._gui = this._experience.app.debug?.ui?.addFolder(HomeExperience.name); + if (this._appDebug?.cameraControls) { + this._appDebug.cameraControls.dispose(); + this._appDebug.cameraControls = undefined; + } if (!this._gui || !this._experience.world) return; this.cameraLookAtPointIndicator = new Mesh( new SphereGeometry(0.1, 12, 12), - new MeshBasicMaterial({ color: "#ff0040" }), + new MeshBasicMaterial({ color: "#ff0040" }) ); this.cameraLookAtPointIndicator.visible = false; this._camera?.cameras.forEach((item, id) => { @@ -67,17 +72,17 @@ export class Debug extends ExperienceBasedBlueprint { !this.cameraLookAtPointIndicator.visible; }, }, - "fn", + "fn" ) .name("Toggle LookAt indicator visibility"); this._cameraCurvePathLine = new Line( new BufferGeometry().setFromPoints( - [...Array(3).keys()].map(() => new Vector3(0, 0, 0)), + [...Array(3).keys()].map(() => new Vector3(0, 0, 0)) ), new LineBasicMaterial({ color: 0xff0000, - }), + }) ); this._gui @@ -98,7 +103,7 @@ export class Debug extends ExperienceBasedBlueprint { : this._experience.camera?.cameraZoomOut(); }, }, - "fn", + "fn" ) .name("Toggle camera zoom"); @@ -106,19 +111,19 @@ export class Debug extends ExperienceBasedBlueprint { .add( { fn: () => { - const WorldManager = this._experience.world?.manager; - if (WorldManager) - WorldManager.autoCameraAnimation = - !WorldManager.autoCameraAnimation; + if (this._cameraAnimation?.enabled === true) + this._cameraAnimation.disable(); + else if (this._cameraAnimation?.enabled === false) + this._cameraAnimation.enable(); }, }, - "fn", + "fn" ) .name("Toggle auto camera animation"); this._experience.app.scene.add( this._cameraCurvePathLine, - this.cameraLookAtPointIndicator, + this.cameraLookAtPointIndicator ); } @@ -156,7 +161,7 @@ export class Debug extends ExperienceBasedBlueprint { this._appCamera?.instance && this._experience.camera && this.cameraLookAtPointIndicator?.position.copy( - this._experience.camera.lookAtPosition, + this._experience.camera.lookAtPosition ); } } diff --git a/src/experiences/home/index.ts b/src/experiences/home/index.ts index b7c948e..9f7d652 100644 --- a/src/experiences/home/index.ts +++ b/src/experiences/home/index.ts @@ -23,6 +23,8 @@ import { ErrorFactory } from "~/errors"; // MODELS import type { ExperienceConstructorProps } from "~/common/experiences/experience.model"; +import { CameraAnimation } from "./camera-aninmation"; +import { Vector3 } from "three"; export class HomeExperience extends ExperienceBlueprint { public ui?: UI; @@ -32,6 +34,7 @@ export class HomeExperience extends ExperienceBlueprint { public composer?: Composer; public camera?: Camera; public world?: World; + public cameraAnimation?: CameraAnimation; public navigation?: Navigation; public debug?: Debug; @@ -41,7 +44,7 @@ export class HomeExperience extends ExperienceBlueprint { HomeExperience._self ?? { ..._, debug: Config.DEBUG, - }, + } ); if (HomeExperience._self) return HomeExperience._self; HomeExperience._self = this; @@ -54,6 +57,7 @@ export class HomeExperience extends ExperienceBlueprint { this.camera = new Camera(); this.world = new World(); this.navigation = new Navigation(); + this.cameraAnimation = new CameraAnimation(); this.debug = new Debug(); } catch (_err) { throw new ErrorFactory(_err); @@ -73,6 +77,7 @@ export class HomeExperience extends ExperienceBlueprint { this.camera?.destruct(); this.world?.destruct(); this.navigation?.destruct(); + this.cameraAnimation?.destruct(); this.debug?.destruct(); this.app.destroy(); @@ -94,6 +99,7 @@ export class HomeExperience extends ExperienceBlueprint { this.renderer?.construct(); this.world?.construct(); this.navigation?.construct(); + this.cameraAnimation?.construct(); this.debug?.construct(); this.app?.setUpdateCallback(HomeExperience.name, () => this.update()); this._onConstruct?.(); @@ -102,6 +108,8 @@ export class HomeExperience extends ExperienceBlueprint { } }); this.loader?.construct(); + + this.camera?.setCameraLookAt(new Vector3(0, 2, 0)); } catch (_) { throw new ErrorFactory(_); } @@ -111,6 +119,7 @@ export class HomeExperience extends ExperienceBlueprint { try { this.world?.update(); this.camera?.update(); + this.cameraAnimation?.update(); this.navigation?.update(); this.composer?.update(); this.debug?.update(); diff --git a/src/experiences/home/navigation.ts b/src/experiences/home/navigation.ts index 8f98f9d..441548d 100644 --- a/src/experiences/home/navigation.ts +++ b/src/experiences/home/navigation.ts @@ -80,6 +80,7 @@ export class Navigation extends ExperienceBasedBlueprint { private _setView() { this._view.enabled = true; + this._view.controls = true; this._view.center = new Vector3(); @@ -114,6 +115,7 @@ export class Navigation extends ExperienceBasedBlueprint { }; this._view.move = (_x, _y) => { if ( + !this.view.controls || !this._view.enabled || !this._view?.drag?.delta || !this._view.drag.previous @@ -140,6 +142,7 @@ export class Navigation extends ExperienceBasedBlueprint { _event.preventDefault(); if ( + !this.view.controls || !this._view.enabled || !this._view.drag || !this._view.down || @@ -264,7 +267,12 @@ export class Navigation extends ExperienceBasedBlueprint { this._view.onWheel = (_event) => { _event.preventDefault(); - if (!this._view.enabled || !this._view.zooming || !this._view.onWheel) + if ( + !this.view.controls || + !this._view.enabled || + !this._view.zooming || + !this._view.onWheel + ) return; const normalized = normalizeWheel(_event); @@ -278,6 +286,7 @@ export class Navigation extends ExperienceBasedBlueprint { passive: false, } ); + this._ui?.targetElementParent?.addEventListener( "wheel", this._view.onWheel, @@ -316,7 +325,63 @@ export class Navigation extends ExperienceBasedBlueprint { this._appSizes.on("resize", () => this._setConfig()); } - public destruct() {} + public destruct() { + if (!this.view) return; + + this._view.onMouseDown && + this._ui?.targetElementParent?.removeEventListener( + "mousedown", + this._view.onMouseDown + ); + + this._view.onMouseUp && + this._ui?.targetElementParent?.removeEventListener( + "mouseup", + this._view.onMouseUp + ); + + this._view.onMouseMove && + this._ui?.targetElementParent?.removeEventListener( + "mousemove", + this._view.onMouseMove + ); + + this._view.onTouchEnd && + this._ui?.targetElementParent?.removeEventListener( + "touchend", + this._view.onTouchEnd + ); + + this._view.onTouchMove && + this._ui?.targetElementParent?.removeEventListener( + "touchmove", + this._view.onTouchMove + ); + + this._view.onTouchStart && + this._ui?.targetElementParent?.removeEventListener( + "touchstart", + this._view.onTouchStart + ); + + this._view.onContextMenu && + this._ui?.targetElementParent?.removeEventListener( + "contextmenu", + this._view.onContextMenu + ); + + this._view.onWheel && + this._ui?.targetElementParent?.removeEventListener( + "mousewheel", + this._view.onWheel + ); + + this._view.onWheel && + this._ui?.targetElementParent?.removeEventListener( + "wheel", + this._view.onWheel + ); + } public disableFreeAzimuthRotation(limits?: { min: number; max: number }) { if (this._view.spherical?.limits) { @@ -388,46 +453,41 @@ export class Navigation extends ExperienceBasedBlueprint { /** * Move the camera position with transition from * the origin position to the passed position and, - * update the lookAt position using the passed lookAt position. + * update the lookAt position using the passed target position. * * @param toPosition The new camera position. - * @param lookAt Where the camera will look at. + * @param target Where the camera will look at. */ public updateCameraPosition( toPosition = new Vector3(), lookAt = new Vector3(), - onStart: gsap.Callback = () => {}, - onUpdate: gsap.Callback = () => {}, - onComplete: gsap.Callback = () => {} + duration = Config.GSAP_ANIMATION_DURATION ) { if (!this._appCamera.instance) return this._timeline; - const lookAtA = this._view.target?.value?.clone(); - const lookAtB = lookAt.clone(); + const targetA = this._view.target?.value?.clone(); + const targetB = lookAt.clone(); const currentCamPosition = this._appCamera.instance?.position.clone(); - if (!lookAtA || !lookAtB || !currentCamPosition) return this._timeline; + if (!targetA || !targetB || !currentCamPosition) return this._timeline; return this._timeline.to(currentCamPosition, { x: toPosition.x, y: toPosition.y, z: toPosition.z, - duration: Config.GSAP_ANIMATION_DURATION, + duration, ease: Config.GSAP_ANIMATION_EASE, onStart: () => { - gsap.to(lookAtA, { - x: lookAtB.x, - y: lookAtB.y, - z: lookAtB.z, - duration: Config.GSAP_ANIMATION_DURATION * 0.55, + gsap.to(targetA, { + x: targetB.x, + y: targetB.y, + z: targetB.z, + duration: duration * 0.55, ease: Config.GSAP_ANIMATION_EASE, onUpdate: () => { - this?.setTargetPosition(lookAtA); - onUpdate(); + this?.setTargetPosition(targetA); }, }); - - onStart(); }, onUpdate: () => { if ( @@ -438,7 +498,6 @@ export class Navigation extends ExperienceBasedBlueprint { return; this.setPositionInSphere(currentCamPosition); }, - onComplete, }); } diff --git a/src/experiences/home/ui.ts b/src/experiences/home/ui.ts index f9f9904..3df8347 100644 --- a/src/experiences/home/ui.ts +++ b/src/experiences/home/ui.ts @@ -8,6 +8,7 @@ import { Config } from "~/config"; // BLUEPRINTS import { ExperienceBasedBlueprint } from "~/blueprints/experiences/experience-based.blueprint"; +import { PerspectiveCamera, type Vector3 } from "three"; /** * Class in charge of all the direct interactions with the DOM HTML elements. @@ -15,6 +16,8 @@ import { ExperienceBasedBlueprint } from "~/blueprints/experiences/experience-ba export class UI extends ExperienceBasedBlueprint { protected readonly _experience = new HomeExperience(); + private readonly _appCamera = this._experience.app.camera; + private _loadedResourcesProgressLineElements?: HTMLElement | null; private _loadedResourcesProgressElements?: HTMLElement | null; private _lastLoadedResourceElement?: HTMLElement | null; @@ -22,6 +25,11 @@ export class UI extends ExperienceBasedBlueprint { public readonly targetElement = this._experience.app.canvas; public readonly targetElementParent = this.targetElement?.parentElement; + public bubblesInfo: { + coordinate: Vector3; + element: HTMLElement; + }[] = []; + constructor() { super(); @@ -108,4 +116,25 @@ export class UI extends ExperienceBasedBlueprint { }, }); } + + public update(): void { + if (!(this._appCamera.instance instanceof PerspectiveCamera)) return; + + for (const bubble of this.bubblesInfo) { + if (bubble.element) { + const screenPosition = bubble.coordinate.clone(); + screenPosition.project(this._appCamera.instance); + + const translateX = + screenPosition.x * this._experience.app.sizes.width * 0.5; + const translateY = -( + screenPosition.y * + this._experience.app.sizes.height * + 0.5 + ); + + bubble.element.style.transform = `translate(${translateX}px, ${translateY}px)`; + } + } + } } diff --git a/src/experiences/home/world/manager.ts b/src/experiences/home/world/manager.ts index 5f68ef7..b8061ff 100644 --- a/src/experiences/home/world/manager.ts +++ b/src/experiences/home/world/manager.ts @@ -1,11 +1,4 @@ -import { - CatmullRomCurve3, - Material, - Mesh, - PerspectiveCamera, - Raycaster, - Vector3, -} from "three"; +import { Material, Mesh, Raycaster, Vector3 } from "three"; import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass"; import gsap, { Power0 } from "gsap"; @@ -19,7 +12,7 @@ import { ExperienceBasedBlueprint } from "~/blueprints/experiences/experience-ba import { Config } from "~/config"; // STATIC -import { errors, events, pages } from "~/static"; +import { errors, events } from "~/static"; // ERROR import { ErrorFactory } from "~/errors"; @@ -64,53 +57,7 @@ export class WorldManager extends ExperienceBasedBlueprint { glassEffectDefault: { duration: 0.3, ease: Power0.easeIn }, }; - // TODO: Reorder properties public rayCaster = new Raycaster(); - public normalizedCursorPosition = { x: 0, y: 0 }; - /** - * The curve path of the camera - */ - public cameraCurvePath = new CatmullRomCurve3([ - new Vector3(0, 5.5, 21), - new Vector3(12, 10, 12), - new Vector3(21, 5.5, 0), - new Vector3(12, 3.7, 12), - new Vector3(0, 5.5, 21), - ]); - /** - * Current curve path position of the camera. - */ - public cameraCurvePosition = new Vector3(); - public cameraCurvePathProgress = { - current: 0, - target: 0, - ease: 0.1, - }; - /** - * Enable auto curve path animation - */ - public autoCameraAnimation = false; - /** - * gsap animation watcher. If gsap is currently animating - */ - public isGsapAnimating = false; - /** - * Curve path backward animation - */ - public backwardCurveAnimation = false; - public focusPointPositionIndex = 0; - public focusedPosition?: Vector3; - public focusedRadius = 2; - public focusedAngleX = 0; - public focusedAngleY = 0; - public mouseDowned = false; - public mouseOverBubble = false; - public lastMouseCoordinate = { x: 0, y: 0 }; - public modelBubbles: { - coordinates: Vector3; - DOMelement: HTMLElement; - }[] = []; - // === ^ private get _supportedPageKeys() { if (!this._world?.availablePageScenes) return []; @@ -371,8 +318,7 @@ export class WorldManager extends ExperienceBasedBlueprint { SCREEN_POSITION, 0.84 ), - SCREEN_POSITION, - () => {} + SCREEN_POSITION ) .add(() => { this._triggerGlassTransitionEffect().add(() => { @@ -406,172 +352,5 @@ export class WorldManager extends ExperienceBasedBlueprint { public destruct() {} - public updateModelBubblesDomElements() { - const _CAMERA = this._appCameraInstance; - if (!(_CAMERA instanceof PerspectiveCamera)) return; - - for (const bubble of this.modelBubbles) { - if (bubble.DOMelement) { - const screenPosition = bubble.coordinates.clone(); - screenPosition.project(_CAMERA); - - const translateX = - screenPosition.x * this._experience.app.sizes.width * 0.5; - const translateY = -( - screenPosition.y * - this._experience.app.sizes.height * - 0.5 - ); - bubble.DOMelement.style.transform = `translate(${translateX}px, ${translateY}px)`; - } - } - } - - public setWheelEventListener() { - window.addEventListener("wheel", (e) => { - if (this.autoCameraAnimation === false) return; - - if (e.deltaY < 0) { - this.cameraCurvePathProgress.target += 0.05; - this.backwardCurveAnimation = false; - - return; - } - - this.cameraCurvePathProgress.target -= 0.05; - this.backwardCurveAnimation = true; - }); - } - - public setMouseMoveEventListener() { - window.addEventListener("mousemove", (e) => { - if (this.autoCameraAnimation === true && this.mouseDowned) { - if (e.clientX < this.lastMouseCoordinate.x) { - this.cameraCurvePathProgress.target += 0.002; - this.backwardCurveAnimation = false; - } else if (e.clientX > this.lastMouseCoordinate.x) { - this.cameraCurvePathProgress.target -= 0.002; - this.backwardCurveAnimation = true; - } - } - - if (!this.autoCameraAnimation) { - this.normalizedCursorPosition.x = - e.clientX / this._experience.app?.sizes.width - 0.5; - this.normalizedCursorPosition.y = - e.clientY / this._experience.app?.sizes.height - 0.5; - } - - this.lastMouseCoordinate = { x: e.clientX, y: e.clientY }; - }); - } - - public setMouseDownEventListener() { - window.addEventListener("mousedown", () => { - this.mouseDowned = true; - if (this.focusedPosition && !this.mouseOverBubble) - this._experience.camera?.cameraZoomIn(); - }); - } - - public setMouseUpEventListener() { - window.addEventListener("mouseup", () => { - this.mouseDowned = false; - if (this.focusedPosition && !this.mouseOverBubble) - this._experience.camera?.cameraZoomOut(); - }); - } - - public getFocusedLookAtPosition(position = this.focusedPosition) { - if (!(position && this._appCameraInstance)) return new Vector3(); - - return new Vector3( - position.x - - this.focusedRadius * - Math.cos( - this.focusedAngleX - - this._appCameraInstance.rotation.y + - Math.PI * 0.5 - ), - position.y - this.focusedRadius * Math.sin(this.focusedAngleY), - position.z - - this.focusedRadius * - Math.sin( - this.focusedAngleX - - this._appCameraInstance.rotation.y + - Math.PI * 0.5 - ) - ); - } - - public getGsapDefaultProps() { - return { - onStart: () => { - this.isGsapAnimating = true; - }, - onComplete: () => { - this.isGsapAnimating = false; - }, - }; - } - - public update() { - if (this.autoCameraAnimation && !this.isGsapAnimating) { - this.cameraCurvePathProgress.current = gsap.utils.interpolate( - this.cameraCurvePathProgress.current, - this.cameraCurvePathProgress.target, - this.cameraCurvePathProgress.ease - ); - this.cameraCurvePathProgress.target = - this.cameraCurvePathProgress.target + - (this.backwardCurveAnimation ? -0.0001 : 0.0001); - - if (this.cameraCurvePathProgress.target > 1) { - setTimeout(() => { - this.backwardCurveAnimation = true; - }, 1000); - } - - if (this.cameraCurvePathProgress.target < 0) { - setTimeout(() => { - this.backwardCurveAnimation = false; - }, 1000); - } - this.cameraCurvePathProgress.target = gsap.utils.clamp( - 0, - 1, - this.cameraCurvePathProgress.target - ); - this.cameraCurvePathProgress.current = gsap.utils.clamp( - 0, - 1, - this.cameraCurvePathProgress.current - ); - this.cameraCurvePath.getPointAt( - this.cameraCurvePathProgress.current, - this.cameraCurvePosition - ); - this._appCameraInstance?.position.copy(this.cameraCurvePosition); - } - - if ( - this._appCameraInstance && - !this.autoCameraAnimation && - this.focusedPosition && - !this.isGsapAnimating - ) - this._camera?.setCameraLookAt(this.getFocusedLookAtPosition()); - - this.updateModelBubblesDomElements(); - - if (this.autoCameraAnimation || !this.isGsapAnimating) - this._experience.camera?.setCameraLookAt( - this._camera?.lookAtPosition ?? new Vector3() - ); - - this.focusedAngleX += - (this.normalizedCursorPosition.x * Math.PI - this.focusedAngleX) * 0.1; - this.focusedAngleY += - (this.normalizedCursorPosition.y * Math.PI - this.focusedAngleY) * 0.1; - } + public update() {} }