diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 687eff323..c02cb4fcf 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -72,6 +72,7 @@ export default defineConfig({ { text: 'useAnimations', link: '/cientos/abstractions/use-animations' }, { text: 'Environment', link: '/cientos/abstractions/environment' }, { text: 'useEnvironment', link: '/cientos/abstractions/use-environment' }, + { text: 'usePamMouse', link: '/cientos/abstractions/pam-camera-mouse' }, ], }, { diff --git a/docs/cientos/abstractions/pam-camera-mouse.md b/docs/cientos/abstractions/pam-camera-mouse.md new file mode 100644 index 000000000..044cd67f2 --- /dev/null +++ b/docs/cientos/abstractions/pam-camera-mouse.md @@ -0,0 +1,33 @@ +# PamCameraMouse + +![](/cientos/PamCameraMouse.gif) + +`` is a component that allow you to create easily the pam mouse camera effect. The camera will update automatically according to the mouse position, creating a beautiful nice effect + +## Usage + +You only need import it and use it `` additionally you can pass two props, disabled and factor. Factor is a number to increase the movement range of the camera + +```vue + +``` + +::: warning +By the nature of the pam mouse camera effect it creates conflicts if it's used in combination with OrbitControls +::: + +## Props [[1]](#1) + +| Prop | Description | Default | +| :----------- | :------------------------------------------------------ | ------- | +| **disabled** | enable or disabled the effect, boolean | false | +| **factor** | Number use to increase the range of the camera movement | 5 | diff --git a/docs/public/cientos/PamCameraMouse.gif b/docs/public/cientos/PamCameraMouse.gif new file mode 100644 index 000000000..b405460aa Binary files /dev/null and b/docs/public/cientos/PamCameraMouse.gif differ diff --git a/packages/cientos/src/composables/useLogger.ts b/packages/cientos/src/composables/useLogger.ts new file mode 100644 index 000000000..d7d67a24b --- /dev/null +++ b/packages/cientos/src/composables/useLogger.ts @@ -0,0 +1,32 @@ +/* eslint-disable no-console */ +export const isProd = import.meta.env.MODE === 'production' + +const logPrefix = '[TresJS - Cientos ▲ ■ ♥] ' + +interface LoggerComposition { + logError: (message: string, error?: Error | ErrorEvent) => void + logWarning: (message: string) => void + logMessage: (name: string, value: any) => void +} + +export function useLogger(): LoggerComposition { + function logError(message: string, error?: Error | ErrorEvent) { + console.error(`${logPrefix} ${message}`, error || '') + } + + function logWarning(message: string) { + console.warn(`${logPrefix} ${message}`) + } + + function logMessage(name: string, value: any) { + if (!isProd) { + console.log(`${logPrefix} - ${name}:`, value) + } + } + + return { + logError, + logWarning, + logMessage, + } +} diff --git a/packages/cientos/src/core/TransformControls.vue b/packages/cientos/src/core/TransformControls.vue index 6fe9a6f79..804148c8d 100644 --- a/packages/cientos/src/core/TransformControls.vue +++ b/packages/cientos/src/core/TransformControls.vue @@ -67,8 +67,8 @@ function addEventListeners(controls: TransformControlsImp) { watch( () => props.object, () => { - if (state.camera?.value && state.renderer && state.scene && props.object) { - controls.value = new TransformControlsImp(state.camera.value, unref(state.renderer).domElement) + if (state.camera && state.renderer && state.scene && props.object) { + controls.value = new TransformControlsImp(state.camera, unref(state.renderer).domElement) controls.value.attach(unref(props.object)) state.scene.add(unref(controls) as TransformControlsImp) diff --git a/packages/cientos/src/core/usePamCameraMouse/component.ts b/packages/cientos/src/core/usePamCameraMouse/component.ts new file mode 100644 index 000000000..d14702a2b --- /dev/null +++ b/packages/cientos/src/core/usePamCameraMouse/component.ts @@ -0,0 +1,29 @@ +import { defineComponent } from 'vue' +import { usePamCameraMouse } from '.' +import { useCientos } from '../useCientos' + +export const PamCameraMouse = defineComponent({ + name: 'PamCameraMouse', + props: { + disabled: { + type: Boolean, + required: false, + default: false, + }, + factor: { + type: Number, + required: false, + default: 5, + }, + }, + setup(props: any) { + const { state } = useCientos() + const camera = state?.camera + + const PamCameraMouse = usePamCameraMouse(props.disabled as boolean, props.factor as number, camera) + + return () => { + PamCameraMouse + } + }, +}) diff --git a/packages/cientos/src/core/usePamCameraMouse/index.ts b/packages/cientos/src/core/usePamCameraMouse/index.ts new file mode 100644 index 000000000..66cc08b26 --- /dev/null +++ b/packages/cientos/src/core/usePamCameraMouse/index.ts @@ -0,0 +1,24 @@ +import { watchEffect, computed } from 'vue' +import { Camera } from 'three' +import { useWindowSize, useMouse } from '@vueuse/core' +import { useLogger } from '/@/composables/useLogger' + +export function usePamCameraMouse(disabled = false, factor = 5, camera: Camera | undefined) { + const { x, y } = useMouse() + const { logWarning } = useLogger() + const { width, height } = useWindowSize() + const cameraX = computed(() => (x.value / width.value - 0.5) * factor) + const cameraY = computed(() => -(y.value / height.value - 0.5) * factor) + if (camera) { + const { x: initX, y: initY } = camera.position + watchEffect(() => { + if (disabled) return + if (camera) { + camera.position.x = initX + cameraX.value + camera.position.y = initY + cameraY.value + } + }) + } else { + logWarning('Scene must contain a Camera component to use this composable') + } +} diff --git a/packages/cientos/src/index.ts b/packages/cientos/src/index.ts index af262b216..4389f8aa1 100644 --- a/packages/cientos/src/index.ts +++ b/packages/cientos/src/index.ts @@ -1,5 +1,6 @@ import OrbitControls from './core/OrbitControls.vue' import TransformControls from './core/TransformControls.vue' +import { PamCameraMouse } from './core/usePamCameraMouse/component' import { useTweakPane } from './core/useTweakPane' import { useAnimations } from './core/useAnimations' import { GLTFModel } from './core/useGLTF/component' @@ -23,6 +24,7 @@ import { Environment } from './core/useEnvironment/component' export * from './core/useGLTF' export * from './core/useFBX' export * from './core/useEnvironment' +export * from './core/usePamCameraMouse' export { OrbitControls, TransformControls, @@ -45,4 +47,5 @@ export { Dodecahedron, useAnimations, Environment, + PamCameraMouse, } diff --git a/packages/cientos/vite.config.ts b/packages/cientos/vite.config.ts index d7f09a399..ced9a48a1 100644 --- a/packages/cientos/vite.config.ts +++ b/packages/cientos/vite.config.ts @@ -13,7 +13,7 @@ import { lightGreen, yellow, gray, bold } from 'kolorist' import pkg from './package.json' // eslint-disable-next-line no-console -console.log(`${lightGreen('▲')} ${gray('■')} ${yellow('⚡️')} ${bold('Tres/cientos')} v${pkg.version}`) +console.log(`${lightGreen('▲')} ${gray('■')} ${yellow('♥')} ${bold('Tres/cientos')} v${pkg.version}`) // https://vitejs.dev/config/ export default defineConfig({ resolve: { diff --git a/packages/tres/src/App.vue b/packages/tres/src/App.vue index 5cadfca48..ddf7cec8f 100644 --- a/packages/tres/src/App.vue +++ b/packages/tres/src/App.vue @@ -1,11 +1,14 @@ diff --git a/packages/tres/src/components/TheEnvironment.vue b/packages/tres/src/components/TheEnvironment.vue index b80a24d73..08f834f30 100644 --- a/packages/tres/src/components/TheEnvironment.vue +++ b/packages/tres/src/components/TheEnvironment.vue @@ -1,6 +1,6 @@