Skip to content

Instantly share code, notes, and snippets.

@ejfox
Created January 17, 2024 18:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ejfox/295b31afc7d5d0e57de1237ac4d1c0d2 to your computer and use it in GitHub Desktop.
Save ejfox/295b31afc7d5d0e57de1237ac4d1c0d2 to your computer and use it in GitHub Desktop.
<script setup>
import { ref } from 'vue';
import { useElementBounding, useWindowSize } from '@vueuse/core';
import { useTres } from 'tresjs';
// `domElementRef` is a ref for the DOM element we want to map to the 3D scene
const domElementRef = ref(null);
// Use VueUse's useElementBounding to track the element's position and size
const { left, top, width, height } = useElementBounding(domElementRef);
// Reactive window size
const { width: windowWidth, height: windowHeight } = useWindowSize();
// tresjs scene, camera and renderer will be set up already in your application
const { scene, camera, renderer } = useTres();
// The function to map a DOM element's position to a 3D position
function mapDomElementTo3DPosition() {
if (!domElementRef.value) return;
// Convert element bounds to 3D coordinates
// Note that these calculations will likely need to be adjusted for Tresjs specifics.
// Convert screen space to normalized device coordinate (NDC) space
const xNDC = (left.value / windowWidth.value) * 2 - 1;
const yNDC = -(top.value / windowHeight.value) * 2 + 1;
// Convert NDC space to 3D world space
const vector3D = new THREE.Vector3(xNDC, yNDC, 0);
vector3D.unproject(camera.value);
// Converts from screen space into 3D world space
vector3D.applyMatrix4(camera.value.matrixWorldInverse);
vector3D.applyMatrix4(camera.value.projectionMatrixInverse);
return vector3D;
}
// A watcher or reactive effect can trigger the update of the 3D position
// whenever the DOM element's bounding box changes
watchEffect(() => {
const position3D = mapDomElementTo3DPosition();
// Update your 3D object's position in the Tresjs scene with `position3D`
// ...
});
</script>
<template>
<div ref="domElementRef">
<!-- Your DOM content here -->
</div>
<!-- Your Tresjs 3D canvas and context -->
</template>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment