three.js生成的canvas保存至服务器无文件生成且右键存图为黑块问题求助
问题修复方案
1. 画布右键保存/导出为纯黑方块问题
原因
Three.js默认的WebGL渲染器会在每次绘制完成后自动清空绘图缓冲区,你调用toDataURL读取画布内容时,缓冲区已经被清空,只能拿到黑帧。
修复方法
创建WebGLRenderer时开启preserveDrawingBuffer配置项,保留绘图缓冲区内容:
// 原renderImageSolo函数内的渲染器创建代码修改为 const solo_renderer = new THREE.WebGLRenderer({ antialias: true, preserveDrawingBuffer: true, // 新增该行 alpha: true // 如果需要透明背景可新增该行,同时删除原错误的透明背景赋值代码 });
额外修正:你注释的透明背景实现逻辑错误,开启透明只需在渲染器参数加alpha: true,无需修改scene.background。如果需要透明背景,还可以把导出格式改为image/png适配透明通道。
2. 服务器未保存文件问题
常见原因&修复
- PHP代码缺少开头的
<?php标记,导致代码被当做文本输出而非执行 - 重复创建目录报错:原代码每次请求都执行
mkdir,目录已存在时会抛出错误,中断后续文件写入逻辑 - 目录权限不足:PHP运行用户对根目录或photos目录没有写入权限
- 前端AJAX请求发送失败:未引入jQuery、跨域等原因导致请求未到达后端
修正后的PHP代码
<?php if (!isset($_POST['photo'])) { die('无上传数据'); } $data = $_POST['photo']; list($type, $data) = explode(';', $data); list(, $data) = explode(',', $data); $data = base64_decode($data); $saveDir = $_SERVER['DOCUMENT_ROOT'] . "/photos/"; // 仅当目录不存在时递归创建,权限设置为755 if (!file_exists($saveDir)) { mkdir($saveDir, 0755, true); } // 校验目录可写 if (!is_writable($saveDir)) { die('目录无写入权限'); } // 前端导出为jpeg格式,后缀统一为jpg $savePath = $saveDir . time() . '.jpg'; $writeRes = file_put_contents($savePath, $data); if ($writeRes) { die('保存成功:' . basename($savePath)); } else { die('文件写入失败'); }
前端AJAX补充调试代码
添加回调排查请求问题:
function saveit() { const canvas = document.getElementById('canvas'); // 第二个参数设置jpeg导出质量,取值0~1 var photo = canvas.toDataURL('image/jpeg', 0.9); $.ajax({ method: 'POST', url: 'photo_upload.php', data: { photo: photo }, success: res => console.log('上传成功', res), error: err => console.log('上传失败', err) }); }
其他注意事项
- 确认页面已正确引入jQuery,否则
$.ajax会报错 - 若纹理图片
images/djmug2.jpg和站点域名不一致,需要配置纹理跨域,否则会污染画布导致toDataURL调用失败 - 可打开浏览器控制台和PHP错误日志排查具体报错信息
内容的提问来源于stack exchange,提问作者Glen Keybit
相关产品推荐
相关产品推荐

