three实现三维建筑沙盘代码
代码语言:html
所属分类:其他
代码由minimax-m3.1-flash ai生成,可能有错误,仅供参考:点击查看提示词
代码描述:三维建筑沙盘
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
<title>大唐長安城 · 程序化建筑沙盘</title>
<style>
:root{ --fg:#d7dee6; --dim:#8b98a6; }
*{ box-sizing:border-box; }
html,body{ margin:0; height:100%; overflow:hidden; background:#0b0f13; color:var(--fg);
font-family:"PingFang SC","Hiragino Sans GB","Microsoft YaHei",system-ui,-apple-system,sans-serif;
-webkit-font-smoothing:antialiased; }
#app{ position:fixed; inset:0; }
#app canvas{ display:block; }
.ov{ position:fixed; z-index:5; pointer-events:none; user-select:none; }
#brand{ left:24px; top:20px; }
#brand h1{ margin:0; font-size:16px; font-weight:600; letter-spacing:.30em;
color:#e9eef3; text-shadow:0 2px 10px rgba(0,0,0,.65); }
#brand h1 small{ font-size:10px; letter-spacing:.16em; color:#96a3b1; margin-left:8px; font-weight:400; }
#brand p{ margin:6px 0 0; font-size:11px; letter-spacing:.10em; color:var(--dim);
text-shadow:0 1px 6px rgba(0,0,0,.7); }
#hint{ left:24px; bottom:20px; font-size:11.5px; letter-spacing:.08em; color:#8390a0;
background:rgba(10,14,18,.45); border:1px solid rgba(255,255,255,.07);
padding:7px 13px; border-radius:999px; backdrop-filter:blur(7px); }
#legend{ right:24px; bottom:20px; font-size:11px; line-height:1.85; color:#7c8896;
text-align:right; text-shadow:0 1px 6px rgba(0,0,0,.8); }
#legend b{ color:#b9c4d0; font-weight:500; }
#boot{ position:fixed; inset:0; z-index:30; display:flex; align-items:center; justify-content:center;
background:#0b0f13; color:#7f8b99; font-size:12px; letter-spacing:.24em; transition:opacity .5s ease; }
#boot.hide{ opacity:0; pointer-events:none; }
.lil-gui{ --background-color:rgba(14,18,23,.86); --widget-color:rgba(36,44,53,.92);
--hover-color:rgba(52,64,76,.95); --focus-color:#3f7ea6; --text-color:#c6d1dc;
--title-background-color:rgba(20,26,32,.95); --title-text-color:#e3eaf1;
--number-color:#8ecdfa; --string-color:#a3dfb8; --font-size:11px; --input-font-size:11px;
--padding:6px; --spacing:4px; --widget-height:20px; z-index:20; }
@media (max-width:760px){ #legend{ display:none; } #brand p{ display:none; } }
</style>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/",
"lil-gui": "https://cdn.jsdelivr.net/npm/lil-gui@0.20.0/dist/lil-gui.esm.js"
}
}
</script>
</head>
<body>
<div id="app"></div>
<div id="boot">正在生成沙盘…</div>
<div id="brand" class="ov">
<h1>大唐長安城<small>CHANG’AN · TANG DYNASTY</small></h1>
<p>外郭城 · 皇城 · 宫城 · 三大内 · 坊市棋盘 · 程序化生成</p>
</div>
<div id="hint" class="ov">拖拽旋转 · 滚轮缩放 · 右键平移</div>
<div id="legend" class="ov">
<b>三大内</b> 太极宫 · 大明宫 · 兴庆宫<br />
<b>标志</b> 大雁塔 · 丹凤门 · 明德门 · 东西二市
</div>
<script type="module">
/* =========================================================================
* 大唐长安城 · Three.js 程序化建筑沙盘
* 0. 依赖 1. CONFIG 2. 工具函数 3. 材质库 4. 场景构建
* 5. 交互 6. 主循环 7. 事件绑定与启动
* ========================================================================= */
import * as THREE from 'three';
import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
import { mergeGeometries } from 'three/addons/utils/BufferGeometryUtils.js';
import GUI from 'lil-gui';
/* =========================================================================
* 1. CONFIG —— 全部可调参数
* ========================================================================= */
const CONFIG = {
seed: 20261026,
city: {
plate: { w: 64, d: 56, radius: 3.6, baseDepth: 2.9, groundInset: 0.9, groundY: 0.02 },
wall: { height: 3.2, thickness: 1.0, merlon: true },
grid: { cols: 10, rows: 10, street: 1.7, axisStreet: 3.6 },
bounds: { x: 31, z: 27 } // 外郭城半尺寸
},
/* 主体大殿(默认:含元殿)—— GUI 可实时重建 */
hall: {
floors: 1, // 殿身层数
floorHeight: 3.8,
width: 17, // 面阔
depth: 9.5, // 进深
setbackStages: 2, // 收分段数(重檐层数)
stageScale: 0.70, // 每段收进比例
podiumFloors: 3, // 台基层数
podiumHeight: 1.7,
podiumInset: 0.8,
parapetHeight: 0.85,
roofType: 'hip', // hip 庑殿顶 | xieshan 歇山顶 | cuanshan 攒尖顶
roofHeight: 3.0,
overhang: 1.3,
bays: 9,
sizeScale: 1.0
},
/* 楼阁(花萼相辉楼 / 市楼) */
tower: {
floors: 3, floorHeight: 2.3, width: 5.6, depth: 5.6,
setbackStages: 3, stageScale: 0.80, podiumFloors: 1, podiumHeight: 1.0,
podiumInset: 0.6, parapetHeight: 0.6, roofType: 'hip', roofHeight: 1.9,
overhang: 0.9, bays: 3
},
sun: { azimuth: 46, elevation: 38, intensity: 3.1 },
night: {
mode: false,
emissive: 2.8, // 窗光强度
environment: 0.16, // 环境光强度
hemisphere: 0.18,
sun: 0.40,
skyScale: 0.34
},
props: { trees: 300, people: 160, carts: 16, horses: 14, show: true },
labels: { show: true },
cover: { show: false }, // 范围罩(半透明玻璃罩示意)
camera: {
fov: 40, near: 0.5, far: 900,
position: [71, 60, 79], target: [7, 2, -6],
minDistance: 16, maxDistance: 190
},
render: {
shadowMapSize: 2048, exposure: 1.0, maxPixelRatio: 2,
fog: [150, 460]
},
gui: { autoRotate: true, autoRotateSpeed: 0.30, idleResume: 3.2 }
};
/* 城市平面分区(世界坐标;z 负方向为北) */
const ZONE = {
palaceCity: { x0: -13, x1: 13, z0: -19, z1: -9 },
imperialCity: { x0: -13, x1: 13, z0: -8, z1: 8 },
daming: { x0: 8, x1: 29, z0: -25, z1: -14.5 },
xingqing: { x0: 14, x1: 25.5, z0: -13.5, z1: -4 },
westMarket: { x0: -27, x1: -17, z0: 11, z1: 21 },
eastMarket: { x0: 17, x1: 27, z0: 11, z1: 21 },
cienTemple: { x0: 3.5, x1: 11.5, z0: 15, z1: 24 },
jianfuTemple: { x0: -22, x1: -16, z0: -2, z1: 4 },
xingshan: { x0: -13.5,x1: -9, z0: 14, z1: 19 },
qujiang: { x0: 19.5, x1: 28, z0: 3.5, z1: 10.5 }
};
const RESERVED = Object.values(ZONE);
/* =========================================================================
* 2. 工具函数
* ========================================================================= */
/* 确定性随机数(mulberry32):保证每次打开模型一致 */
const _rand = (() => {
let s = CONFIG.seed >>> 0;
return function () {
s = (s + 0x6D2B79F5) >>> 0;
let t = Math.imul(s ^ (s >>> 15), 1 | s);
t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
};
})();
function randomRange(min, max) { return min + _rand() * (max - min); }
function randomInt(min, max) { return Math.floor(randomRange(min, max + 1)); }
function clamp(v, a, b) { return Math.min(b, Math.max(a, v)); }
function smoothstep(e0, e1, x) { const t = clamp((x - e0) / (e1 - e0), 0, 1); return t * t * (3 - 2 * t); }
/* 程序化画布贴图 */
function makeCanvasTexture(draw, size = 256, opts = {}) {
const w = opts.w || size, h = opts.h || size;
const c = document.createElement('canvas');
c.width = w; c.height = h;
const ctx = c.getContext('2d');
draw(ctx, w, h);
const tex = new THREE.CanvasTexture(c);
tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
tex.repeat.set(opts.repeat ? opts.repeat[0] : 1, opts.repeat ? opts.repeat[1] : 1);
tex.anisotropy = opts.anisotropy || 8;
if (opts.srgb !== false) tex.colorSpace = THREE.SRGBColorSpace;
return tex;
}
/* 释放一组对象(几何体必释放;材质仅释放标记 dynamic 的) */
function disposeGroup(group) {
if (!group) return;
group.traverse((o) => {
if (o.geometry) o.geometry.dispose();
const mats = Array.isArray(o.material) ? o.material : (o.material ? [o.material] : []);
mats.forEach((m) => { if (m && m.userData &&a.........完整代码请登录后点击上方下载按钮下载查看















网友评论0