951 lines
35 KiB
HTML
951 lines
35 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>3D Model Showcase SDK - TS</title>
|
||
<style>
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
body {
|
||
font-family: Arial, sans-serif;
|
||
overflow: hidden;
|
||
background-color: rgb(227 226 226);
|
||
}
|
||
|
||
#app {
|
||
width: 100vw;
|
||
height: 100vh;
|
||
display: flex;
|
||
position: relative;
|
||
}
|
||
|
||
#canvas-container {
|
||
flex: 1;
|
||
position: relative;
|
||
}
|
||
|
||
#renderDom {
|
||
width: 100%;
|
||
height: 100%;
|
||
display: block;
|
||
}
|
||
|
||
#config-panel {
|
||
width: 400px;
|
||
background: rgba(30, 30, 45, 0.95);
|
||
backdrop-filter: blur(10px);
|
||
overflow-y: auto;
|
||
padding: 20px;
|
||
box-shadow: -2px 0 10px rgba(0, 0, 0, 0.3);
|
||
}
|
||
|
||
#config-panel::-webkit-scrollbar {
|
||
width: 6px;
|
||
}
|
||
|
||
#config-panel::-webkit-scrollbar-track {
|
||
background: rgba(255, 255, 255, 0.1);
|
||
}
|
||
|
||
#config-panel::-webkit-scrollbar-thumb {
|
||
background: rgba(255, 255, 255, 0.3);
|
||
border-radius: 3px;
|
||
}
|
||
|
||
.config-title {
|
||
color: #fff;
|
||
font-size: 18px;
|
||
font-weight: bold;
|
||
margin-bottom: 20px;
|
||
padding-bottom: 10px;
|
||
border-bottom: 2px solid rgba(255, 255, 255, 0.2);
|
||
}
|
||
|
||
.click-info {
|
||
background: rgba(76, 175, 80, 0.2);
|
||
border: 1px solid rgba(76, 175, 80, 0.5);
|
||
border-radius: 8px;
|
||
padding: 12px;
|
||
margin-bottom: 15px;
|
||
color: #fff;
|
||
font-size: 13px;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.click-info-title {
|
||
font-weight: bold;
|
||
color: #4caf50;
|
||
margin-bottom: 8px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.click-info-item {
|
||
margin-bottom: 4px;
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
|
||
.click-info-label {
|
||
color: rgba(255, 255, 255, 0.7);
|
||
min-width: 70px;
|
||
}
|
||
|
||
.click-info-value {
|
||
color: #fff;
|
||
word-break: break-all;
|
||
}
|
||
|
||
.config-category {
|
||
margin-bottom: 15px;
|
||
border-radius: 8px;
|
||
overflow: hidden;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
}
|
||
|
||
.category-header {
|
||
padding: 12px 15px;
|
||
background: rgba(255, 255, 255, 0.1);
|
||
color: #fff;
|
||
cursor: pointer;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
transition: background 0.3s;
|
||
user-select: none;
|
||
}
|
||
|
||
.category-header:hover {
|
||
background: rgba(255, 255, 255, 0.15);
|
||
}
|
||
|
||
.category-header.active {
|
||
background: rgba(76, 175, 80, 0.3);
|
||
}
|
||
|
||
.category-title {
|
||
font-size: 14px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.category-arrow {
|
||
transition: transform 0.3s;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.category-arrow.expanded {
|
||
transform: rotate(180deg);
|
||
}
|
||
|
||
.category-content {
|
||
display: grid;
|
||
grid-template-rows: 0fr;
|
||
overflow: hidden;
|
||
transition: grid-template-rows 0.3s ease, padding 0.3s ease;
|
||
padding: 0 15px;
|
||
}
|
||
|
||
.category-content.expanded {
|
||
grid-template-rows: 1fr;
|
||
padding: 15px;
|
||
}
|
||
|
||
.category-content>* {
|
||
min-height: 0;
|
||
}
|
||
|
||
.option-item {
|
||
margin-bottom: 12px;
|
||
}
|
||
|
||
.option-label {
|
||
color: rgba(255, 255, 255, 0.8);
|
||
font-size: 13px;
|
||
margin-bottom: 8px;
|
||
display: block;
|
||
}
|
||
|
||
.option-group {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
gap: 8px;
|
||
}
|
||
|
||
.option-btn {
|
||
padding: 8px 16px;
|
||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||
background: rgba(255, 255, 255, 0.05);
|
||
color: #fff;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 12px;
|
||
transition: all 0.3s;
|
||
}
|
||
|
||
.option-btn:hover {
|
||
background: rgba(255, 255, 255, 0.1);
|
||
border-color: rgba(255, 255, 255, 0.5);
|
||
}
|
||
|
||
.option-btn.selected {
|
||
background: rgba(76, 175, 80, 0.6);
|
||
border-color: #4CAF50;
|
||
}
|
||
|
||
.option-checkbox {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 8px;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
transition: background 0.3s;
|
||
}
|
||
|
||
.option-checkbox:hover {
|
||
background: rgba(255, 255, 255, 0.05);
|
||
}
|
||
|
||
.option-checkbox input[type="checkbox"] {
|
||
margin-right: 8px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.option-checkbox label {
|
||
color: rgba(255, 255, 255, 0.8);
|
||
font-size: 12px;
|
||
cursor: pointer;
|
||
}
|
||
|
||
/* 标签页样式 */
|
||
.tabs-container {
|
||
margin-bottom: 15px;
|
||
}
|
||
|
||
.tabs-header {
|
||
display: flex;
|
||
gap: 8px;
|
||
margin-bottom: 15px;
|
||
border-bottom: 2px solid rgba(255, 255, 255, 0.1);
|
||
}
|
||
|
||
.tab-btn {
|
||
padding: 10px 20px;
|
||
background: rgba(255, 255, 255, 0.05);
|
||
color: rgba(255, 255, 255, 0.6);
|
||
border: none;
|
||
border-bottom: 2px solid transparent;
|
||
cursor: pointer;
|
||
font-size: 13px;
|
||
transition: all 0.3s;
|
||
flex: 1;
|
||
margin-bottom: -2px;
|
||
}
|
||
|
||
.tab-btn:hover {
|
||
background: rgba(255, 255, 255, 0.1);
|
||
color: rgba(255, 255, 255, 0.8);
|
||
}
|
||
|
||
.tab-btn.active {
|
||
background: rgba(76, 175, 80, 0.2);
|
||
color: #fff;
|
||
border-bottom-color: #4CAF50;
|
||
}
|
||
|
||
.tab-content {
|
||
display: none;
|
||
}
|
||
|
||
.tab-content.active {
|
||
display: block;
|
||
}
|
||
|
||
/* 系列分割线样式 */
|
||
.series-divider {
|
||
color: rgba(255, 255, 255, 0.5);
|
||
font-size: 12px;
|
||
text-align: center;
|
||
margin: 10px 0;
|
||
padding: 5px 0;
|
||
letter-spacing: 2px;
|
||
}
|
||
|
||
/* 进度条样式 */
|
||
#progress-container {
|
||
position: absolute;
|
||
top: 50%;
|
||
left: 50%;
|
||
transform: translate(-50%, -50%);
|
||
width: 80%;
|
||
max-width: 500px;
|
||
background: rgba(255, 255, 255, 0.2);
|
||
border-radius: 10px;
|
||
padding: 10px;
|
||
z-index: 1000;
|
||
}
|
||
|
||
#progress-bar {
|
||
width: 0%;
|
||
height: 10px;
|
||
background: linear-gradient(90deg, #4CAF50, #45a049);
|
||
border-radius: 5px;
|
||
transition: width 0.1s ease;
|
||
}
|
||
|
||
#progress-text {
|
||
color: white;
|
||
text-align: center;
|
||
margin-top: 5px;
|
||
font-size: 14px;
|
||
}
|
||
</style>
|
||
</head>
|
||
|
||
<body>
|
||
<div id="app">
|
||
<!-- 画布区域 -->
|
||
<div id="canvas-container">
|
||
<canvas id="renderDom"></canvas>
|
||
<div id="progress-container" style="display: none;">
|
||
<div id="progress-bar"></div>
|
||
<div id="progress-text">0%</div>
|
||
</div>
|
||
|
||
<!-- 生成放置区域按钮 -->
|
||
<button id="dropzone-btn" style="
|
||
position: absolute;
|
||
top: 20px;
|
||
left: 20px;
|
||
padding: 10px 20px;
|
||
background: #21c7ff;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 14px;
|
||
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
||
z-index: 100;
|
||
">生成放置区域</button>
|
||
</div>
|
||
|
||
<!-- 配置面板 -->
|
||
<div id="config-panel">
|
||
<div class="config-title">选装选配</div>
|
||
|
||
<!-- 点击信息显示区域 -->
|
||
<div id="click-info" class="click-info" style="display: none;">
|
||
<div class="click-info-title">点击信息</div>
|
||
<div id="click-info-content"></div>
|
||
</div>
|
||
|
||
<!-- 标签页容器 -->
|
||
<div class="tabs-container">
|
||
<div class="tabs-header">
|
||
<button class="tab-btn active" data-tab="size-1013">10x13</button>
|
||
<button class="tab-btn" data-tab="size-1010">10x10</button>
|
||
<button class="tab-btn" data-tab="size-1020">10x20</button>
|
||
<button class="tab-btn" data-tab="size-1012">10x12</button>
|
||
</div>
|
||
|
||
<!-- 10x13 尺寸配置 -->
|
||
<div class="tab-content active" id="tab-size-1013">
|
||
<!-- 棚子尺寸 -->
|
||
<div class="config-category">
|
||
<div class="category-header active" data-category="size-1013">
|
||
<span class="category-title">棚子尺寸</span>
|
||
<span class="category-arrow expanded">▼</span>
|
||
</div>
|
||
<div class="category-content expanded">
|
||
<!-- 111 系列 -->
|
||
<div class="series-divider">----- 111 -----</div>
|
||
<div class="option-group">
|
||
<button class="option-btn" data-option="size-1">SPF111S1013W</button>
|
||
<button class="option-btn" data-option="size-2">SPF111S1013TA</button>
|
||
<button class="option-btn" data-option="size-3">SPF111S1013C</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 10x10 尺寸配置 -->
|
||
<div class="tab-content" id="tab-size-1010">
|
||
<!-- 棚子尺寸 -->
|
||
<div class="config-category">
|
||
<div class="category-header active" data-category="size-1010">
|
||
<span class="category-title">棚子尺寸</span>
|
||
<span class="category-arrow expanded">▼</span>
|
||
</div>
|
||
<div class="category-content expanded">
|
||
<!-- 80 系列 -->
|
||
<div class="series-divider">----- 80 -----</div>
|
||
<div class="option-group">
|
||
<button class="option-btn" data-option="size-4">SPF80S1010L</button>
|
||
</div>
|
||
<!-- 111 系列 -->
|
||
<div class="series-divider">----- 111 -----</div>
|
||
<div class="option-group">
|
||
<button class="option-btn" data-option="size-4">SPF111S1010C</button>
|
||
<button class="option-btn" data-option="size-5">SPF111S1010TA</button>
|
||
<button class="option-btn" data-option="size-6">SPF111S1010W</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 10x20 尺寸配置 -->
|
||
<div class="tab-content" id="tab-size-1020">
|
||
<!-- 棚子尺寸 -->
|
||
<div class="config-category">
|
||
<div class="category-header active" data-category="size-1020">
|
||
<span class="category-title">棚子尺寸</span>
|
||
<span class="category-arrow expanded">▼</span>
|
||
</div>
|
||
<div class="category-content expanded">
|
||
|
||
<!-- 80 系列 -->
|
||
<div class="series-divider">----- 80 -----</div>
|
||
<div class="option-group">
|
||
<button class="option-btn" data-option="size-4">SPF80S1020C</button>
|
||
</div>
|
||
<!-- 111 系列 -->
|
||
<div class="series-divider">----- 111 -----</div>
|
||
<div class="option-group">
|
||
<button class="option-btn" data-option="size-7">SPF111S1020C</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 10x12 尺寸配置 -->
|
||
<div class="tab-content" id="tab-size-1012">
|
||
<!-- 棚子尺寸 -->
|
||
<div class="config-category">
|
||
<div class="category-header active" data-category="size-1012">
|
||
<span class="category-title">棚子尺寸</span>
|
||
<span class="category-arrow expanded">▼</span>
|
||
</div>
|
||
<div class="category-content expanded">
|
||
<!-- 88 系列 -->
|
||
<div class="series-divider">----- 88 -----</div>
|
||
<div class="option-group">
|
||
<button class="option-btn" data-option="size-10">SPF88S1012C</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 百叶配件(独立区域) -->
|
||
<div class="louver-section" style="margin-top: 20px; padding-top: 20px; border-top: 2px solid #e0e0e0;">
|
||
<div class="config-title" style="font-size: 16px; margin-bottom: 15px;">百叶配件</div>
|
||
|
||
<!-- 10x13 百叶 -->
|
||
<div class="config-category">
|
||
<div class="category-header active" data-category="louver-1013">
|
||
<span class="category-title">13 百叶</span>
|
||
<span class="category-arrow expanded">▼</span>
|
||
</div>
|
||
<div class="category-content expanded">
|
||
<div class="option-group">
|
||
<button class="option-btn" data-option="color-1">SPFPDS13FTW</button>
|
||
<button class="option-btn" data-option="color-2">SPFPDS13FTC</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 10x10 百叶 -->
|
||
<div class="config-category">
|
||
<div class="category-header active" data-category="louver-1010">
|
||
<span class="category-title">10 百叶</span>
|
||
<span class="category-arrow expanded">▼</span>
|
||
</div>
|
||
<div class="category-content expanded">
|
||
<div class="option-group">
|
||
<button class="option-btn" data-option="color-3">SPFPDS10FTW</button>
|
||
<button class="option-btn" data-option="color-4">SPFPDS10FTC</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 10x12 百叶 -->
|
||
<div class="config-category">
|
||
<div class="category-header active" data-category="louver-1012">
|
||
<span class="category-title">12 百叶</span>
|
||
<span class="category-arrow expanded">▼</span>
|
||
</div>
|
||
<div class="category-content expanded">
|
||
<div class="option-group">
|
||
<button class="option-btn" data-option="color-7">SPF80CS12FTC</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<button id="hotspot-btn">生成热点</button>
|
||
<button id="prevent-btn">生成防止区域</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 模型信息框(用于2D转3D显示) -->
|
||
<div id="model-info-box" style="display: none;">
|
||
<div style="
|
||
background: rgba(255, 255, 255, 0.95);
|
||
padding: 15px 20px;
|
||
border-radius: 8px;
|
||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
|
||
font-size: 14px;
|
||
color: #333;
|
||
min-width: 200px;
|
||
">
|
||
<div style="font-weight: bold; margin-bottom: 8px; color: #4CAF50;">模型信息</div>
|
||
<div id="info-name" style="margin-bottom: 5px;">名称: -</div>
|
||
<div id="info-position" style="margin-bottom: 10px; font-size: 12px; color: #666;">坐标: -</div>
|
||
|
||
<!-- 颜色按钮 -->
|
||
<div id="color-buttons" style="display: none; gap: 8px; margin-bottom: 8px;">
|
||
<button id="color-btn-1" style="
|
||
flex: 1;
|
||
padding: 8px;
|
||
background: #FFFFFF;
|
||
color: #333;
|
||
border: 1px solid #ddd;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 12px;
|
||
">白色</button>
|
||
<button id="color-btn-2" style="
|
||
flex: 1;
|
||
padding: 8px;
|
||
background: #000000;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 12px;
|
||
">黑色</button>
|
||
</div>
|
||
|
||
<!-- 旋转按钮 -->
|
||
<div id="rotation-buttons" style="display: none; gap: 8px; margin-bottom: 8px;">
|
||
<button id="rotation-btn-90" style="
|
||
flex: 1;
|
||
padding: 8px;
|
||
background: #2196F3;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 12px;
|
||
">旋转90°</button>
|
||
<button id="rotation-btn-180" style="
|
||
flex: 1;
|
||
padding: 8px;
|
||
background: #2196F3;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 12px;
|
||
">旋转180°</button>
|
||
</div>
|
||
|
||
<div style="display: flex; gap: 8px;">
|
||
<button id="remove-model-btn" style="
|
||
flex: 1;
|
||
padding: 8px;
|
||
background: #f44336;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 12px;
|
||
">移除</button>
|
||
<button id="close-info-btn" style="
|
||
flex: 1;
|
||
padding: 8px;
|
||
background: #4CAF50;
|
||
color: white;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
font-size: 12px;
|
||
">关闭</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<script src="https://sdk.zguiy.com/zt/asstes/index.global.js"></script>
|
||
<script src="https://sdk.zguiy.com/zt/asstes/app-global.js"></script>
|
||
<script>
|
||
// 从全局对象获取 SDK kernel
|
||
var kernel = window.faceSDK && window.faceSDK.kernel;
|
||
console.log('kernel:', kernel.on);
|
||
if (!kernel) {
|
||
console.error('faceSDK kernel 不可用,请确认 index.global.js 已正确加载');
|
||
alert('SDK 加载失败,请检查网络连接');
|
||
}
|
||
|
||
// 初始化 AppLogic
|
||
window.AppLogic.initApp(kernel);
|
||
window.AppLogic.init();
|
||
|
||
// 存储当前选中的材质名和网格
|
||
var currentMaterialName = '';
|
||
var currentPickedMesh = null;
|
||
|
||
kernel.on('all:ready', function (data) {
|
||
console.log('所有模块加载完,', data);
|
||
kernel.material.apply({
|
||
target: 'Material__2',
|
||
attribute: 'alpha',
|
||
value: 0.5,
|
||
});
|
||
});
|
||
|
||
// ========== UI 交互逻辑 ==========
|
||
|
||
// 标签页切换
|
||
document.querySelectorAll('.tab-btn').forEach(function (btn) {
|
||
btn.addEventListener('click', function () {
|
||
var tabId = this.dataset.tab;
|
||
|
||
// 移除所有标签页的激活状态
|
||
document.querySelectorAll('.tab-btn').forEach(function (b) { b.classList.remove('active'); });
|
||
document.querySelectorAll('.tab-content').forEach(function (c) { c.classList.remove('active'); });
|
||
|
||
// 激活当前标签页
|
||
this.classList.add('active');
|
||
document.getElementById('tab-' + tabId).classList.add('active');
|
||
});
|
||
});
|
||
|
||
// 折叠面板切换
|
||
document.querySelectorAll('.category-header').forEach(function (header) {
|
||
header.addEventListener('click', function () {
|
||
var content = this.nextElementSibling;
|
||
var arrow = this.querySelector('.category-arrow');
|
||
|
||
// 切换展开/收起状态
|
||
content.classList.toggle('expanded');
|
||
arrow.classList.toggle('expanded');
|
||
this.classList.toggle('active');
|
||
});
|
||
});
|
||
|
||
var sku = "";
|
||
// 单选按钮逻辑
|
||
document.querySelectorAll('.option-btn').forEach(function (btn) {
|
||
btn.addEventListener('click', async function () {
|
||
var optionGroup = this.parentElement;
|
||
var category = this.closest('.config-category');
|
||
var categoryName = category.querySelector('.category-header').dataset.category;
|
||
|
||
// 同一组内取消其他选中状态
|
||
optionGroup.querySelectorAll('.option-btn').forEach(function (b) {
|
||
b.classList.remove('selected');
|
||
});
|
||
|
||
// 选中当前按钮
|
||
this.classList.add('selected');
|
||
|
||
console.log('配置变更:', {
|
||
category: categoryName,
|
||
value: this.dataset.option,
|
||
text: this.textContent
|
||
});
|
||
|
||
var currentText = this.textContent;
|
||
sku = currentText;
|
||
await window.AppLogic.getProductConfig(currentText);
|
||
});
|
||
});
|
||
|
||
document.querySelector('#hotspot-btn').addEventListener('click', async function () {
|
||
await window.AppLogic.getHotspot();
|
||
});
|
||
|
||
document.querySelector('#prevent-btn').addEventListener('click', async function () {
|
||
await window.AppLogic.getPlacementZone();
|
||
});
|
||
|
||
// 监听放置区域点击事件
|
||
kernel.on('dropzone:click', async function (dropzone_data) {
|
||
await window.AppLogic.getEvent(dropzone_data, sku);
|
||
});
|
||
|
||
// 监听模型点击事件
|
||
kernel.on('model:click', function (data) {
|
||
console.log('模型点击事件', data);
|
||
console.log('模型控制类型:', data.modelControlType);
|
||
switch (data.modelControlType) {
|
||
case "color":
|
||
// DOM 2D转3D 示例:点击模型时显示信息框
|
||
if (data.pickedMesh && data.pickedPoint) {
|
||
var meshName = data.pickedMesh.name;
|
||
var position = data.pickedPoint;
|
||
currentMaterialName = data.materialName || '';
|
||
currentPickedMesh = data.pickedMesh;
|
||
|
||
// 获取已创建的DOM元素
|
||
var infoDiv = document.getElementById('model-info-box');
|
||
// 更新信息内容
|
||
document.getElementById('info-name').textContent = '名称: ' + meshName;
|
||
document.getElementById('info-position').textContent = '坐标: [' + position.x.toFixed(2) + ', ' + position.y.toFixed(2) + ', ' + position.z.toFixed(2) + ']';
|
||
|
||
// 显示颜色按钮,隐藏旋转按钮
|
||
document.getElementById('color-buttons').style.display = 'flex';
|
||
document.getElementById('rotation-buttons').style.display = 'none';
|
||
|
||
// 将DOM附加到点击的3D坐标(会自动显示)
|
||
kernel.domTo3D.attach('model-info', infoDiv, [position.x, position.y, position.z], { x: -2, y: -2 });
|
||
}
|
||
break;
|
||
case "rotation":
|
||
// 显示旋转控制UI
|
||
if (data.pickedMesh && data.pickedPoint) {
|
||
var meshName = data.pickedMesh.name;
|
||
var position = data.pickedPoint;
|
||
currentPickedMesh = data.pickedMesh;
|
||
|
||
// 获取已创建的DOM元素
|
||
var infoDiv = document.getElementById('model-info-box');
|
||
// 更新信息内容
|
||
document.getElementById('info-name').textContent = '名称: ' + meshName;
|
||
document.getElementById('info-position').textContent = '坐标: [' + position.x.toFixed(2) + ', ' + position.y.toFixed(2) + ', ' + position.z.toFixed(2) + ']';
|
||
|
||
// 显示旋转按钮,隐藏颜色按钮
|
||
document.getElementById('rotation-buttons').style.display = 'flex';
|
||
document.getElementById('color-buttons').style.display = 'none';
|
||
|
||
// 将DOM附加到点击的3D坐标(会自动显示)
|
||
kernel.domTo3D.attach('model-info', infoDiv, [position.x, position.y, position.z], { x: -2, y: -2 });
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
});
|
||
|
||
// 暴露到全局,供使用
|
||
window.getCurrentMaterialName = function () { return currentMaterialName; };
|
||
window.getCurrentPickedMesh = function () { return currentPickedMesh; };
|
||
|
||
kernel.on('hotspot:click', function (event) {
|
||
console.log('热点被点击:', event);
|
||
var id = event.id;
|
||
var name = event.name;
|
||
var payload = event.payload;
|
||
|
||
if (payload && payload.skus && payload.skus.length > 0) {
|
||
console.log('热点关联的SKU列表:', payload.skus);
|
||
} else {
|
||
console.log('该热点没有关联SKU');
|
||
}
|
||
});
|
||
|
||
// 移除按钮事件
|
||
document.getElementById('remove-model-btn').addEventListener('click', function () {
|
||
var pickedMesh = window.getCurrentPickedMesh();
|
||
if (pickedMesh) {
|
||
var modelName = kernel.model.findModelNameByMesh?.(pickedMesh);
|
||
if (modelName) {
|
||
console.log('移除模型:', modelName);
|
||
kernel.model.remove({ modelId: modelName });
|
||
kernel.domTo3D.detach('model-info');
|
||
}
|
||
}
|
||
});
|
||
|
||
// 关闭按钮事件
|
||
document.getElementById('close-info-btn').addEventListener('click', function () {
|
||
kernel.domTo3D.detach('model-info');
|
||
});
|
||
|
||
// 白色按钮事件
|
||
document.getElementById('color-btn-1').addEventListener('click', function () {
|
||
var materialName = window.getCurrentMaterialName();
|
||
if (materialName) {
|
||
console.log('切换为白色,材质名:', materialName);
|
||
kernel.material.apply({
|
||
target: materialName,
|
||
albedoColor: '#FFFFFF',
|
||
});
|
||
} else {
|
||
console.log('没有选中材质');
|
||
}
|
||
});
|
||
|
||
// 黑色按钮事件
|
||
document.getElementById('color-btn-2').addEventListener('click', function () {
|
||
var materialName = window.getCurrentMaterialName();
|
||
if (materialName) {
|
||
console.log('切换为黑色,材质名:', materialName);
|
||
kernel.material.apply({
|
||
target: materialName,
|
||
albedoColor: '#000000',
|
||
});
|
||
} else {
|
||
console.log('没有选中材质');
|
||
}
|
||
});
|
||
|
||
// 旋转90度按钮事件
|
||
document.getElementById('rotation-btn-90').addEventListener('click', function () {
|
||
var pickedMesh = window.getCurrentPickedMesh();
|
||
if (pickedMesh) {
|
||
var modelName = kernel.model.findModelNameByMesh?.(pickedMesh);
|
||
if (modelName) {
|
||
console.log('旋转90度,模型名:', modelName);
|
||
kernel.transform.rotation({
|
||
modelId: modelName,
|
||
vector3: { x: 0, y: 90, z: 0 }
|
||
});
|
||
} else {
|
||
console.log('未找到模型名称');
|
||
}
|
||
} else {
|
||
console.log('没有选中的网格');
|
||
}
|
||
});
|
||
|
||
// 旋转180度按钮事件
|
||
document.getElementById('rotation-btn-180').addEventListener('click', function () {
|
||
var pickedMesh = window.getCurrentPickedMesh();
|
||
if (pickedMesh) {
|
||
var modelName = kernel.model.findModelNameByMesh?.(pickedMesh);
|
||
if (modelName) {
|
||
console.log('旋转180度,模型名:', modelName);
|
||
kernel.transform.rotation({
|
||
modelId: modelName,
|
||
vector3: { x: 0, y: 180, z: 0 }
|
||
});
|
||
} else {
|
||
console.log('未找到模型名称');
|
||
}
|
||
} else {
|
||
console.log('没有选中的网格');
|
||
}
|
||
});
|
||
|
||
|
||
|
||
// 移除按钮事件
|
||
document.getElementById('remove-model-btn').addEventListener('click', () => {
|
||
const pickedMesh = window.getCurrentPickedMesh();
|
||
if (pickedMesh) {
|
||
const meshName = pickedMesh.name;
|
||
const modelName = kernel.model.findModelNameByMesh(pickedMesh);
|
||
const success = kernel.model.removeByName(modelName);
|
||
if (success) {
|
||
console.log('模型已移除');
|
||
// 关闭信息框
|
||
kernel.domTo3D.detach('model-info');
|
||
} else {
|
||
console.log('移除失败:未找到该网格所属的模型');
|
||
}
|
||
} else {
|
||
console.log('没有选中的网格');
|
||
}
|
||
});
|
||
|
||
// 生成放置区域按钮事件
|
||
var dropZoneVisible = false;
|
||
document.getElementById('dropzone-btn').addEventListener('click', function () {
|
||
if (!dropZoneVisible) {
|
||
kernel.dropZone.showAll();
|
||
dropZoneVisible = true;
|
||
document.getElementById('dropzone-btn').textContent = '隐藏放置区域';
|
||
console.log('已生成并显示放置区域');
|
||
} else {
|
||
kernel.dropZone.hideAll();
|
||
dropZoneVisible = false;
|
||
document.getElementById('dropzone-btn').textContent = '生成放置区域';
|
||
console.log('已隐藏放置区域');
|
||
}
|
||
});
|
||
|
||
console.log(kernel);
|
||
|
||
// 监听放置区域点击事件
|
||
kernel.on('dropzone:click', function (dropzone_data) {
|
||
window.AppLogic.getEvent(dropzone_data, sku);
|
||
});
|
||
|
||
// 存储当前选中的材质名和网格
|
||
var currentMaterialName = '';
|
||
var currentPickedMesh = null;
|
||
|
||
kernel.on('model:click', function (data) {
|
||
console.log('模型点击事件', data);
|
||
console.log('模型控制类型:', data.modelControlType);
|
||
|
||
var modelName = data.modelName;
|
||
console.log('点击的模型ID:', modelName);
|
||
|
||
switch (data.modelControlType) {
|
||
case "color":
|
||
if (data.pickedMesh && data.pickedPoint) {
|
||
var meshName = data.pickedMesh.name;
|
||
var modelName = kernel.model.findModelNameByMesh(data.pickedMesh) || meshName;
|
||
var position = data.pickedPoint;
|
||
currentMaterialName = data.materialName || '';
|
||
currentPickedMesh = data.pickedMesh;
|
||
|
||
var infoDiv = document.getElementById('model-info-box');
|
||
document.getElementById('info-name').textContent = '模型: ' + modelName;
|
||
document.getElementById('info-position').textContent = '坐标: [' + position.x.toFixed(2) + ', ' + position.y.toFixed(2) + ', ' + position.z.toFixed(2) + ']';
|
||
|
||
document.getElementById('color-buttons').style.display = 'flex';
|
||
document.getElementById('rotation-buttons').style.display = 'none';
|
||
|
||
kernel.domTo3D.attach('model-info', infoDiv, [position.x, position.y, position.z], { x: -2, y: -2 });
|
||
}
|
||
break;
|
||
case "rotation":
|
||
if (data.pickedMesh && data.pickedPoint) {
|
||
var meshName = data.pickedMesh.name;
|
||
var modelName = kernel.model.findModelNameByMesh(data.pickedMesh) || meshName;
|
||
var position = data.pickedPoint;
|
||
currentPickedMesh = data.pickedMesh;
|
||
|
||
var infoDiv = document.getElementById('model-info-box');
|
||
document.getElementById('info-name').textContent = '名称: ' + meshName;
|
||
document.getElementById('info-position').textContent = '坐标: [' + position.x.toFixed(2) + ', ' + position.y.toFixed(2) + ', ' + position.z.toFixed(2) + ']';
|
||
|
||
document.getElementById('rotation-buttons').style.display = 'flex';
|
||
document.getElementById('color-buttons').style.display = 'none';
|
||
|
||
kernel.domTo3D.attach('model-info', infoDiv, [position.x, position.y, position.z], { x: -2, y: -2 });
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
|
||
});
|
||
|
||
window.getCurrentMaterialName = function () { return currentMaterialName; };
|
||
window.getCurrentPickedMesh = function () { return currentPickedMesh; };
|
||
|
||
kernel.on('hotspot:click', function (event) {
|
||
console.log('热点被点击:', event);
|
||
|
||
var id = event.id;
|
||
var name = event.name;
|
||
var payload = event.payload;
|
||
|
||
if (payload && payload.skus && payload.skus.length > 0) {
|
||
console.log('热点关联的SKU列表:', payload.skus);
|
||
} else {
|
||
console.log('该热点没有关联SKU');
|
||
}
|
||
});
|
||
</script>
|
||
</body>
|
||
|
||
</html> |