新增相机限制
This commit is contained in:
4
.env
4
.env
@ -1,6 +1,8 @@
|
|||||||
# API 配置
|
# API 配置
|
||||||
# 开发环境
|
# 开发环境
|
||||||
VITE_API_BASE_URL=https://ztserver.zguiy.com
|
VITE_API_BASE_URL=http://192.168.3.100:26517
|
||||||
|
|
||||||
|
#生产环境
|
||||||
|
# VITE_API_BASE_URL=https://ztserver.zguiy.com
|
||||||
# 生产环境示例(部署时修改)
|
# 生产环境示例(部署时修改)
|
||||||
# VITE_API_BASE_URL=https://api.yourdomain.com
|
# VITE_API_BASE_URL=https://api.yourdomain.com
|
||||||
|
|||||||
194
index.html
194
index.html
@ -221,6 +221,50 @@
|
|||||||
cursor: pointer;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/* 进度条样式 */
|
/* 进度条样式 */
|
||||||
#progress-container {
|
#progress-container {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -289,83 +333,76 @@
|
|||||||
<div id="click-info-content"></div>
|
<div id="click-info-content"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 棚子尺寸 -->
|
<!-- 标签页容器 -->
|
||||||
<div class="config-category">
|
<div class="tabs-container">
|
||||||
<div class="category-header" data-category="size">
|
<div class="tabs-header">
|
||||||
<span class="category-title">棚子尺寸</span>
|
<button class="tab-btn active" data-tab="size-1013">10x13 尺寸</button>
|
||||||
<span class="category-arrow">▼</span>
|
<button class="tab-btn" data-tab="size-1010">10x10 尺寸</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="category-content">
|
|
||||||
<div class="option-group">
|
<!-- 10x13 尺寸配置 -->
|
||||||
<button class="option-btn" data-option="size-1">3*3</button>
|
<div class="tab-content active" id="tab-size-1013">
|
||||||
<button class="option-btn" data-option="size-2">3x6</button>
|
<!-- 棚子尺寸 -->
|
||||||
<button class="option-btn" data-option="size-3">10x13EM星空篷</button>
|
<div class="config-category">
|
||||||
<button class="option-btn" data-option="size-4">全铁3x6</button>
|
<div class="category-header active" data-category="size-1013">
|
||||||
<button class="option-btn" data-option="size-1">10x12</button>
|
<span class="category-title">棚子尺寸</span>
|
||||||
<button class="option-btn" data-option="size-2">SPF111S1010W</button>
|
<span class="category-arrow expanded">▼</span>
|
||||||
<button class="option-btn" data-option="size-3">SPF111S1013W</button>
|
</div>
|
||||||
<button class="option-btn" data-option="size-4">10x20星空篷</button>
|
<div class="category-content expanded">
|
||||||
|
<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 class="config-category">
|
||||||
|
<div class="category-header active" data-category="louver-1013">
|
||||||
|
<span class="category-title">百叶</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>
|
||||||
|
<button class="option-btn" data-option="color-3">SPFPDS10FTW</button>
|
||||||
|
<button class="option-btn" data-option="color-4">SPFPDS10FTC</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 棚子类型 -->
|
<!-- 10x10 尺寸配置 -->
|
||||||
<div class="config-category">
|
<div class="tab-content" id="tab-size-1010">
|
||||||
<div class="category-header" data-category="type">
|
<!-- 棚子尺寸 -->
|
||||||
<span class="category-title">棚子类型</span>
|
<div class="config-category">
|
||||||
<span class="category-arrow">▼</span>
|
<div class="category-header active" data-category="size-1010">
|
||||||
</div>
|
<span class="category-title">棚子尺寸</span>
|
||||||
<div class="category-content">
|
<span class="category-arrow expanded">▼</span>
|
||||||
<div class="option-group">
|
</div>
|
||||||
<button class="option-btn" data-option="type-1">平顶</button>
|
<div class="category-content expanded">
|
||||||
<button class="option-btn" data-option="type-2">尖顶</button>
|
<div class="option-group">
|
||||||
<button class="option-btn" data-option="type-3">弧形</button>
|
<button class="option-btn" data-option="size-4">SPF111S1010C</button>
|
||||||
<button class="option-btn" data-option="type-4">异形</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>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 百叶 (单选) -->
|
|
||||||
<div class="config-category">
|
|
||||||
<div class="category-header" data-category="louver">
|
|
||||||
<span class="category-title">百叶</span>
|
|
||||||
<span class="category-arrow">▼</span>
|
|
||||||
</div>
|
|
||||||
<div class="category-content">
|
|
||||||
<div class="option-group">
|
|
||||||
<button class="option-btn" data-option="louver-1">SPFPDS13FTW</button>
|
|
||||||
<button class="option-btn" data-option="louver-2">SPFPDS13FTC</button>
|
|
||||||
<button class="option-btn" data-option="louver-3">3m下拉帘</button>
|
|
||||||
<button class="option-btn" data-option="louver-4">SPFSW13FTW</button>
|
|
||||||
<button class="option-btn" data-option="louver-4">SPFSW10FTW</button>
|
|
||||||
<button class="option-btn" data-option="louver-4">SPFPDS10FTC</button>
|
|
||||||
<button class="option-btn" data-option="louver-4">SPFPDS10FTW</button>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<div>13</div>
|
|
||||||
<button class="option-btn" data-option="color-1">SPFPDS13FTW</button>
|
|
||||||
<button class="option-btn" data-option="color-2">SPFPDS13FTC</button>
|
|
||||||
<div>10</div>
|
|
||||||
<button class="option-btn" data-option="color-1">SPFPDS10FTW</button>
|
|
||||||
<button class="option-btn" data-option="color-2">SPFPDS10FTC</button>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 配色 -->
|
|
||||||
<div class="config-category">
|
|
||||||
<div class="category-header" data-category="color">
|
|
||||||
<span class="category-title">配色</span>
|
|
||||||
<span class="category-arrow">▼</span>
|
|
||||||
</div>
|
|
||||||
<div class="category-content">
|
|
||||||
<div class="option-group">
|
|
||||||
<div>13</div>
|
|
||||||
<button class="option-btn" data-option="color-1">SPF111S1013W</button>
|
|
||||||
<div>10</div>
|
|
||||||
<button class="option-btn" data-option="color-3">SPF111S1010TA</button>
|
|
||||||
|
|
||||||
|
<!-- 百叶 -->
|
||||||
|
<div class="config-category">
|
||||||
|
<div class="category-header active" data-category="louver-1010">
|
||||||
|
<span class="category-title">百叶</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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -504,6 +541,21 @@
|
|||||||
|
|
||||||
// ========== UI 交互逻辑 ==========
|
// ========== UI 交互逻辑 ==========
|
||||||
|
|
||||||
|
// 标签页切换
|
||||||
|
document.querySelectorAll('.tab-btn').forEach(btn => {
|
||||||
|
btn.addEventListener('click', function () {
|
||||||
|
const tabId = this.dataset.tab;
|
||||||
|
|
||||||
|
// 移除所有标签页的激活状态
|
||||||
|
document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('active'));
|
||||||
|
document.querySelectorAll('.tab-content').forEach(c => c.classList.remove('active'));
|
||||||
|
|
||||||
|
// 激活当前标签页
|
||||||
|
this.classList.add('active');
|
||||||
|
document.getElementById('tab-' + tabId).classList.add('active');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
// 折叠面板切换
|
// 折叠面板切换
|
||||||
document.querySelectorAll('.category-header').forEach(header => {
|
document.querySelectorAll('.category-header').forEach(header => {
|
||||||
header.addEventListener('click', function () {
|
header.addEventListener('click', function () {
|
||||||
|
|||||||
22
index.js
22
index.js
@ -39,7 +39,7 @@ export const init = async (customConfig = {}) => {
|
|||||||
const defaultConfig = {
|
const defaultConfig = {
|
||||||
container: document.querySelector('#renderDom'),
|
container: document.querySelector('#renderDom'),
|
||||||
modelUrlList: [],
|
modelUrlList: [],
|
||||||
env: { envPath: 'https://sdk.zguiy.com/resurces/hdr/hdr.env', intensity: 1.2, rotationY: 0.3, background: true },
|
env: { envPath: 'https://sdk.zguiy.com/resurces/hdr/hdr.env', intensity: 1.2, rotationY: 0.3, background: false },
|
||||||
gizmo: {
|
gizmo: {
|
||||||
position: false,
|
position: false,
|
||||||
rotation: false,
|
rotation: false,
|
||||||
@ -123,7 +123,6 @@ export const getPlacementZone = async (sku) => {
|
|||||||
|
|
||||||
//执行事件
|
//执行事件
|
||||||
export const getEvent = async (dropzone_data, sku) => {
|
export const getEvent = async (dropzone_data, sku) => {
|
||||||
console.log(sku);
|
|
||||||
|
|
||||||
// 将模型放置到该区域
|
// 将模型放置到该区域
|
||||||
try {
|
try {
|
||||||
@ -153,6 +152,8 @@ export const executeEvent = async (dropzone_data, result, sku) => {
|
|||||||
|
|
||||||
let modelId = null; // 在外部声明,用于在两个循环之间传递
|
let modelId = null; // 在外部声明,用于在两个循环之间传递
|
||||||
let modelName = null;
|
let modelName = null;
|
||||||
|
let pergolaSku = null; // 用于存储棚子的 SKU
|
||||||
|
|
||||||
// 第一次循环:处理 change_model
|
// 第一次循环:处理 change_model
|
||||||
for (const event of result.data.events) {
|
for (const event of result.data.events) {
|
||||||
if (event.event_type === 'change_model') {
|
if (event.event_type === 'change_model') {
|
||||||
@ -205,6 +206,20 @@ export const executeEvent = async (dropzone_data, result, sku) => {
|
|||||||
console.log(`百叶模型颜色已替换为 ${color}`);
|
console.log(`百叶模型颜色已替换为 ${color}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 查找棚子的 SKU(从已加载的模型中查找 model_control_type 为 'pergola' 的模型)
|
||||||
|
const allModels = kernel.model.getAllMetadata();
|
||||||
|
for (const model of allModels) {
|
||||||
|
if (model.modelControlType === 'pergola') {
|
||||||
|
pergolaSku = getSkuByModelId(model.modelId);
|
||||||
|
if (pergolaSku) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('当前棚子的 SKU:', pergolaSku);
|
||||||
|
return pergolaSku;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -225,7 +240,6 @@ export const executeEvent2 = async (result, sku) => {
|
|||||||
console.log(`检查模型 ${name + '_' + category} 是否存在:`, modelAlreadyExists);
|
console.log(`检查模型 ${name + '_' + category} 是否存在:`, modelAlreadyExists);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log(hasModelChange && !modelAlreadyExists);
|
|
||||||
kernel.dropZone.hide();
|
kernel.dropZone.hide();
|
||||||
// 只有在需要更换模型且模型不存在时才清除
|
// 只有在需要更换模型且模型不存在时才清除
|
||||||
if (hasModelChange && !modelAlreadyExists) {
|
if (hasModelChange && !modelAlreadyExists) {
|
||||||
@ -238,6 +252,8 @@ console.log(hasModelChange && !modelAlreadyExists);
|
|||||||
|
|
||||||
// 先处理所有 change_model 事件
|
// 先处理所有 change_model 事件
|
||||||
for (const event of result.data.events) {
|
for (const event of result.data.events) {
|
||||||
|
console.log(event);
|
||||||
|
|
||||||
if (event.event_type === 'change_model') {
|
if (event.event_type === 'change_model') {
|
||||||
const { target_data } = event;
|
const { target_data } = event;
|
||||||
console.log(event.target_data);
|
console.log(event.target_data);
|
||||||
|
|||||||
@ -29,8 +29,7 @@ export class AppCamera extends Monobehiver {
|
|||||||
this.object.panningSensibility = 0;
|
this.object.panningSensibility = 0;
|
||||||
|
|
||||||
// 限制垂直角范围,实现上帝视角
|
// 限制垂直角范围,实现上帝视角
|
||||||
// this.object.upperBetaLimit = Tools.ToRadians(60); // 最大垂直角(接近90度,避免万向锁)
|
this.object.upperBetaLimit = Tools.ToRadians(90); // 最大垂直角(接近90度,避免万向锁)
|
||||||
// this.object.lowerBetaLimit = Tools.ToRadians(60); // 最小垂直角
|
|
||||||
|
|
||||||
this.object.position = new Vector3(-0, 10, 0);
|
this.object.position = new Vector3(-0, 10, 0);
|
||||||
this.setTarget(0, 2, 0);
|
this.setTarget(0, 2, 0);
|
||||||
|
|||||||
@ -12,7 +12,7 @@ export const AppConfig = {
|
|||||||
envPath: '/hdr/sanGiuseppeBridge.env',
|
envPath: '/hdr/sanGiuseppeBridge.env',
|
||||||
intensity: 1.5,
|
intensity: 1.5,
|
||||||
rotationY: 0,
|
rotationY: 0,
|
||||||
background: true,
|
background: false,
|
||||||
},
|
},
|
||||||
gizmo: {
|
gizmo: {
|
||||||
position: true,
|
position: true,
|
||||||
|
|||||||
@ -554,6 +554,24 @@ export class AppModel extends Monobehiver {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有模型的元数据
|
||||||
|
* @returns 所有模型的元数据数组
|
||||||
|
*/
|
||||||
|
getAllModelMetadata(): ModelMetadata[] {
|
||||||
|
const keys = this.modelDic.Keys();
|
||||||
|
const metadataList: ModelMetadata[] = [];
|
||||||
|
|
||||||
|
for (const key of keys) {
|
||||||
|
const metadata = this.modelMetadataDic.Get(key);
|
||||||
|
if (metadata) {
|
||||||
|
metadataList.push(metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return metadataList;
|
||||||
|
}
|
||||||
|
|
||||||
private getModelTransformTargets(meshes: AbstractMesh[]): AbstractMesh[] {
|
private getModelTransformTargets(meshes: AbstractMesh[]): AbstractMesh[] {
|
||||||
const meshSet = new Set<AbstractMesh>(meshes);
|
const meshSet = new Set<AbstractMesh>(meshes);
|
||||||
const rootMeshes = meshes.filter(mesh => !mesh.parent || !meshSet.has(mesh.parent as AbstractMesh));
|
const rootMeshes = meshes.filter(mesh => !mesh.parent || !meshSet.has(mesh.parent as AbstractMesh));
|
||||||
|
|||||||
@ -82,6 +82,18 @@ export class KernelAdapter {
|
|||||||
*/
|
*/
|
||||||
exists: (modelId: string): boolean => {
|
exists: (modelId: string): boolean => {
|
||||||
return this.mainApp.appModel.exists(modelId);
|
return this.mainApp.appModel.exists(modelId);
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 获取所有模型的元数据
|
||||||
|
* @returns 所有模型的元数据数组,包含 modelName, modelId, modelControlType 等信息
|
||||||
|
* @example
|
||||||
|
* // 获取所有模型
|
||||||
|
* const allModels = kernel.model.getAllMetadata();
|
||||||
|
* // 查找特定类型的模型
|
||||||
|
* const pergola = allModels.find(m => m.modelControlType === 'pergola');
|
||||||
|
*/
|
||||||
|
getAllMetadata: (): any[] => {
|
||||||
|
return this.mainApp.appModel.getAllModelMetadata();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user