更新图钉 API 文档及代码
This commit is contained in:
258
demo/index.html
258
demo/index.html
@@ -344,8 +344,235 @@
|
||||
let unsubscribePresetSaved = null;
|
||||
let unsubscribePresetChanged = null;
|
||||
let unsubscribePresetDeleted = null;
|
||||
let unsubscribePinCreated = null;
|
||||
let unsubscribePinDeleted = null;
|
||||
let unsubscribePinChanged = null;
|
||||
const PIN_CACHE_KEY = 'iflow-demo-pins-v1';
|
||||
let pinCache = [];
|
||||
|
||||
// 主视图缓存相关
|
||||
let unsubscribeMainViewSaved = null;
|
||||
let unsubscribeMainViewRestored = null;
|
||||
let unsubscribeModelLoaded = null;
|
||||
const MAIN_VIEW_CACHE_KEY = 'iflow-demo-main-view-v1';
|
||||
|
||||
function loadMainViewCache() {
|
||||
try {
|
||||
const raw = localStorage.getItem(MAIN_VIEW_CACHE_KEY);
|
||||
if (!raw) return {};
|
||||
const parsed = JSON.parse(raw);
|
||||
return typeof parsed === 'object' && parsed !== null ? parsed : {};
|
||||
} catch (error) {
|
||||
console.warn('读取主视图缓存失败:', error);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function saveMainViewCache(cache) {
|
||||
localStorage.setItem(MAIN_VIEW_CACHE_KEY, JSON.stringify(cache));
|
||||
}
|
||||
|
||||
function saveMainViewToCache(url, viewData) {
|
||||
const cache = loadMainViewCache();
|
||||
cache[url] = {
|
||||
viewData: viewData,
|
||||
timestamp: Date.now()
|
||||
};
|
||||
saveMainViewCache(cache);
|
||||
console.log('💾 主视图已缓存:', url);
|
||||
}
|
||||
|
||||
function applyMainViewIfExists(url) {
|
||||
const cache = loadMainViewCache();
|
||||
const cached = cache[url];
|
||||
if (cached && cached.viewData) {
|
||||
if (engine && engine.engine) {
|
||||
engine.engine.setMainViewPort(cached.viewData);
|
||||
console.log('✅ 已应用缓存的主视图:', url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function clearMainViewCache(url) {
|
||||
const cache = loadMainViewCache();
|
||||
if (cache[url]) {
|
||||
delete cache[url];
|
||||
saveMainViewCache(cache);
|
||||
console.log('🗑️ 主视图缓存已清除:', url);
|
||||
}
|
||||
}
|
||||
|
||||
function bindMainViewEvents() {
|
||||
if (!engine || typeof engine.on !== 'function') return;
|
||||
|
||||
if (unsubscribeMainViewSaved) {
|
||||
unsubscribeMainViewSaved();
|
||||
unsubscribeMainViewSaved = null;
|
||||
}
|
||||
if (unsubscribeModelLoaded) {
|
||||
unsubscribeModelLoaded();
|
||||
unsubscribeModelLoaded = null;
|
||||
}
|
||||
|
||||
// 监听主视图保存事件
|
||||
unsubscribeMainViewSaved = engine.on('view:main-view-saved', (data) => {
|
||||
console.log('[Demo] view:main-view-saved:', data);
|
||||
saveMainViewToCache(current3dModelUrl, data.viewData);
|
||||
});
|
||||
|
||||
// 监听主视图重置事件
|
||||
unsubscribeMainViewRestored = engine.on('view:main-view-restored', () => {
|
||||
console.log('[Demo] view:main-view-restored');
|
||||
clearMainViewCache(current3dModelUrl);
|
||||
});
|
||||
|
||||
// 监听模型加载完成事件
|
||||
unsubscribeModelLoaded = engine.on('engine:model-loading-completed', () => {
|
||||
console.log('[Demo] engine:model-loading-completed, applying main view if exists');
|
||||
applyMainViewIfExists(current3dModelUrl);
|
||||
});
|
||||
|
||||
console.log('✅ 主视图事件绑定完成');
|
||||
}
|
||||
|
||||
function loadPinCache() {
|
||||
try {
|
||||
const raw = localStorage.getItem(PIN_CACHE_KEY);
|
||||
if (!raw) return [];
|
||||
const parsed = JSON.parse(raw);
|
||||
return Array.isArray(parsed) ? parsed : [];
|
||||
} catch (error) {
|
||||
console.warn('读取图钉缓存失败,已忽略:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
function savePinCache(list) {
|
||||
localStorage.setItem(PIN_CACHE_KEY, JSON.stringify(list));
|
||||
}
|
||||
|
||||
function normalizeParentId(parentId) {
|
||||
return parentId == null || parentId === '' ? null : parentId;
|
||||
}
|
||||
|
||||
function sortPinRecords(list) {
|
||||
return [...list].sort((a, b) => {
|
||||
const parentA = normalizeParentId(a.parentId) || '';
|
||||
const parentB = normalizeParentId(b.parentId) || '';
|
||||
if (parentA !== parentB) return parentA.localeCompare(parentB);
|
||||
return (a.seq || 0) - (b.seq || 0);
|
||||
});
|
||||
}
|
||||
|
||||
function resequencePinRecords(list, parentId) {
|
||||
const normalizedParentId = normalizeParentId(parentId);
|
||||
const siblings = sortPinRecords(list.filter((item) => normalizeParentId(item.parentId) === normalizedParentId));
|
||||
siblings.forEach((item, index) => {
|
||||
item.seq = index;
|
||||
});
|
||||
}
|
||||
|
||||
function collectDescendantIds(list, parentId) {
|
||||
const ids = [];
|
||||
const stack = [parentId];
|
||||
while (stack.length > 0) {
|
||||
const currentId = stack.pop();
|
||||
list.forEach((item) => {
|
||||
if (normalizeParentId(item.parentId) === currentId) {
|
||||
ids.push(item.id);
|
||||
stack.push(item.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
function pushPinRecordsToEngine() {
|
||||
if (!engine || !engine.engine) return;
|
||||
if (typeof engine.engine.setPinRecords === 'function') {
|
||||
engine.engine.setPinRecords(pinCache);
|
||||
return;
|
||||
}
|
||||
if (typeof engine.engine.setPinList === 'function') {
|
||||
engine.engine.setPinList(pinCache);
|
||||
}
|
||||
}
|
||||
|
||||
function injectPinsFromCache() {
|
||||
pinCache = loadPinCache();
|
||||
if (pinCache.length > 0) {
|
||||
pushPinRecordsToEngine();
|
||||
console.log('✅ 已注入缓存图钉列表,数量:', pinCache.length);
|
||||
}
|
||||
}
|
||||
|
||||
function bindPinEvents() {
|
||||
if (!engine || typeof engine.on !== 'function') return;
|
||||
|
||||
if (unsubscribePinCreated) {
|
||||
unsubscribePinCreated();
|
||||
unsubscribePinCreated = null;
|
||||
}
|
||||
if (unsubscribePinDeleted) {
|
||||
unsubscribePinDeleted();
|
||||
unsubscribePinDeleted = null;
|
||||
}
|
||||
if (unsubscribePinChanged) {
|
||||
unsubscribePinChanged();
|
||||
unsubscribePinChanged = null;
|
||||
}
|
||||
|
||||
unsubscribePinCreated = engine.on('drawingPin:create', ({ record }) => {
|
||||
console.log('[Demo] drawingPin:create:', record);
|
||||
const normalizedRecord = {
|
||||
...record,
|
||||
parentId: normalizeParentId(record.parentId)
|
||||
};
|
||||
pinCache.push(normalizedRecord);
|
||||
resequencePinRecords(pinCache, normalizedRecord.parentId);
|
||||
savePinCache(pinCache);
|
||||
pushPinRecordsToEngine();
|
||||
});
|
||||
|
||||
unsubscribePinDeleted = engine.on('drawingPin:delete', ({ id }) => {
|
||||
console.log('[Demo] drawingPin:delete:', id);
|
||||
const record = pinCache.find((item) => item.id === id);
|
||||
if (!record) return;
|
||||
const targetParentId = normalizeParentId(record.parentId);
|
||||
const descendantIds = collectDescendantIds(pinCache, id);
|
||||
const deleteIds = new Set([id, ...descendantIds]);
|
||||
pinCache = pinCache.filter((item) => !deleteIds.has(item.id));
|
||||
resequencePinRecords(pinCache, targetParentId);
|
||||
savePinCache(pinCache);
|
||||
pushPinRecordsToEngine();
|
||||
});
|
||||
|
||||
unsubscribePinChanged = engine.on('drawingPin:update', ({ id, patch }) => {
|
||||
console.log('[Demo] drawingPin:update:', id, patch);
|
||||
const index = pinCache.findIndex((item) => item.id === id);
|
||||
if (index !== -1) {
|
||||
const previousParentId = normalizeParentId(pinCache[index].parentId);
|
||||
const nextParentId = Object.prototype.hasOwnProperty.call(patch, 'parentId')
|
||||
? normalizeParentId(patch.parentId)
|
||||
: previousParentId;
|
||||
pinCache[index] = {
|
||||
...pinCache[index],
|
||||
...patch,
|
||||
parentId: nextParentId,
|
||||
};
|
||||
resequencePinRecords(pinCache, previousParentId);
|
||||
resequencePinRecords(pinCache, nextParentId);
|
||||
}
|
||||
savePinCache(pinCache);
|
||||
pushPinRecordsToEngine();
|
||||
});
|
||||
|
||||
console.log('✅ 图钉事件绑定完成');
|
||||
}
|
||||
// const DEFAULT_3D_MODEL_URL = 'https://pub-8092fd0db2e14822a9f742ad0050750c.r2.dev/e9603d6b-c885-4f1b-84b0-2589bc9dc44f';
|
||||
const DEFAULT_3D_MODEL_URL = 'https://lyz-1259524260.cos.ap-guangzhou.myqcloud.com/iflow/models/417664a3-76c8-4d94-9344-1337246a5d4e';
|
||||
// const DEFAULT_3D_MODEL_URL = 'https://lyz-1259524260.cos.ap-guangzhou.myqcloud.com/iflow/models/417664a3-76c8-4d94-9344-1337246a5d4e';
|
||||
//const DEFAULT_3D_MODEL_URL = 'https://lyz-1259524260.cos.ap-guangzhou.myqcloud.com/iflow/models/cc389dc8-c6d5-43db-81f1-6998d4eee8f6';
|
||||
const DEFAULT_3D_MODEL_URL = 'https://pub-8092fd0db2e14822a9f742ad0050750c.r2.dev/bc7de1ae-a47e-458f-b3da-2a6d6b8f39af';
|
||||
//const DEFAULT_3D_MODEL_URL = 'https://pub-8092fd0db2e14822a9f742ad0050750c.r2.dev/66ad9a66-5ca8-47ac-9139-6aa8756069c1/';
|
||||
let current3dModelUrl = DEFAULT_3D_MODEL_URL;
|
||||
|
||||
@@ -457,6 +684,30 @@
|
||||
unsubscribePresetDeleted();
|
||||
unsubscribePresetDeleted = null;
|
||||
}
|
||||
if (unsubscribePinCreated) {
|
||||
unsubscribePinCreated();
|
||||
unsubscribePinCreated = null;
|
||||
}
|
||||
if (unsubscribePinDeleted) {
|
||||
unsubscribePinDeleted();
|
||||
unsubscribePinDeleted = null;
|
||||
}
|
||||
if (unsubscribePinChanged) {
|
||||
unsubscribePinChanged();
|
||||
unsubscribePinChanged = null;
|
||||
}
|
||||
if (unsubscribeMainViewSaved) {
|
||||
unsubscribeMainViewSaved();
|
||||
unsubscribeMainViewSaved = null;
|
||||
}
|
||||
if (unsubscribeMainViewRestored) {
|
||||
unsubscribeMainViewRestored();
|
||||
unsubscribeMainViewRestored = null;
|
||||
}
|
||||
if (unsubscribeModelLoaded) {
|
||||
unsubscribeModelLoaded();
|
||||
unsubscribeModelLoaded = null;
|
||||
}
|
||||
if (engine) { engine.destroy(); engine = null; }
|
||||
if (engine2d) { engine2d.destroy(); engine2d = null; }
|
||||
if (engine720) { engine720.destroy(); engine720 = null; }
|
||||
@@ -626,6 +877,9 @@
|
||||
if (success) {
|
||||
injectSettingPresetsFromCache();
|
||||
bindPresetEvents();
|
||||
bindPinEvents();
|
||||
bindMainViewEvents();
|
||||
injectPinsFromCache();
|
||||
updateEngineStatus('已初始化');
|
||||
console.log('✅ 3D 引擎初始化成功');
|
||||
loadModel();
|
||||
@@ -1171,4 +1425,4 @@
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user