# Room3D
**Repository Path**: dan90s/room3d
## Basic Information
- **Project Name**: Room3D
- **Description**: Room3D是一款JS插件,它可以帮你用纯html/css快速构建3D房间或盒子。
Room3D is a javascript plugin which you can use it to create a 3D room or box by html&css so easily.
- **Primary Language**: JavaScript
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 14
- **Forks**: 1
- **Created**: 2022-06-02
- **Last Updated**: 2025-02-27
## Categories & Tags
**Categories**: Uncategorized
**Tags**: css3dbox, 3droom, 3dbox, html-3d-box, 3d房间
## README
# Room3D
## 介绍
Room3D是一款JS插件,它能帮你用纯html/css快速构建3D房间和盒子。
这是一个轻量且不依赖任何第三方库的插件,设计它的初衷仅用于帮助开发者快速构建简单布局的3D场景,或者用于简易3D特效。如果你需要构建复杂场景,且对渲染效果要求较高,建议使用基于WebGL的3D库,如threeJs/babylonJs等。
———— 作者:DAN
***
中文文档 | [English Document](readme-en.md) | [DEMO on gitee](http://dan90s.gitee.io/room3d) | [DEMO on git](https://danhu1990.github.io/Room3D/) | [Github仓库](https://github.com/Danhu1990/Room3D) | [Npm Package](https://www.npmjs.com/package/room3d)
---


## 使用方法
1. 安装插件,你将获得一个名为 `Scene3D` 的构造函数
+ 通过 `` 标签引入html文件,或者
+ 在模块化开发中,通过 `npm install room3d` 安装插件,然后
- 使用 `const Scene3D = require("room3d")` 或者
- `import Scene3D from "room3d"` 都能获得 `Scene3D` 构造函数
2. 引入样式文件 `room3d.css`
3. 准备Html元素 `
` ,选择器可使用id或class。你可以手动为元素设置css `width` 和 `height` ,如果未设置,插件将会为其设置 `widt:100%; height:100%;`
4. 编写脚本使用配置项创建场景和元素吧
```javascript
let myScene = new Scene3D("#wraper",{
width:"400px",
depth:"400px",
rooms:[
{
height:"400px",
boxes:[
{
width:"100px",
depth:"100px",
height:"100px",
left:"150px",
top:"160px",
color:"green"
}
]
}
]
})
```
## 关系图

## API
### Scene 场景对象
#### 配置项
| 属性名 | 值类型 | 默认值 | 说明 |
| :---- | :----: | :----: | ---- |
| **width** | string | "1000px" | 场景宽度,必须包含px等单位,不支持百分比 |
| **depth** | string | "1000px" | 场景进深,必须包含px等单位,不支持百分比 |
| **offsetVer** | string | "-200px" | 场景垂直方向偏移,负数为向下偏移,正数向上偏移,不支持百分比 |
| **rotateVer** | string | "70deg" | 场景初始垂直方向旋转角度,必须携带单位deg,负值为反方向旋转 |
| **rotateHor** | string | "-40deg" | 场景初始水平方向旋转角度,必须携带单位deg,负值为反方向旋转 |
| **scaleRat** | number | 0.8 | 场景初始缩放比例 |
| **wheelScale** | boolean | true | 允许使用滚轮缩放场景 |
| **showGrid** | boolean | true | 是否显示网格 |
| **perspective** | number | 2000 | 透视系数,不允许负值,默认2000,值越小透视感越强,值越大透视感越弱。建议最小值不低于800,最大值不超过8000。 |
| **dragRotate** | boolean | true | 允许使用鼠标拖拽旋转场景 |
| **rotateFixed** | string | "aroundRestric" | 旋转限制,仅在 `dragRotate` 设置为 `true` 有效,可选值:
"`around`" :可水平、垂直任意旋转。
"`aroundRestric`" :带有限制的任意旋转,其中垂直旋转只允许0-90度,最终效果表现为,不能将场景旋转至倒立。
"`horizontal`" :只允许水平任意旋转。
"`vertical`" :只允许垂直任意旋转
"`verticalRestric`" :带有限制的垂直旋转。|
| **rooms** | array | [ ] | 房间配置对象,用于配置Room房间对象 |
#### 方法
创建一个Scene对象 `let Scene = new Scene3D("#Scene1",{options...})` ,该对象将可以使用以下方法:
+ **`Scene.showGrid( boolean )`**
- **参数**\
boolean {boolean} | `必须` | 传true表示显示,false表示隐藏
- **返回值**\
返回当前Scene对象,可用于链式调用
- **说明**\
用于显示或隐藏场景的网格
+ **`Scene.resetScene()`**
- **参数**\
\-
- **返回值**\
返回当前Scene对象,可用于链式调用
- **说明**\
重置场景旋转和缩放状态至初始值
+ **`Scene.buildRoom( options )`**
- **参数**\
options {object} | `可选` | 配置对象,参照Room配置项
- **返回值**\
返回被创建的Room对象
- **说明**\
用传入的配置参数,手动创建Room,如果不传options参数,则使用默认配置创建Room
***
### Room 房间对象
#### 配置项
| 属性名 | 值类型 | 默认值 | 说明 |
| :---- | :----: | :----: | ---- |
| **className** | string | "" | 房间类名,将使用 `"Room3D_room_"` 进行拼接,用作房间容器的class类名 |
| **width** | string | "100%" | 房间宽度,必须包含px等单位,支持百分比 |
| **depth** | string | "100%" | 房间进深,必须包含px等单位,支持百分比 |
| **height** | string | "300px" | 房间高度,必须包含px等单位,不支持百分比 |
| **left** | string | "auto" | 房间距场景左边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **top** | string | "auto" | 房间距场景后边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **right** | string | "auto" | 房间距场景右边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **bottom** | string | "auto" | 房间距场景前边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **showWall** | boolean | true | 是否显示墙壁 |
| **wallColor** | string | "#ddd" | 墙壁颜色,可使用css支持的所有色值类型 |
| **wallOpacity** | number | 0.9 | 墙壁透明度 |
| **wallBackFace** | string | "hidden" | 墙背面是否透明,可选参数: `"hidden"` , `"visible"` |
| **showLine** | boolean | true | 是否显示墙角线 |
| **lineColor** | string | "#666" | 墙角线颜色,可使用css支持的所有色值类型 |
| **lineOpacity** | number | 1 | 墙角线透明度 |
| **lineWidth** | string | "1px" | 墙角线粗细 |
| **showFloor** | boolean | true | 是否显示地板 |
| **floorColor** | string | "#444" | 地板颜色,可使用css支持的所有色值类型 |
| **floorOpacity** | number | 1 | 地板透明度 |
| **boxes** | array | [ ] | 房间内Box盒子对象 |
其中 `top` `right` `bottom` `left` 用于定位房间在场景中的水平位置,一般 `left` 和 `right` 只需要设置其中一项即可。`top` 和 `bottom` 同理\
关于宽度、进深、高度如何定义,可查看文档顶部的图示。
#### 方法
创建一个Room对象 `let Room = Scene.buildRoom()` 。如果是通过配置对象生成的Room,则可以通过 `let Room = Scene.rooms[index]` 获得Room对象,该对象可以使用以下方法:
+ **`Room.showFloor( boolean )`**
+ **`Room.showWall( boolean )`**
+ **`Room.showLine( boolean )`**
- **参数**\
boolean {boolean} | `必须` | 传true表示显示,false表示隐藏
- **返回值**\
返回当前Room对象,可用于链式调用
- **说明**\
用于显示或隐藏Room的Floor地板、Wall墙壁、Line墙角线。
+ **`Room.backface( value )`**
- **参数**\
value {string} | `必须` | value可以为 "hidden" 或 "visible"
- **返回值**\
返回当前Room对象,可用于链式调用
- **说明**\
用于设置墙壁元素的 `backface-visibility` 样式,具体表现是:设置为"hidden",朝向屏幕方向的墙壁将变成透明的,从而可以看见房间内的元素,且不会遮挡鼠标与房间内元素的交互。
+ **`Room.buildDoor( wall , doorOptions )`**
- **参数**\
wall {string} | `必须` | wall参数可选值为 `"left"` , `"right"` , `"fore"` , `"back"`
doorOptions {object} | `可选` | 门的配置项对象,详细配置参数见下方的Door配置项。
- **返回值**\
返回被创建的Door对象
- **说明**\
用传入的配置参数,手动创建Door。
##### Door 配置项
| 属性名 | 值类型 | 默认值 | 说明 |
| :---- | :----: | :----: | ---- |
| **className** | string | "" | 门类名,将使用 `"Room3D_door_"` 进行拼接,用作门容器的class类名 |
| **width** | string | "60px" | 门宽度,必须包含px等单位,允许使用百分比,不允许负值 |
| **height** | string | "120px" | 门高度,必须包含px等单位,允许使用百分比,不允许负值 |
| **left** | string | "50%" | 门距墙左边缘距离,可设置为包含单位的数值或百分比值 |
| **right** | string | \- | 门距墙右边缘距离,可设置为包含单位的数值或百分比值,如果希望以 `right` 值作为定位,必须将 `left` 设置为 `auto` |
| **show** | boolean | true | 是否显示门,如果为 `false` ,则只能看到门洞。 |
| **type** | string | "single left" | 门类型,可选参数:`"single left"` 单开门,门轴在左侧、 `"single right"` 单开门,门轴在右侧、 `"double"` 双开门。 |
| **openSide** | string | "outside" | 开门的方向,`"outside"` 朝外开门、 `"inside"` 朝内开门。 |
| **color** | string | "#634A42" | 颜色色值,设置门板的颜色。 |
| **doorFrameWidth** | string | "3px" | 门框宽度,可以为包含单位的数值,不允许百分比。 |
| **doorFrameColor** | string | "#3B2A24" | 门框颜色 |
##### Door 方法
使用 `let Door = Room.buildDoor( wall , doorArray )[index]` 或者 `let Door = Room.walls[wall].doors[index]` 获取Door对象,该对象可以使用以下方法:
+ **`Door.openDoor()`** 将门打开
+ **`Door.closeDoor()`** 将门关闭
+ **`Room.buildBox( options )`**
- **参数**\
options {object} | `可选` | 配置对象,参数见Box配置项
- **返回值**\
返回被创建的Box对象
- **说明**\
用传入的配置参数,手动创建Box,如果不传options参数,则使用默认配置创建Box
+ **`Room.destroy()`**
- **参数**\
\-
- **返回值**\
\-
- **说明**\
销毁Room实例对象
***
### Box 盒子对象
#### 配置项
| 属性名 | 值类型 | 默认值 | 说明 |
| :---- | :----: | :----: | ---- |
| **className** | string | "" | 盒子类名,将使用 `"Box3D_box_"` 进行拼接,用作盒子容器的class类名 |
| **name** | string | "" | 盒子名称,将显示在Marker标注上 |
| **width** | string | "100%" | 盒子宽度,必须包含px等单位,支持百分比 |
| **depth** | string | "100%" | 盒子进深,必须包含px等单位,支持百分比 |
| **height** | string | "100%" | 盒子高度,必须包含px等单位,支持百分比 |
| **left** | string | "auto" | 盒子距房间左边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **top** | string | "auto" | 盒子距房间后边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **right** | string | "auto" | 盒子距房间右边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **bottom** | string | "auto" | 盒子距房间前边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **offsetZ** | string | "0px" | 垂直偏移距离,必须包含单位,不允许百分比,负值表示向下偏移 |
| **rotateX** | string | "0deg" | X轴旋转角度,必须包含单位deg |
| **rotateY** | string | "0deg" | Y轴旋转角度,必须包含单位deg |
| **rotateZ** | string | "0deg" | Z轴旋转角度,必须包含单位deg |
| **opacity** | number | 1 | 盒子透明度 |
| **color** | string | "#999" | 盒子颜色,可使用css支持的所有色值类型 |
| **showLine** | boolean | true | 是否显示边角线 |
| **lineColor** | string | "#666" | 边角线颜色,可使用css支持的所有色值类型 |
| **lineOpacity** | number | 1 | 边角线透明度 |
| **lineWidth** | string | "1px" | 边角线粗细 |
| **marker** | object | { } | 盒子标注配置项 |
其中 `top` `right` `bottom` `left` 用于定位盒子在房间中的水平位置,一般 `left` 和 `right` 只需要设置其中一项即可。`top` 和 `bottom` 同理
#### 方法
创建一个Box对象 `let Box = Room.buildBox()` 。如果是通过配置对象生成的Box,则可以通过 `let Box = Room.boxes[index]` 获得Box对象,该对象可以使用以下方法:
+ **`Box.showLine( boolean )`**
+ **`Box.showMarker( boolean )`**
- **参数**\
boolean {boolean} | `必须` | 传true表示显示,false表示隐藏
- **返回值**\
返回当前Box对象,可用于链式调用
- **说明**\
用于显示或隐藏Box的Line边角线、Marker标注。
+ **`Box.buildMarker( options )`**
- **参数**\
options {object} | `可选` | 配置对象,参数见Marker配置项
- **返回值**\
返回被创建的Marker对象
- **说明**\
每一个Box对象被创建的时候会顺便自动创建相应的Marker对象,所以该方法实际上是先销毁原有的标注,再用新的配置项重新创建一个标注。如果你只是希望改变标注的一些数据,可以使用Marker对象的 `updateMarker()` 方法。
+ **`Box.destroy()`**
- **参数**\
\-
- **返回值**\
\-
- **说明**\
销毁Box实例对象
***
### Marker 标注对象
#### 配置项
| 属性名 | 值类型 | 默认值 | 说明 |
| :---- | :----: | :----: | ---- |
| **width** | string | "auto" | 标注宽度,必须包含px等单位,不允许百分比和负值,默认自适应 |
| **height** | string | "auto" | 标注高度,必须包含px等单位,不允许百分比和负值,默认自适应 |
| **left** | string | expression | 标注距场景左边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **top** | string | expression | 标注距场景后边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **right** | string | "auto" | 标注距场景右边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **bottom** | string | "auto" | 标注距场景前边缘距离,可设置为包含单位的数值、百分比或 `auto` |
| **offsetZ** | string | expression | 标注在场景中的垂直高度,可设置为包含单位的数值,不允许百分比、 `auto`或负值。 |
| **show** | boolean | true | 是否显示标注 |
| **lineColor** | string | "#666" | 标注连接线颜色 |
| **lineWidth** | string | "1px" | 标注连接线宽度 |
| **fontSize** | string | "14px" | 标注默认文字大小 |
| **fontColor** | string | "#ffffff" | 标注文字颜色 |
| **backgroundColor** | string | "rgba(36, 212, 174, 0.9)" | 标注背景色,Marker对象没有提供opacity属性,如果需要让标注透明,可以使用带有alpha通道的色值。 |
| **content** | string | "\
\{\{params.title\}\}\<\/h4>" | 标注内容模板,可使用{{params.属性名}}的形式作为占位符,用于接收params属性传入的参数。你可以使用html字符串编辑更丰富的标注模板 |
| **params** | object |\{title:box.options.name \|\| "Marker"\}| 保存需要被传递的参数,用于解析标注内容模板,默认会将与之绑定的Box对象配置项中的name值传递进来。 |
由于在dom结构中标注是直接创建在场景中,所以其 `top` `right` `bottom` `left` 是相对于场景的定位,同样 `left` 和 `right` 以及`top` 和 `bottom`只需要设置其中一项即可。并且由于 `left` 和 `top` 的默认值是一个表达式,用于将标注创建在盒子的正上方,所以如果需要用 `right` 和 `bottom` 进行定位,则必须将对应的 `left` 和 `top` 值设置为 `auto` 。
#### 方法
创建一个Marker对象并获取它 `let Marker = Box.buildMarker()` 。如果要获取已经生成的Marker,则可以通过 `let Marker = Box.marker` 获得,该对象可以使用以下方法:
+ **`Marker.updateMarker( params )`**
- **参数**\
params {object} | `必须` | params对象必须包含与标注content模板相匹配的属性,以及需要更新的值。
- **返回值**\
返回当前Marker对象
- **说明**\
用于更新Marker内容模板。
+ **`Marker.destroy()`**
- **参数**\
\-
- **返回值**\
\-
- **说明**\
销毁Marker实例对象
***
## 注意事项
1. 所有的长度及距离数值必须使用统一的单位,推荐使用px,否则会出现一些因为单位换算而导致的bug
2. 两个紧贴相邻的Room如果需要在紧贴着的墙上创建门,需要在两个Room上对应的墙上都使用 `buildDoor()` 方法,在对称的位置创建门,同时将其中一个门设置为不可见,即可实现。
3. 你还可以使用css为场景内的各种元素设置 `background-image` 样式,模仿贴图效果,从而实现更丰富的场景。
## NPM包版本与更新
+ `1.0.0` 发布时间:2022/6/8
- `1.0.1` & `1.0.2` 发布时间:2022/6/8
+ 修改说明文档
- `1.1.0` 发布时间:2022/6/15
+ Marker 对象添加 `scene` 属性,它的值指向当前场景对象;
+ Box 对象增加 `.destroy()` 方法;
+ Room 对象增加 `.destroy()` 方法。
## 其他
