
本文介绍如何通过 requestanimationframe 实现 three.js 场景的持续渲染,并结合 php 动态数据(如 mysql 查询结果)实时更新相机位置,避免页面刷新即可驱动模型视角动态变化。
本文介绍如何通过 requestanimationframe 实现 three.js 场景的持续渲染,并结合 php 动态数据(如 mysql 查询结果)实时更新相机位置,避免页面刷新即可驱动模型视角动态变化。
要让 Three.js 模型根据后端实时数据(例如通过 PHP 从 MySQL 获取的坐标值)动态调整视角,关键在于建立持续的渲染循环,并在每一帧中主动读取并应用最新坐标——而非仅在初始化时静态赋值一次。
当前代码的问题在于:camera.position.set(...) 仅在 init() 中执行一次,后续即使 $xaxis、yaxis、zaxis 对应的 DOM 元素或隐藏变量已更新,Three.js 并不会自动感知或重绘。同时,render() 未被持续调用,导致场景“冻结”。
✅ 正确做法是启用动画循环,并在其中动态获取最新坐标值。由于 PHP 变量在服务端渲染后即固化为静态值,需改用客户端方式获取实时数据,推荐以下两种方案:
方案一:通过 AJAX 轮询(简单可靠)
// 在 init() 之后、animate() 启动前添加:
let cameraPosition = { x: <?php echo $xaxis; ?>, y: <?php echo $yaxis; ?>, z: <?php echo $zaxis; ?> };
function fetchCameraData() {
return fetch('./get-camera-position.php') // 返回 JSON: { "x": 12.5, "y": -8.3, "z": 42 }
.then(res => res.json())
.catch(err => console.warn('Failed to fetch position:', err));
}
function animate() {
requestAnimationFrame(animate);
// 每帧更新(或按需降低频率,如每 500ms)
if (performance.now() % 1000 {
camera.position.set(pos.x, pos.y, pos.z);
camera.lookAt(80, 65, 35); // 可选:同步更新观察目标
});
}
render();
}
? get-camera-position.php 示例:
<?php header('Content-Type: application/json'); // 此处执行实时 SQL 查询(注意防注入、加缓存/限频) $stmt = $pdo->query("SELECT x, y, z FROM camera_state ORDER BY updated_at DESC LIMIT 1"); echo json_encode($stmt->fetch(PDO::FETCH_ASSOC)); ?>
方案二:使用 Server-Sent Events(SSE)实现低延迟推送(进阶)
若需毫秒级响应,可由 PHP 后端主动推送坐标变更事件,前端监听:
const eventSource = new EventSource("./stream-camera.php");
eventSource.onmessage = e => {
const pos = JSON.parse(e.data);
camera.position.set(pos.x, pos.y, pos.z);
};
⚠️ 关键注意事项:
- 移除 render() 的一次性调用:原代码中 loader.load(..., function() { scene.add(object); render(); }) 仅渲染一帧,必须替换为持续 animate() 循环;
- 避免阻塞主线程:AJAX 请求建议设 cache: false 或添加时间戳参数防止浏览器缓存旧值;
- 性能优化:requestAnimationFrame 本身约 60fps,无需额外 setTimeout;坐标更新频率应与业务需求匹配(如每秒 1–10 次),避免过度请求;
- 坐标一致性:确保 PHP 输出的坐标单位、坐标系(如 up.set(0,0,1) 对应 Z-up)与 Three.js 场景严格一致;
- 错误降级:网络失败时保留上一次有效位置,避免 camera.position.set(NaN, NaN, NaN) 导致崩溃。
最后,在 init() 结尾启动动画循环:
// 替换原 init() 末尾的 render() 调用 animate(); // ✅ 启动持续渲染
如此改造后,模型将真正“活”起来——无需刷新页面,即可随数据库中坐标的实时变化平滑旋转、平移,为工业监控、远程设备可视化等场景提供可靠交互基础。











