Drag to rotate
+
+
+
{{ nametag }}
@@ -88,7 +95,19 @@
import * as THREE from 'three'
import { useGLTF } from '@tresjs/cientos'
import { useTexture, TresCanvas, useRenderLoop } from '@tresjs/core'
-import { shallowRef, ref, computed, watch, markRaw, onBeforeMount, onUnmounted, toRefs } from 'vue'
+import {
+ shallowRef,
+ ref,
+ computed,
+ watch,
+ markRaw,
+ onBeforeMount,
+ onUnmounted,
+ toRefs,
+ useTemplateRef,
+ onMounted,
+ nextTick,
+} from 'vue'
import {
applyTexture,
applyCapeTexture,
@@ -129,12 +148,12 @@ const props = withDefaults(
capeSrc: undefined,
initialRotation: 15.75,
nametag: undefined,
- animationConfig: {
+ animationConfig: () => ({
baseAnimation: 'idle',
randomAnimations: [],
randomAnimationInterval: 8000,
transitionDuration: 0.5,
- }
+ }),
},
)
@@ -161,6 +180,30 @@ const clock = new THREE.Clock()
const currentAnimation = ref
('')
const randomAnimationTimer = ref(null)
+const nametagElement = useTemplateRef('nametagElement')
+const maxContainerWidth = ref(300)
+
+const dynamicNametagFontSize = computed(() => {
+ if (!props.nametag) return '2rem'
+ const textLength = props.nametag.length
+ const baseSize = 32
+ const minSize = 12
+ const maxSize = 32
+ const availableWidth = maxContainerWidth.value - 64
+ const estimatedCharWidth = baseSize * 0.6
+ const estimatedTextWidth = textLength * estimatedCharWidth
+ const scaleFactor = availableWidth / estimatedTextWidth
+ const calculatedSize = Math.max(minSize, Math.min(maxSize, baseSize * scaleFactor))
+
+ return `${calculatedSize}px`
+})
+
+const updateContainerWidth = () => {
+ if (nametagElement.value?.parentElement) {
+ maxContainerWidth.value = nametagElement.value.parentElement.clientWidth
+ }
+}
+
const { baseAnimation, randomAnimations } = toRefs(props.animationConfig)
function initializeAnimations(loadedScene: THREE.Object3D, clips: THREE.AnimationClip[]) {
@@ -480,9 +523,25 @@ watch(
setupRandomAnimationLoop()
}
},
- { deep: true }
+ { deep: true },
)
+watch(
+ () => props.nametag,
+ () => {
+ nextTick(() => {
+ updateContainerWidth()
+ })
+ },
+)
+
+onMounted(() => {
+ nextTick(() => {
+ updateContainerWidth()
+ window.addEventListener('resize', updateContainerWidth)
+ })
+})
+
onBeforeMount(async () => {
try {
isTextureLoaded.value = false
@@ -512,13 +571,15 @@ onUnmounted(() => {
mixer.value.stopAllAction()
mixer.value = null
}
+
+ window.removeEventListener('resize', updateContainerWidth)
})