<meta charset="utf-8" />
<script src='https://cdn.everxyz.com/fractal3d/sdk/webviewer/3d@4.6.31.js'></script>
<script src="https://cdn.everxyz.com/axios/dist/axios.min.js"></script>
2. sldprt,prt 等有装配关系, 但是不需要显示装配关系的文件显示
<div style="display: flex">
<input type="file" id="file" />
<button id="upload">上传</button>
<label id="status"></label>
<div style="padding: 15px 0;font-size: 12px">
注:此demo上传的需为复杂文件,否则converts接口会报错500。判断文件是否为复杂文件请查询
<a href="https://ever-xyz.feishu.cn/wiki/wikcn04EgZRPnFYCFbhHHXYVDQb">文件格式清单</a>
<div id="everapi-1" style="height: 600px; width: 800px;"></div>
function init_fractal3d(accessToken) {
const container = document.getElementById("everapi-1");
window.EverAPI._addInstance(
console.log(accessToken)
window.EverAPI.loginUtopia(accessToken, "https://portal.fractal3d.everxyz.com");
let instance = window.EverAPI.getInstanceById('everapi-1');
const get_access_token = async () => {
const res = await axios.post(
"https://portal.fractal3d.everxyz.com/api/users/access-token",
Authorization: "Bearer <API_KEY>",
const token = res.data.access_token;
const uploadFile = async (
onProgress /* (progress: number) => void */
// 调用 uploadFile 方法,将包装好的 formData 上传到服务器
const res = await axios.post(
"https://portal.fractal3d.everxyz.com/api/files",
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/octet-stream",
// 上传进度回调,需要注意的是,这里的进度是文件上传的进度, 接口最后会做一次校验,所以进度 100% 并不代表接口结束
const { loaded, total } = e;
onProgress((loaded / total) * 100);
return { filename, file_id };
const convert_exec = async (file_id, accessToken) => {
const result = await axios.post(
"https://portal.fractal3d.everxyz.com/api/converts",
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/octet-stream",
let { transaction_id } = result.data;
return { transaction_id };
// 需要注意的是, 这里的 url 是临时的,在一段时间后会失效,所以推荐做法是保存上传文件的 uuid,然后通过 uuid 查询文件的 url
// 参数 uuid 为 uploadFile 返回的 uuid
const pollingFileStatus = async (txId, accessToken) => {
// 使用 uploadFile 返回的 uuid 查询该文件的转换状态
const data = await axios.get("https://portal.fractal3d.everxyz.com/api/converts/result_file", {
Authorization: `Bearer ${accessToken}`,
status = data.data.status;
get_access_token().then((token) => {
console.log("no valid token");
instance = init_fractal3d(accessToken);
const onUpload = async () => {
// 这里使用了原生的 file input 获取文件,也可以使用其他方式获取文件
const file = document.getElementById("file").files[0];
const { filename, file_id } = await uploadFile(file, accessToken, (progress) => {
document.getElementById(
).innerText = `上传进度:${progress}%`;
document.getElementById("status").innerText = "上传成功,开始转换";
const { transaction_id } = await convert_exec(file_id.file_id, accessToken);
// 这里使用 Promise + setTimeout 实现轮询,也可以使用其他方式实现轮询
while (status === "Pending") {
await new Promise((resolve) => setTimeout(resolve, 1000));
({ status, url } = await pollingFileStatus(transaction_id, accessToken));
if (status === "Succeeded") {
document.getElementById("status").innerText = "转换成功";
const currentFiles = [{ filename, url }];
instance.openFiles(currentFiles);
} else if (status == "Failed") {
document.getElementById("status").innerText = "转换失败";
// set button onclick event
document.getElementById("upload").onclick = onUpload;