You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Three.js实现字符串字符依次缩放动画失败,求解决

字符依次缩放动画的Three.js代码问题排查与修复

你的代码无法正常运行的核心问题在于字符几何体复用错误,以及位置计算的不合理,以下是具体问题分析和修复方案:

问题分析

  1. 几何体复用错误:你创建了一个包含完整文本的TextGeometry,然后用它生成所有字符的网格,导致每个网格渲染的都是完整的"Hello, World!",而非单个字符,自然看不到预期的逐个缩放效果。
  2. 位置计算不合理:固定的80像素间距没有考虑不同字符的实际宽度,会导致字符重叠或间距不均,影响视觉效果。

修复后的代码

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Zoom In/Out Text Animation</title>
    <style>
        body {
            margin: 0;
            padding: 0;
            background-color: #000;
        }
        canvas {
            display: block;
        }
    </style>
</head>
<body>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
    <script>
        // 初始化场景、相机、渲染器
        const scene = new THREE.Scene();
        const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000);
        const renderer = new THREE.WebGLRenderer();
        renderer.setSize(window.innerWidth, window.innerHeight);
        document.body.appendChild(renderer.domElement);

        // 文本内容与字体加载
        const text = "Hello, World!";
        const fontLoader = new THREE.FontLoader();
        fontLoader.load('https://threejs.org/examples/fonts/helvetiker_regular.typeface.json', function(font) {
            const material = new THREE.MeshBasicMaterial({color: 0xffffff});
            const meshes = [];
            let totalWidth = 0;
            const charGeometries = [];

            // 先创建所有字符的几何体,计算总宽度
            for (let i = 0; i < text.length; i++) {
                const charGeometry = new THREE.TextGeometry(text[i], {
                    font: font,
                    size: 50,
                    height: 5,
                    curveSegments: 12,
                    bevelEnabled: true,
                    bevelThickness: 2,
                    bevelSize: 1,
                    bevelSegments: 5
                });
                charGeometry.computeBoundingBox();
                charGeometries.push(charGeometry);
                totalWidth += charGeometry.boundingBox.max.x - charGeometry.boundingBox.min.x;
                // 字符间添加间距
                totalWidth += 20;
            }

            // 计算起始位置,让文本居中
            let currentX = -totalWidth / 2;

            // 创建每个字符的网格并设置位置
            for (let i = 0; i < text.length; i++) {
                const geometry = charGeometries[i];
                const mesh = new THREE.Mesh(geometry, material);
                // 让字符基于自身中心定位
                const charWidth = geometry.boundingBox.max.x - geometry.boundingBox.min.x;
                mesh.position.x = currentX + charWidth / 2;
                currentX += charWidth + 20;
                meshes.push(mesh);
                scene.add(mesh);
            }

            // 动画函数:逐个字符缩放
            const animate = function () {
                requestAnimationFrame(animate);
                const time = Date.now() * 0.002;
                meshes.forEach((mesh, index) => {
                    // 每个字符的动画延迟依次递增,实现依次缩放效果
                    const scale = Math.sin(time + index * Math.PI / 4) * 0.3 + 1.0;
                    mesh.scale.set(scale, scale, scale);
                });
                renderer.render(scene, camera);
            };

            animate();
        });

        // 设置相机位置
        camera.position.z = 300;
    </script>
</body>
</html>

关键修复点

  • 为每个字符单独创建TextGeometry,确保每个网格只渲染单个字符。
  • 通过computeBoundingBox()计算每个字符的实际宽度,动态调整位置,让文本居中且间距合理。
  • 调整动画的相位偏移,让字符缩放的先后顺序更明显,增强依次动画的效果。
  • 增加相机z轴距离,确保所有字符都在视野范围内。

内容的提问来源于stack exchange,提问作者Humberto José Bortolossi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 05:55:02