update .gitgnore

This commit is contained in:
hujinwei
2022-11-04 11:39:56 +08:00
parent d89ce6f05d
commit ec65c97e99
400 changed files with 12826 additions and 30162 deletions

3
.gitignore vendored
View File

@ -4,6 +4,9 @@
/node_modules
/.pnp
.pnp.js
package-lock.json
.idea
/public/demo/projects
# testing
/coverage

View File

@ -1,46 +1,9 @@
# Getting Started with Create React App
# gemini-viewer-examples
Examples and demos for gemini-viewer sdk
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
# start
npm install
## Available Scripts
npm start
In the project directory, you can run:
### `npm start`
Runs the app in the development mode.\
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
The page will reload if you make edits.\
You will also see any lint errors in the console.
### `npm test`
Launches the test runner in the interactive watch mode.\
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
### `npm run build`
Builds the app for production to the `build` folder.\
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.\
Your app is ready to be deployed!
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
### `npm run eject`
**Note: this is a one-way operation. Once you `eject`, you cant go back!**
If you arent satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point youre on your own.
You dont have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldnt feel obligated to use this feature. However we understand that this tool wouldnt be useful if you couldnt customize it when you are ready for it.
## Learn More
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
To learn React, check out the [React documentation](https://reactjs.org/).
http://localhost:3000/#/demo

30042
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -3,6 +3,11 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@codemirror/autocomplete": "^6.3.0",
"@codemirror/commands": "^6.1.2",
"@codemirror/lang-javascript": "^6.1.1",
"@codemirror/state": "^6.1.2",
"@codemirror/view": "^6.4.0",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
@ -10,9 +15,15 @@
"@types/node": "^16.18.0",
"@types/react": "^18.0.23",
"@types/react-dom": "^18.0.7",
"@uiw/codemirror-theme-sublime": "^4.12.4",
"antd": "^4.24.0",
"codemirror": "^6.0.1",
"http-proxy-middleware": "^2.0.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.4.3",
"react-scripts": "5.0.1",
"recoil": "^0.7.6",
"typescript": "^4.8.4",
"web-vitals": "^2.1.4"
},

58
public/config.json Normal file
View File

@ -0,0 +1,58 @@
[{
"title": "模型",
"subMenus": [{
"title": "本地模型加载",
"url": "./demo/empty_model_project.html"
}, {
"title": "technical school",
"url": "./demo/technical_school.html"
}]
}, {
"title": "图纸",
"subMenus": [{
"title": "本地图纸加载",
"url": "../demo/empty_dxf_project.html"
}, {
"title": "Rac Basic Sample Project",
"url": "./demo/dxf_0.html"
}, {
"title": "运维监控楼地下一层 、首层平面图",
"url": "./demo/dxf_1.html"
}, {
"title": "厨房平面",
"url": "./demo/dxf_2.html"
}, {
"title": "图纸对比",
"url": "./demo/dxf_3.html"
}, {
"title": "多屏图纸对比",
"url": "./demo/dxf_4.html"
}]
}, {
"title": "全景图",
"subMenus": [{
"title": "本地全景图加载",
"url": "./demo/empty_vr_project.html"
}, {
"title": "全景图(1张图)",
"url": "./demo/vr_0.html"
}, {
"title": "全景图(6张图)",
"url": "./demo/vr_1.html"
}, {
"title": "全景图(6张图)",
"url": "./demo/vr_2.html"
}, {
"title": "全景图(24张图)",
"url": "./demo/vr_3.html"
}, {
"title": "全景图(模块替换)",
"url": "./demo/vr_4.html"
}, {
"title": "全景图(双屏)",
"url": "./demo/vr_5.html"
}, {
"title": "全景图切换",
"url": "./demo/vr_album_0.html"
}]
}]

View File

@ -0,0 +1,71 @@
b {
font-weight: bold;
}
.hide {
display: none;
}
.compare-panel-container {
position: absolute;
top: 80px;
right: 0;
width: 160px;
height: auto;
min-height: 200px;
padding: 10px;
z-index: 100;
box-sizing: border-box;
background-color: #fff;
user-select: none;
}
.compare-panel-container h3 {
position: fixed;
margin: 0;
padding-left: 5px;
line-height: 30px;
border-bottom: 1px solid #aaa;
font-size: 14px;
font-weight: bold;
}
.compare-detail {
margin-top: 35px;
max-height: 500px;
overflow: hidden;
cursor: pointer;
}
.compare-list {
margin-top: 6px;
}
.list-title {
display: flex;
align-items: center;
}
.title-icon {
padding: 5px;
}
.title-icon::before {
content: '';
display: block;
width: 0;
height: 0;
border-right: 8px solid #666;
border-top: 8px solid transparent;
}
.compare-collapse .title-icon::before {
transform: rotate(-40deg);
}
.title-content {
font-size: 12px;
}
.compare-detail ul {
margin-left: 18px;
max-height: 150px;
font-size: 12px;
overflow: scroll;
}
.compare-detail ul li {
margin: 6px 0;
}

View File

@ -0,0 +1,101 @@
/* eslint-disable no-undef */
export default class CompareSidePanel {
compareDetail;
container;
viewer;
constructor(viewer, container = document.body) {
this.init(viewer, container);
}
init(viewer, container) {
this.viewer = viewer;
this.container = container;
this.buildPanel();
this.initEvents();
}
buildPanel() {
const panelContainer = document.createElement("div");
panelContainer.classList.add("compare-panel-container");
const header = document.createElement("h3");
panelContainer.appendChild(header);
this.container.appendChild(panelContainer);
const compareDetail = document.createElement("div");
compareDetail.classList.add("compare-detail");
panelContainer.appendChild(compareDetail);
this.compareDetail = compareDetail;
const changes = this.viewer.changes;
const changesValues = Object.values(changes);
header.innerHTML = `差异列表(${changesValues.length})`;
const addedChangesValues = changesValues.filter((val) => val.type === "Added");
const deletedChangeValues = changesValues.filter((val) => val.type === "Deleted");
const modifiedChanageValues = changesValues.filter((val) => val.type === "Modified");
if (addedChangesValues.length > 0) {
this.buildList(addedChangesValues, "新增");
}
if (deletedChangeValues.length > 0) {
this.buildList(deletedChangeValues, "删除");
}
if (modifiedChanageValues.length > 0) {
this.buildList(modifiedChanageValues, "修改");
}
}
buildList(changesValues, text) {
const section = document.createElement("div");
section.classList.add("compare-list", "compare-add");
this.compareDetail.appendChild(section);
this.buildListTitle(section, `${text}(<b>${changesValues.length}</b>)`);
const listEle = document.createElement("ul");
listEle.classList.add("list", "hide");
section.appendChild(listEle);
let listFragment = "";
changesValues.forEach((val) => {
listFragment += `<li class="list-item">${val.handle}</li>`;
});
listEle.innerHTML = listFragment;
}
buildListTitle(group, title) {
const listTitle = document.createElement("div");
listTitle.classList.add("list-title", "compare-collapse");
group.appendChild(listTitle);
const titleIcon = document.createElement("span");
titleIcon.classList.add("title-icon");
listTitle.appendChild(titleIcon);
const titleContent = document.createElement("span");
titleContent.classList.add("title-content");
titleContent.innerHTML = title;
listTitle.appendChild(titleContent);
}
initEvents() {
const listTitles = document.querySelectorAll(".list-title");
listTitles.forEach((listTitle) => {
listTitle.addEventListener("click", () => {
listTitle.classList.toggle("compare-collapse");
listTitle.nextSibling?.classList.toggle("hide");
});
});
const lists = document.querySelectorAll(".list");
lists.forEach((list) => {
list.addEventListener("click", (e) => {
this.viewer.zoomToCompareChange(e.target.innerHTML);
});
});
}
}

View File

@ -0,0 +1,85 @@
[
{
"id": "rac_basic_sample_project",
"name": "rac basic sample project",
"thumbnail": "projects/rac_basic_sample_project/thumbnail.png",
"camera": {
"eye": [-65, 37, 41],
"look": [-15, 0, 15]
},
"models": [{
"name": "rac basic sample project",
"src": "projects/rac_basic_sample_project/rac_basic_sample_project.gltf",
"position": [0, 0, 0],
"rotation": [-90, 0, 0],
"scale": [0.001, 0.001, 0.001],
"instantiate": false,
"merge": false,
"edges": true,
"visible": true
}]
}, {
"id": "technical_school",
"name": "technical school",
"thumbnail": "projects/technical_school/thumbnail.png",
"camera": {
"eye": [-65, 37, 41],
"look": [-15, 0, 15]
},
"models": [{
"name": "technical school",
"src": "projects/technical_school/technical_school.gltf",
"position": [0, 0, 0],
"rotation": [-90, 0, 0],
"scale": [0.001, 0.001, 0.001],
"instantiate": false,
"merge": false,
"edges": true,
"visible": true
}]
}, {
"id": "misc",
"name": "misc",
"thumbnail": "projects/misc/thumbnail.png",
"camera": {
"eye": [30, 40, -100],
"look": [30, 5, -20]
},
"models": [{
"name": "building_1.ifc",
"src": "projects/misc/building_1.ifc",
"position": [0, 0, 0],
"edges": true
}, {
"name": "cgaxis_tree.fbx",
"src": "projects/misc/cgaxis_tree.fbx",
"position": [20, 0, 0],
"scale": [0.05, 0.05, 0.05]
}, {
"name": "cgaxis_tree.obj",
"src": "projects/misc/cgaxis_tree.obj",
"position": [30, 0, 0],
"scale": [0.05, 0.05, 0.05]
}, {
"name": "M4A1.dae",
"src": "projects/misc/M4A1.dae",
"position": [40, 0, 0],
"scale": [0.05, 0.05, 0.05],
"edges": true
}, {
"name": "car",
"src": "projects/misc/car/car.dae",
"position": [50, 0, 0],
"rotation": [-90, 0, 0],
"edges": true
}]
}, {
"id": "ifc_building",
"name": "ifc building",
"thumbnail": "projects/ifc_building/thumbnail.png",
"models": [{
"src": "projects/ifc_building/building_2.ifc",
"rotation": [0, 0, 0]
}]
}
]

141
public/demo/dxf_0.html Normal file
View File

@ -0,0 +1,141 @@
<html>
<head>
<link rel="icon" href="./demo/favicon.ico">
<link rel="stylesheet" type="text/css" href="./demo/global.css">
<link rel="stylesheet" type="text/css" href="./demo/iconfont/iconfont.css">
<link rel="stylesheet" href="./demo/layerManager/layerManager.css">
<link rel="stylesheet" href="./demo/settings/SettingsPanel.css">
<style>
#myCanvas {
position: absolute;
width: calc(100% - 100px);
width: -moz-calc(100% - 100px);
width: -webkit-calc(100% - 100px);
height: calc(100% - 80px);
height: -moz-calc(100% - 80px);
height: -webkit-calc(100vh - 80px);
left: 50px;
top: 40px;
}
</style>
</head>
<body>
<div id="viewerContainer">
<div id="myCanvas" class="renderer-container"></div>
</div>
<script type="module">
import { DxfViewer } from "./demo/libs/gemini-viewer.esm.min.js";
import DxfSettingsPanel from './demo/settings/DxfSettingsPanel.js';
import LayerManager from './demo/layerManager/LayerManager.js';
const models= [{
modelId: "dxf_0",
name: "dxf_0",
src: "./demo/projects/dxf_test/dxf_0.dxf",
merge: true,
visible: true,
}, {
modelId: "dxf_0_1",
name: "dxf_0_1",
src: "./demo/projects/dxf_test/dxf_0_1.dxf",
merge: true,
visible: true,
}];
const config = {
containerId: "myCanvas",
enableAxisGizmo: true,
enableStats: true,
enableToolbar: true,
enableSpinner: true,
enableProgressBar: true,
enableBottomBar: true,
enableLayoutBar: true,
enableSelection: true,
};
const viewer = new DxfViewer(config);
// const fontFiles = ["three/fonts/Microsoft_YaHei_Regular.typeface.json"];
const fontFiles = ["./demo/three/fonts/hztxt.shx", "./demo/three/fonts/simplex.shx"];
await viewer.setFont(fontFiles);
window.viewer = viewer;
// loadProjectModel
let counter = 0; // to indicate how many models are loading
models.forEach((modelCfg) => {
if (modelCfg.visible === false) {
// visible is true by default
return; // only load visible ones
}
counter++;
const onProgress = (event) => {
let type = "Loading progress";
if (event.type === "parseProgress") {
type = "Parsing progress";
}
const progress = ((event.loaded * 100) / event.total).toFixed(2);
console.log(`[Demo] ${type}: ${progress}%`);
};
try {
viewer.loadModelAsync(modelCfg, onProgress).then(() => {
console.log(`[Demo] Loaded model ${modelCfg.src}`);
if (!viewer.layerManager) {
viewer.layerManager = new LayerManager(viewer);
}
}).finally(() => {
counter--;
});
} catch (ex) {
console.log(ex);
}
});
// as a demo page, add dxfSettingsPanel to window!
window.dxfSettingsPanel = new DxfSettingsPanel(viewer);
const measurementData = [{
type: "Distance",
id: "measure_data_id_1",
layoutName: "Model",
points: [[0, -22000], [6000, -22000]],
}, {
type: "Area",
id: "measure_data_id_2",
layoutName: "Model",
points: [[0, -23000], [6000, -23000], [6000, -25000], [0, -25000], [0, -23000]],
}, {
type: "Angle",
id: "measure_data_id_3",
layoutName: "Model",
points: [[0, -26000], [6000, -26000], [4000, -29000]],
}, {
type: "Distance",
id: "measure_data_id_4",
layoutName: "Layout1",
points: [[0, -10000], [0, 10000]],
}];
const markupData = [{
type: "Arrow",
id: "c6ea70a3-ddb0-4dd0-87c8-bd2491936428",
lineWidth: 2,
strokeStyle: "#ff0000",
fillStyle: "#ff000030",
layoutName: "Model",
points: [[-15000, -9000], [-11000, -4000]],
}, {
type: "Rectangle",
id: "82aba74f-7cd6-40e7-bac0-78d95a7bbecd",
lineWidth: 2,
strokeStyle: "#ff0000",
fillStyle: "#ff000030",
layoutName: "Model",
points: [[-7000, -1800], [-1000, -5000]],
}];
viewer.setMeasurements(measurementData);
viewer.setMarkups(markupData);
</script>
</body>
</html>

80
public/demo/dxf_1.html Normal file
View File

@ -0,0 +1,80 @@
<html>
<head>
<link rel="icon" href="./demo/favicon.ico" />
<link rel="stylesheet" type="text/css" href="./demo/global.css" />
<link rel="stylesheet" type="text/css" href="./demo/iconfont/iconfont.css" />
<link rel="stylesheet" href="./demo/layerManager/layerManager.css" />
<link rel="stylesheet" href="./demo/settings/SettingsPanel.css">
</head>
<body>
<div id="viewerContainer">
<div id="myCanvas" class="renderer-container"></div>
</div>
<script type="module">
import { DxfViewer } from "./demo/libs/gemini-viewer.esm.min.js";
import DxfSettingsPanel from './demo/settings/DxfSettingsPanel.js';
import LayerManager from "./demo/layerManager/LayerManager.js";
const models = [{
modelId: "dxf_1",
name: "dxf_1",
src: "./demo/projects/dxf_test/dxf_1.dxf",
merge: true,
visible: true,
}];
const config = {
containerId: "myCanvas",
enableAxisGizmo: true,
enableStats: true,
enableToolbar: true,
enableSpinner: true,
enableProgressBar: true,
enableBottomBar: true,
enableLayoutBar: true,
};
const viewer = new DxfViewer(config);
// const fontFiles = ["three/fonts/Microsoft_YaHei_Regular.typeface.json"];
const fontFiles = ["./demo/three/fonts/hztxt.shx", "./demo/three/fonts/simplex.shx"];
await viewer.setFont(fontFiles);
// loadProjectModel
let counter = 0; // to indicate how many models are loading
models.forEach((modelCfg) => {
if (modelCfg.visible === false) {
// visible is true by default
return; // only load visible ones
}
counter++;
const onProgress = (event) => {
let type = "Loading progress";
if (event.type === "parseProgress") {
type = "Parsing progress";
}
const progress = ((event.loaded * 100) / event.total).toFixed(2);
console.log(`[Demo] ${type}: ${progress}%`);
};
try {
viewer
.loadModelAsync(modelCfg, onProgress)
.then(() => {
console.log(`[Demo] Loaded model ${modelCfg.src}`);
if (!viewer.layerManager) {
viewer.layerManager = new LayerManager(viewer);
}
})
.finally(() => {
counter--;
});
} catch (ex) {
console.log(ex);
}
});
// as a demo page, add dxfSettingsPanel to window!
window.dxfSettingsPanel = new DxfSettingsPanel(viewer);
</script>
</body>
</html>

80
public/demo/dxf_2.html Normal file
View File

@ -0,0 +1,80 @@
<html>
<head>
<link rel="icon" href="./demo/favicon.ico" />
<link rel="stylesheet" type="text/css" href="./demo/global.css" />
<link rel="stylesheet" type="text/css" href="./demo/iconfont/iconfont.css" />
<link rel="stylesheet" href="./demo/layerManager/layerManager.css" />
<link rel="stylesheet" href="./demo/settings/SettingsPanel.css">
</head>
<body>
<div id="viewerContainer">
<div id="myCanvas" class="renderer-container"></div>
</div>
<script type="module">
import { DxfViewer } from "./demo/libs/gemini-viewer.esm.min.js";
import DxfSettingsPanel from './demo/settings/DxfSettingsPanel.js';
import LayerManager from "./demo/layerManager/LayerManager.js";
const models = [{
modelId: "dxf_2",
name: "dxf_2",
src: "./demo/projects/dxf_test/dxf_2.dxf",
merge: true,
visible: true,
}];
const config = {
containerId: "myCanvas",
enableAxisGizmo: true,
enableStats: true,
enableToolbar: true,
enableSpinner: true,
enableProgressBar: true,
enableBottomBar: true,
enableLayoutBar: true,
};
const viewer = new DxfViewer(config);
// const fontFiles = ["three/fonts/Microsoft_YaHei_Regular.typeface.json"];
const fontFiles = ["./demo/three/fonts/hztxt.shx", "./demo/three/fonts/simplex.shx"];
await viewer.setFont(fontFiles);
// loadProjectModel
let counter = 0; // to indicate how many models are loading
models.forEach((modelCfg) => {
if (modelCfg.visible === false) {
// visible is true by default
return; // only load visible ones
}
counter++;
const onProgress = (event) => {
let type = "Loading progress";
if (event.type === "parseProgress") {
type = "Parsing progress";
}
const progress = ((event.loaded * 100) / event.total).toFixed(2);
console.log(`[Demo] ${type}: ${progress}%`);
};
try {
viewer
.loadModelAsync(modelCfg, onProgress)
.then(() => {
console.log(`[Demo] Loaded model ${modelCfg.src}`);
if (!viewer.layerManager) {
viewer.layerManager = new LayerManager(viewer);
}
})
.finally(() => {
counter--;
});
} catch (ex) {
console.log(ex);
}
});
// as a demo page, add dxfSettingsPanel to window!
window.dxfSettingsPanel = new DxfSettingsPanel(viewer);
</script>
</body>
</html>

62
public/demo/dxf_3.html Normal file
View File

@ -0,0 +1,62 @@
<html>
<head>
<link rel="icon" href="./demo/favicon.ico" />
<link rel="stylesheet" type="text/css" href="./demo/global.css" />
<link rel="stylesheet" type="text/css" href="./demo/iconfont/iconfont.css" />
<link rel="stylesheet" href="./demo/compare/compareSidePanel.css" />
<link rel="stylesheet" href="./demo/layerManager/layerManager.css" />
<link rel="stylesheet" href="./demo/settings/SettingsPanel.css" />
</head>
<body>
<div id="viewerContainer">
<div id="myCanvas" class="renderer-container"></div>
</div>
<script type="module">
import { DxfViewer } from "./demo/libs/gemini-viewer.esm.min.js";
import DxfCompareSidePanel from "./demo/compare/compareSidePanel.js"
import DxfSettingsPanel from "./demo/settings/DxfSettingsPanel.js";
import LayerManager from "./demo/layerManager/LayerManager.js";
const url1 = "./demo/projects/dxf_test/dxf_3.dxf";
const url2 = "./demo/projects/dxf_test/dxf_3_1.dxf";
const config = {
containerId: "myCanvas",
enableAxisGizmo: true,
enableStats: true,
enableToolbar: true,
enableSpinner: true,
enableProgressBar: true,
enableBottomBar: true,
enableLayoutBar: true,
};
const viewer = new DxfViewer(config);
// const fontFiles = ["three/fonts/Microsoft_YaHei_Regular.typeface.json"];
const fontFiles = ["./demo/three/fonts/hztxt.shx", "./demo/three/fonts/simplex.shx"];
await viewer.setFont(fontFiles);
const onProgress = (event) => {
let type = "Loading progress";
if (event.type === "parseProgress") {
type = "Parsing progress";
}
const progress = ((event.loaded * 100) / event.total).toFixed(2);
console.log(`[Demo] ${type}: ${progress}%`);
};
await viewer.compare(url1, url2, onProgress).then(() => {
console.log(`[Demo] Compared models: ${url1}, ${url2}`);
if (!viewer.layerManager) {
viewer.layerManager = new LayerManager(viewer);
}
if (!viewer.dxfCompareSidePanel) {
viewer.dxfCompareSidePanel = new DxfCompareSidePanel(viewer);
}
});
// as a demo page, add dxfSettingsPanel to window!
window.dxfSettingsPanel = new DxfSettingsPanel(viewer);
</script>
</body>
</html>

115
public/demo/dxf_4.html Normal file
View File

@ -0,0 +1,115 @@
<html>
<head>
<link rel="icon" href="./demo/favicon.ico" />
<link rel="stylesheet" type="text/css" href="./demo/global.css" />
<link rel="stylesheet" type="text/css" href="./demo/iconfont/iconfont.css" />
<link rel="stylesheet" href="./demo/compare/compareSidePanel.css" />
<link rel="stylesheet" href="./demo/layerManager/layerManager.css" />
<link rel="stylesheet" href="./demo/settings/SettingsPanel.css" />
<style>
#myCanvas1 {
width: 40%;
height: 50%;
top: 0;
left: 0;
position: absolute;
border: 1px #dddddd solid;
}
#myCanvas2 {
width: 40%;
top: 50% !important;
height: 50%;
left: 0;
position: absolute;
border: 1px #dddddd solid;
}
#myCanvas3 {
width: 60%;
top: 0;
right: 0;
position: absolute;
border: 1px #dddddd solid;
}
.title {
font-size: 18px;
z-index: 3;
position: absolute;
margin-top: 8px;
color: white;
top: 0%;
left: 18%;
}
.title2 {
top: 50%;
left: 18%;
}
.title3 {
left: 68%;
}
</style>
</head>
<body>
<div id="viewerContainer">
<span class="title">图纸 1</span>
<div id="myCanvas1" class="renderer-container"></div>
<span class="title title2">图纸 2</span>
<div id="myCanvas2" class="renderer-container"></div>
<span class="title title3">对比结果</span>
<!-- myCanvas3 is the one for compare -->
<div id="myCanvas3" class="renderer-container"></div>
</div>
<script type="module">
import { DxfViewer } from "./demo/libs/gemini-viewer.esm.min.js";
import DxfCompareSidePanel from "./demo/compare/compareSidePanel.js"
import DxfSettingsPanel from "./demo/settings/DxfSettingsPanel.js";
import LayerManager from "./demo/layerManager/LayerManager.js";
const url1 = "./demo/projects/dxf_test/dxf_3.dxf";
const url2 = "./demo/projects/dxf_test/dxf_3_1.dxf";
const modelConfig1 = { modelId: "dxf_1", name: "dxf 1", src: url1, ignorePaperSpace: true };
const modelConfig2 = { modelId: "dxf_2", name: "dxf 2", src: url2, ignorePaperSpace: true };
const config = {
containerId: "myCanvas3",
enableAxisGizmo: true,
enableStats: false,
enableToolbar: true,
enableSpinner: true,
enableProgressBar: true,
enableBottomBar: true,
};
const viewer1 = new DxfViewer({ containerId: "myCanvas1"});
const viewer2 = new DxfViewer({ containerId: "myCanvas2"});
const viewer3 = new DxfViewer(config);
const fontFiles = ["./demo/three/fonts/hztxt.shx", "./demo/three/fonts/simplex.shx"];
await viewer1.setFont(fontFiles);
await viewer2.setFont(fontFiles);
await viewer3.setFont(fontFiles);
const onProgress = (event) => {
let type = "Loading progress";
if (event.type === "parseProgress") {
type = "Parsing progress";
}
const progress = ((event.loaded * 100) / event.total).toFixed(2);
console.log(`[Demo] ${type}: ${progress}%`);
};
await viewer1.loadModelAsync(modelConfig1, onProgress);
await viewer2.loadModelAsync(modelConfig2, onProgress);
await viewer3.compare(url1, url2, onProgress).then(() => {
console.log(`[Demo] Compared models: ${url1}, ${url2}`);
if (!viewer3.layerManager) {
viewer3.layerManager = new LayerManager(viewer3);
}
if (!viewer3.dxfCompareSidePanel) {
viewer3.dxfCompareSidePanel = new DxfCompareSidePanel(viewer3);
}
});
// as a demo page, add dxfSettingsPanel to window!
window.dxfSettingsPanel = new DxfSettingsPanel(viewer3);
</script>
</body>
</html>

View File

@ -0,0 +1,115 @@
<html>
<head>
<link rel="icon" href="./demo/favicon.ico" />
<link rel="stylesheet" type="text/css" href="./demo/global.css" />
<link rel="stylesheet" href="./demo/layerManager/layerManager.css">
<link rel="stylesheet" href="./demo/settings/SettingsPanel.css">
<style>
.upload-btn {
margin-top: 2em;
}
.upload-btn button {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.upload-btn label {
color: #353535;
background: gray;
border: 0;
border-radius: 3px;
/*transition: ease 0.2s background-color;*/
font-size: 1rem;
font-weight: 700;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
display: inline-block;
overflow: hidden;
padding: 0.625rem 1.25rem;
}
.upload-btn label:hover {
background: #DDD;
}
.upload-btn svg {
width: 1em;
height: 1em;
vertical-align: middle;
fill: currentColor;
margin-top: -0.25em;
margin-right: 0.25em;
}
</style>
</head>
<body>
<div id="viewerContainer">
<div id="myDxfViewerContainer" class="renderer-container"></div>
</div>
<div style="position: absolute; top: 10px; opacity: 0.6; width: 100%;text-align: center;">
<div class="upload-btn" id="uploadBtn">
<button id="uploadModelFile" type="button">点此上传本地模型文件</button>
<label for="uploadModelFile" title="">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" viewBox="0 0 20 17"><path d="M10 0l-5.2 4.9h3.3v5.1h3.8v-5.1h3.3l-5.2-4.9zm9.3 11.5l-3.2-2.1h-2l3.4 2.6h-3.5c-.1 0-.2.1-.2.1l-.8 2.3h-6l-.8-2.2c-.1-.1-.1-.2-.2-.2h-3.6l3.4-2.6h-2l-3.2 2.1c-.4.3-.7 1-.6 1.5l.6 3.1c.1.5.7.9 1.2.9h16.3c.6 0 1.1-.4 1.3-.9l.6-3.1c.1-.5-.2-1.2-.7-1.5z"></path></svg>
<span>Upload dxf</span>
</label>
<div style="margin-top: 1em;">
<input id="fileUrlInput" style="display: inline-block; width: 20em; height: 2em;">
<button
style="width: 8em; height: 2em; color: #fff; overflow: auto; z-index: 1; opacity: 1; background: #000;"
id="loadDxf">加载DXF
</button>
</div>
</div>
</div>
<script type="module">
import { DxfViewer, LocalDxfUploader } from "./demo/libs/gemini-viewer.esm.min.js";
import DxfSettingsPanel from './demo/settings/DxfSettingsPanel.js';
import LayerManager from './demo/layerManager/LayerManager.js';
const config = {
containerId: "myDxfViewerContainer",
enableAxisGizmo: true,
enableStats: true,
enableToolbar: true,
enableBottomBar: true,
enableSpinner: true,
enableProgressBar: true,
enableLayoutBar: true,
};
const viewer = new DxfViewer(config);
// const fontFiles = ["three/fonts/Microsoft_YaHei_Regular.typeface.json"];
const fontFiles = ["./demo/three/fonts/hztxt.shx", "./demo/three/fonts/simplex.shx"];
await viewer.setFont(fontFiles);
const modelUploader = new LocalDxfUploader(viewer);
modelUploader.onSuccess = () => {
!viewer.layerManager && (viewer.layerManager = new LayerManager(viewer));
}
document.getElementById("uploadModelFile").onclick = function() {
modelUploader.openFileBrowserToUpload();
}
document.getElementById("loadDxf").onclick = function() {
const url = document.getElementById("fileUrlInput").value;
if (url) {
viewer.loadModelAsync({ src: url, merge: true }).then(() => {
console.log(`[Demo] Loaded model ${url}`);
!viewer.layerManager && (viewer.layerManager = new LayerManager(viewer));
})
}
}
// as a demo page, add dxfSettingsPanel to window!
window.dxfSettingsPanel = new DxfSettingsPanel(viewer);
</script>
</body>
</html>

View File

@ -0,0 +1,122 @@
<html>
<head>
<link rel="icon" href="./demo/favicon.ico" />
<link rel="stylesheet" type="text/css" href="./demo/global.css" />
<style>
.upload-btn {
margin-top: 2em;
}
.upload-btn button {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.upload-btn label {
color: #353535;
border: 0;
border-radius: 3px;
transition: ease 0.2s;
transition-property: background;
font-size: 1rem;
font-weight: 700;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
display: inline-block;
overflow: hidden;
padding: 0.625rem 1.25rem;
}
.upload-btn label:hover {
background: #DDD;
}
.upload-btn svg {
width: 1em;
height: 1em;
vertical-align: middle;
fill: currentColor;
margin-top: -0.25em;
margin-right: 0.25em;
}
</style>
</head>
<body>
<div id="viewerContainer">
<div id="myBimViewerContainer" class="renderer-container"></div>
</div>
<div style="position: absolute; top: 10px; opacity: 0.6; width: 100%;text-align: center;">
<div class="upload-btn" id="uploadBtn">
<button id="uploadModelFile" type="button">点此上传本地模型文件</button>
<label for="uploadModelFile" title="支持 gltf, dxf, obj, stl, fbx, ifc, dae等。只支持单模型文件不支持链接文件。也就是几何体、材质都要内嵌在单一模型文件中。">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" viewBox="0 0 20 17"><path d="M10 0l-5.2 4.9h3.3v5.1h3.8v-5.1h3.3l-5.2-4.9zm9.3 11.5l-3.2-2.1h-2l3.4 2.6h-3.5c-.1 0-.2.1-.2.1l-.8 2.3h-6l-.8-2.2c-.1-.1-.1-.2-.2-.2h-3.6l3.4-2.6h-2l-3.2 2.1c-.4.3-.7 1-.6 1.5l.6 3.1c.1.5.7.9 1.2.9h16.3c.6 0 1.1-.4 1.3-.9l.6-3.1c.1-.5-.2-1.2-.7-1.5z"></path></svg>
<span>Upload model</span>
</label>
</div>
</div>
<script type="module">
import { BimViewer, ToolbarMenuId, LocalModelUploader } from "./demo/libs/gemini-viewer.esm.min.js";
const project = {
id: "empty_project",
name: "Empty project",
thumbnail: "./demo/projects/empty_project/thumbnail.png",
camera: {
},
models: [{
"name": "model 01",
"src": "",
"rotation": [0, 0, 0],
"scale": [1, 1, 1],
"merge": false,
"visible": false
}],
};
const bimViewer = new BimViewer(
{
containerId: "myBimViewerContainer",
enableAxisGizmo: true,
enableStats: true,
toolbarMenuConfig: {
[ToolbarMenuId.BimTree]: { visible: false },
},
enableBottomBar: true,
enableNavCube: true,
enableContextMenu: true,
},
project.camera
);
// loadProjectModel
let counter = 0; // to indicate how many models are loading
project.models.forEach((modelCfg) => {
if (modelCfg.visible === false) {
// visible is true by default
return; // only load visible ones
}
counter++;
bimViewer.loadModel(modelCfg, (event) => {
console.log(`[Demo] Loading model ${modelCfg.src}`);
}, (event) => {
console.error(`[Demo] Failed to load ${modelCfg.src}. " + event.message`);
}
).then(() => {
console.log(`[Demo] Loaded model ${modelCfg.src}`);
});
});
const modelUploader = new LocalModelUploader(bimViewer);
document.getElementById("uploadModelFile").onclick = function() {
modelUploader.openFileBrowserToUpload();
}
</script>
</body>
</html>

View File

@ -0,0 +1,80 @@
<html>
<head>
<link rel="icon" href="./demo/favicon.ico" />
<link rel="stylesheet" type="text/css" href="./demo/global.css" />
<style>
.upload-btn {
margin-top: 2em;
}
.upload-btn button {
width: 0.1px;
height: 0.1px;
opacity: 0;
overflow: hidden;
position: absolute;
z-index: -1;
}
.upload-btn label {
color: #353535;
border: 0;
border-radius: 3px;
transition: ease 0.2s background;
font-size: 1rem;
font-weight: 700;
text-overflow: ellipsis;
white-space: nowrap;
cursor: pointer;
display: inline-block;
overflow: hidden;
padding: 0.625rem 1.25rem;
}
.upload-btn label:hover {
background: #DDD;
}
.upload-btn svg {
width: 1em;
height: 1em;
vertical-align: middle;
fill: currentColor;
margin-top: -0.25em;
margin-right: 0.25em;
}
</style>
</head>
<body>
<div id="viewerContainer">
<div id="myVRViewerContainer" class="renderer-container"></div>
</div>
<div style="position: absolute; top: 10px; opacity: 0.6; width: 100%;text-align: center;">
<div class="upload-btn" id="uploadBtn">
<button id="uploadImage" type="button">点此上传本地图片文件</button>
<label for="uploadImage" title="支持 png, jpg 等;请选择 1 张鱼眼图或 6 张图,若为 6 张,图片名须为 right/r, left/l, up/u, down/d, front/f, back/b">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="17" viewBox="0 0 20 17"><path d="M10 0l-5.2 4.9h3.3v5.1h3.8v-5.1h3.3l-5.2-4.9zm9.3 11.5l-3.2-2.1h-2l3.4 2.6h-3.5c-.1 0-.2.1-.2.1l-.8 2.3h-6l-.8-2.2c-.1-.1-.1-.2-.2-.2h-3.6l3.4-2.6h-2l-3.2 2.1c-.4.3-.7 1-.6 1.5l.6 3.1c.1.5.7.9 1.2.9h16.3c.6 0 1.1-.4 1.3-.9l.6-3.1c.1-.5-.2-1.2-.7-1.5z"></path></svg>
<span>Upload image</span>
</label>
</div>
</div>
<script type="module">
import { VRViewer, LocalImageUploader } from "./demio/libs/gemini-viewer.esm.min.js";
const config = {
containerId: "myVRViewerContainer",
enableAxisGizmo: true,
enableBottomBar: true,
}
const vrViewer = new VRViewer(config);
const imageUploader = new LocalImageUploader(vrViewer);
document.getElementById("uploadImage").onclick = function() {
imageUploader.openFileBrowserToUpload();
}
</script>
</body>
</html>

BIN
public/demo/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

100
public/demo/global.css Normal file
View File

@ -0,0 +1,100 @@
@charset "utf-8";
* {
box-sizing: border-box;
}
html {
background-color: #fff;
color: #000;
font-size: 16px;
}
blockquote, body, button, dd, dl, figure, form, h1, h2, h3, h4, h5, h6, input, legend, ol, p, pre, td, textarea, th, ul, xmp {
margin: 0;
padding: 0;
}
body, button, code, input, kbd, pre, samp, select, textarea, tt, xmp {
line-height: 1.5;
}
big, button, h1, h2, h3, h4, h5, h6, input, select, small, textarea {
font-size: 100%;
}
h1, h2, h3, h4, h5, h6 {
font-family: tahoma, arial, "Hiragino Sans GB", "微软雅黑", simsun, sans-serif;
}
b, h1, h2, h3, h4, h5, h6, strong {
font-weight: 400;
}
address, cite, dfn, em, i, optgroup, var {
font-style: normal;
}
table {
border-collapse: collapse;
border-spacing: 0;
text-align: left;
}
caption, th {
text-align: inherit;
}
menu, ol, ul {
list-style: none;
}
img {
border: 0;
}
button, img, input, object, select, textarea {
vertical-align: middle;
}
article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
display: block;
}
audio, canvas, video {
display: inline-block;
}
blockquote:after, blockquote:before, q:after, q:before {
content: "\0020";
}
textarea {
overflow: auto;
resize: vertical;
}
a, button, input, select, textarea {
border: none;
outline: 0 none;
}
button::-moz-focus-inner, input::-moz-focus-inner {
border: 0;
padding: 0;
}
mark {
background-color: transparent;
}
a, del, ins, s, u {
text-decoration: none;
}
sub, sup {
vertical-align: baseline;
}
html {
height: 100%;
overflow-x: hidden;
}
body {
color: #333;
font-family: Arial, "Microsoft Yahei", "Helvetica Neue", Helvetica, sans-serif;
line-height: 1;
}
a {
color: #25a4bb;
text-decoration: none;
}
::-webkit-scrollbar {
height: 1px;
width: 5px;
}
::-webkit-scrollbar-thumb {
background: rgba(0, 0, 0, .1);
border-radius: 10px;
}
::-webkit-scrollbar-track {
background: #ededed;
border-radius: 4px;
}

View File

@ -0,0 +1,539 @@
/* Logo 字体 */
@font-face {
font-family: "iconfont logo";
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834');
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'),
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg');
}
.logo {
font-family: "iconfont logo";
font-size: 160px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
/* tabs */
.nav-tabs {
position: relative;
}
.nav-tabs .nav-more {
position: absolute;
right: 0;
bottom: 0;
height: 42px;
line-height: 42px;
color: #666;
}
#tabs {
border-bottom: 1px solid #eee;
}
#tabs li {
cursor: pointer;
width: 100px;
height: 40px;
line-height: 40px;
text-align: center;
font-size: 16px;
border-bottom: 2px solid transparent;
position: relative;
z-index: 1;
margin-bottom: -1px;
color: #666;
}
#tabs .active {
border-bottom-color: #f00;
color: #222;
}
.tab-container .content {
display: none;
}
/* 页面布局 */
.main {
padding: 30px 100px;
width: 960px;
margin: 0 auto;
}
.main .logo {
color: #333;
text-align: left;
margin-bottom: 30px;
line-height: 1;
height: 110px;
margin-top: -50px;
overflow: hidden;
*zoom: 1;
}
.main .logo a {
font-size: 160px;
color: #333;
}
.helps {
margin-top: 40px;
}
.helps pre {
padding: 20px;
margin: 10px 0;
border: solid 1px #e7e1cd;
background-color: #fffdef;
overflow: auto;
}
.icon_lists {
width: 100% !important;
overflow: hidden;
*zoom: 1;
}
.icon_lists li {
width: 100px;
margin-bottom: 10px;
margin-right: 20px;
text-align: center;
list-style: none !important;
cursor: default;
}
.icon_lists li .code-name {
line-height: 1.2;
}
.icon_lists .icon {
display: block;
height: 100px;
line-height: 100px;
font-size: 42px;
margin: 10px auto;
color: #333;
-webkit-transition: font-size 0.25s linear, width 0.25s linear;
-moz-transition: font-size 0.25s linear, width 0.25s linear;
transition: font-size 0.25s linear, width 0.25s linear;
}
.icon_lists .icon:hover {
font-size: 100px;
}
.icon_lists .svg-icon {
/* 通过设置 font-size 来改变图标大小 */
width: 1em;
/* 图标和文字相邻时,垂直对齐 */
vertical-align: -0.15em;
/* 通过设置 color 来改变 SVG 的颜色/fill */
fill: currentColor;
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示
normalize.css 中也包含这行 */
overflow: hidden;
}
.icon_lists li .name,
.icon_lists li .code-name {
color: #666;
}
/* markdown 样式 */
.markdown {
color: #666;
font-size: 14px;
line-height: 1.8;
}
.highlight {
line-height: 1.5;
}
.markdown img {
vertical-align: middle;
max-width: 100%;
}
.markdown h1 {
color: #404040;
font-weight: 500;
line-height: 40px;
margin-bottom: 24px;
}
.markdown h2,
.markdown h3,
.markdown h4,
.markdown h5,
.markdown h6 {
color: #404040;
margin: 1.6em 0 0.6em 0;
font-weight: 500;
clear: both;
}
.markdown h1 {
font-size: 28px;
}
.markdown h2 {
font-size: 22px;
}
.markdown h3 {
font-size: 16px;
}
.markdown h4 {
font-size: 14px;
}
.markdown h5 {
font-size: 12px;
}
.markdown h6 {
font-size: 12px;
}
.markdown hr {
height: 1px;
border: 0;
background: #e9e9e9;
margin: 16px 0;
clear: both;
}
.markdown p {
margin: 1em 0;
}
.markdown>p,
.markdown>blockquote,
.markdown>.highlight,
.markdown>ol,
.markdown>ul {
width: 80%;
}
.markdown ul>li {
list-style: circle;
}
.markdown>ul li,
.markdown blockquote ul>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown>ul li p,
.markdown>ol li p {
margin: 0.6em 0;
}
.markdown ol>li {
list-style: decimal;
}
.markdown>ol li,
.markdown blockquote ol>li {
margin-left: 20px;
padding-left: 4px;
}
.markdown code {
margin: 0 3px;
padding: 0 5px;
background: #eee;
border-radius: 3px;
}
.markdown strong,
.markdown b {
font-weight: 600;
}
.markdown>table {
border-collapse: collapse;
border-spacing: 0px;
empty-cells: show;
border: 1px solid #e9e9e9;
width: 95%;
margin-bottom: 24px;
}
.markdown>table th {
white-space: nowrap;
color: #333;
font-weight: 600;
}
.markdown>table th,
.markdown>table td {
border: 1px solid #e9e9e9;
padding: 8px 16px;
text-align: left;
}
.markdown>table th {
background: #F7F7F7;
}
.markdown blockquote {
font-size: 90%;
color: #999;
border-left: 4px solid #e9e9e9;
padding-left: 0.8em;
margin: 1em 0;
}
.markdown blockquote p {
margin: 0;
}
.markdown .anchor {
opacity: 0;
transition: opacity 0.3s ease;
margin-left: 8px;
}
.markdown .waiting {
color: #ccc;
}
.markdown h1:hover .anchor,
.markdown h2:hover .anchor,
.markdown h3:hover .anchor,
.markdown h4:hover .anchor,
.markdown h5:hover .anchor,
.markdown h6:hover .anchor {
opacity: 1;
display: inline-block;
}
.markdown>br,
.markdown>p>br {
clear: both;
}
.hljs {
display: block;
background: white;
padding: 0.5em;
color: #333333;
overflow-x: auto;
}
.hljs-comment,
.hljs-meta {
color: #969896;
}
.hljs-string,
.hljs-variable,
.hljs-template-variable,
.hljs-strong,
.hljs-emphasis,
.hljs-quote {
color: #df5000;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-type {
color: #a71d5d;
}
.hljs-literal,
.hljs-symbol,
.hljs-bullet,
.hljs-attribute {
color: #0086b3;
}
.hljs-section,
.hljs-name {
color: #63a35c;
}
.hljs-tag {
color: #333333;
}
.hljs-title,
.hljs-attr,
.hljs-selector-id,
.hljs-selector-class,
.hljs-selector-attr,
.hljs-selector-pseudo {
color: #795da3;
}
.hljs-addition {
color: #55a532;
background-color: #eaffea;
}
.hljs-deletion {
color: #bd2c00;
background-color: #ffecec;
}
.hljs-link {
text-decoration: underline;
}
/* 代码高亮 */
/* PrismJS 1.15.0
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
code[class*="language-"],
pre[class*="language-"] {
color: black;
background: none;
text-shadow: 0 1px white;
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
line-height: 1.5;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
pre[class*="language-"]::-moz-selection,
pre[class*="language-"] ::-moz-selection,
code[class*="language-"]::-moz-selection,
code[class*="language-"] ::-moz-selection {
text-shadow: none;
background: #b3d4fc;
}
pre[class*="language-"]::selection,
pre[class*="language-"] ::selection,
code[class*="language-"]::selection,
code[class*="language-"] ::selection {
text-shadow: none;
background: #b3d4fc;
}
@media print {
code[class*="language-"],
pre[class*="language-"] {
text-shadow: none;
}
}
/* Code blocks */
pre[class*="language-"] {
padding: 1em;
margin: .5em 0;
overflow: auto;
}
:not(pre)>code[class*="language-"],
pre[class*="language-"] {
background: #f5f2f0;
}
/* Inline code */
:not(pre)>code[class*="language-"] {
padding: .1em;
border-radius: .3em;
white-space: normal;
}
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #905;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
background: hsla(0, 0%, 100%, .5);
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

View File

@ -0,0 +1,487 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>iconfont Demo</title>
<link rel="shortcut icon" href="//img.alicdn.com/imgextra/i2/O1CN01ZyAlrn1MwaMhqz36G_!!6000000001499-73-tps-64-64.ico" type="image/x-icon"/>
<link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01EYTRnJ297D6vehehJ_!!6000000008020-55-tps-64-64.svg"/>
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css">
<link rel="stylesheet" href="demo.css">
<link rel="stylesheet" href="iconfont.css">
<script src="iconfont.js"></script>
<!-- jQuery -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script>
<!-- 代码高亮 -->
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script>
<style>
.main .logo {
margin-top: 0;
height: auto;
}
.main .logo a {
display: flex;
align-items: center;
}
.main .logo .sub-title {
margin-left: 0.5em;
font-size: 22px;
color: #fff;
background: linear-gradient(-45deg, #3967FF, #B500FE);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
</style>
</head>
<body>
<div class="main">
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank">
<img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg">
</a></h1>
<div class="nav-tabs">
<ul id="tabs" class="dib-box">
<li class="dib active"><span>Unicode</span></li>
<li class="dib"><span>Font class</span></li>
<li class="dib"><span>Symbol</span></li>
</ul>
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=2522399" target="_blank" class="nav-more">查看项目</a>
</div>
<div class="tab-container">
<div class="content unicode" style="display: block;">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont">&#xe683;</span>
<div class="name">cutting</div>
<div class="code-name">&amp;#xe683;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6a2;</span>
<div class="name">model & plane-overlay</div>
<div class="code-name">&amp;#xe6a2;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6c0;</span>
<div class="name">first view-filled</div>
<div class="code-name">&amp;#xe6c0;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6c1;</span>
<div class="name">measure-area</div>
<div class="code-name">&amp;#xe6c1;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6c4;</span>
<div class="name">measure-filled</div>
<div class="code-name">&amp;#xe6c4;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6c6;</span>
<div class="name">measure-angle</div>
<div class="code-name">&amp;#xe6c6;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6ca;</span>
<div class="name">measure-distance</div>
<div class="code-name">&amp;#xe6ca;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6cb;</span>
<div class="name">weather control-filled</div>
<div class="code-name">&amp;#xe6cb;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe6cc;</span>
<div class="name">configuration</div>
<div class="code-name">&amp;#xe6cc;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe71f;</span>
<div class="name">cloud download-filled</div>
<div class="code-name">&amp;#xe71f;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe721;</span>
<div class="name">cloud upload-filled</div>
<div class="code-name">&amp;#xe721;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe786;</span>
<div class="name">phase-review</div>
<div class="code-name">&amp;#xe786;</div>
</li>
<li class="dib">
<span class="icon iconfont">&#xe791;</span>
<div class="name">data-space planning</div>
<div class="code-name">&amp;#xe791;</div>
</li>
</ul>
<div class="article markdown">
<h2 id="unicode-">Unicode 引用</h2>
<hr>
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p>
<ul>
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li>
<li>默认情况下不支持多色,直接添加多色图标会自动去色。</li>
</ul>
<blockquote>
<p>注意:新版 iconfont 支持两种方式引用多色图标SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p>
</blockquote>
<p>Unicode 使用步骤如下:</p>
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3>
<pre><code class="language-css"
>@font-face {
font-family: 'iconfont';
src: url('iconfont.woff2?t=1620285948639') format('woff2'),
url('iconfont.woff?t=1620285948639') format('woff'),
url('iconfont.ttf?t=1620285948639') format('truetype');
}
</code></pre>
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3>
<pre><code class="language-css"
>.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3>
<pre>
<code class="language-html"
>&lt;span class="iconfont"&gt;&amp;#x33;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content font-class">
<ul class="icon_lists dib-box">
<li class="dib">
<span class="icon iconfont icon-clip-plane"></span>
<div class="name">
cutting
</div>
<div class="code-name">.icon-clip-plane
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-clip-box"></span>
<div class="name">
model & plane-overlay
</div>
<div class="code-name">.icon-clip-box
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-firstview-filled"></span>
<div class="name">
first view-filled
</div>
<div class="code-name">.icon-firstview-filled
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-measure-area"></span>
<div class="name">
measure-area
</div>
<div class="code-name">.icon-measure-area
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-measure-filled"></span>
<div class="name">
measure-filled
</div>
<div class="code-name">.icon-measure-filled
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-measure-angle"></span>
<div class="name">
measure-angle
</div>
<div class="code-name">.icon-measure-angle
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-measure-distance"></span>
<div class="name">
measure-distance
</div>
<div class="code-name">.icon-measure-distance
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-weathercontrol-filled"></span>
<div class="name">
weather control-filled
</div>
<div class="code-name">.icon-weathercontrol-filled
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-configuration"></span>
<div class="name">
configuration
</div>
<div class="code-name">.icon-configuration
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-clouddownload-filled"></span>
<div class="name">
cloud download-filled
</div>
<div class="code-name">.icon-clouddownload-filled
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-cloudupload-filled"></span>
<div class="name">
cloud upload-filled
</div>
<div class="code-name">.icon-cloudupload-filled
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-phase-review"></span>
<div class="name">
phase-review
</div>
<div class="code-name">.icon-phase-review
</div>
</li>
<li class="dib">
<span class="icon iconfont icon-data-spaceplanning"></span>
<div class="name">
data-space planning
</div>
<div class="code-name">.icon-data-spaceplanning
</div>
</li>
</ul>
<div class="article markdown">
<h2 id="font-class-">font-class 引用</h2>
<hr>
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p>
<p>与 Unicode 使用方式相比,具有如下特点:</p>
<ul>
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li>
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3>
<pre><code class="language-html">&lt;link rel="stylesheet" href="./iconfont.css"&gt;
</code></pre>
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;span class="iconfont icon-xxx"&gt;&lt;/span&gt;
</code></pre>
<blockquote>
<p>"
iconfont" 是你项目下的 font-family。可以通过编辑项目查看默认是 "iconfont"。</p>
</blockquote>
</div>
</div>
<div class="content symbol">
<ul class="icon_lists dib-box">
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-clip-plane"></use>
</svg>
<div class="name">cutting</div>
<div class="code-name">#icon-clip-plane</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-clip-box"></use>
</svg>
<div class="name">model & plane-overlay</div>
<div class="code-name">#icon-clip-box</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-firstview-filled"></use>
</svg>
<div class="name">first view-filled</div>
<div class="code-name">#icon-firstview-filled</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-measure-area"></use>
</svg>
<div class="name">measure-area</div>
<div class="code-name">#icon-measure-area</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-measure-filled"></use>
</svg>
<div class="name">measure-filled</div>
<div class="code-name">#icon-measure-filled</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-measure-angle"></use>
</svg>
<div class="name">measure-angle</div>
<div class="code-name">#icon-measure-angle</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-measure-distance"></use>
</svg>
<div class="name">measure-distance</div>
<div class="code-name">#icon-measure-distance</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-weathercontrol-filled"></use>
</svg>
<div class="name">weather control-filled</div>
<div class="code-name">#icon-weathercontrol-filled</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-configuration"></use>
</svg>
<div class="name">configuration</div>
<div class="code-name">#icon-configuration</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-clouddownload-filled"></use>
</svg>
<div class="name">cloud download-filled</div>
<div class="code-name">#icon-clouddownload-filled</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-cloudupload-filled"></use>
</svg>
<div class="name">cloud upload-filled</div>
<div class="code-name">#icon-cloudupload-filled</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-phase-review"></use>
</svg>
<div class="name">phase-review</div>
<div class="code-name">#icon-phase-review</div>
</li>
<li class="dib">
<svg class="icon svg-icon" aria-hidden="true">
<use xlink:href="#icon-data-spaceplanning"></use>
</svg>
<div class="name">data-space planning</div>
<div class="code-name">#icon-data-spaceplanning</div>
</li>
</ul>
<div class="article markdown">
<h2 id="symbol-">Symbol 引用</h2>
<hr>
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a>
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p>
<ul>
<li>支持多色图标了,不再受单色限制。</li>
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li>
<li>兼容性较差,支持 IE9+,及现代浏览器。</li>
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li>
</ul>
<p>使用步骤如下:</p>
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3>
<pre><code class="language-html">&lt;script src="./iconfont.js"&gt;&lt;/script&gt;
</code></pre>
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3>
<pre><code class="language-html">&lt;style&gt;
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
&lt;/style&gt;
</code></pre>
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3>
<pre><code class="language-html">&lt;svg class="icon" aria-hidden="true"&gt;
&lt;use xlink:href="#icon-xxx"&gt;&lt;/use&gt;
&lt;/svg&gt;
</code></pre>
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('.tab-container .content:first').show()
$('#tabs li').click(function (e) {
var tabContent = $('.tab-container .content')
var index = $(this).index()
if ($(this).hasClass('active')) {
return
} else {
$('#tabs li').removeClass('active')
$(this).addClass('active')
tabContent.hide().eq(index).fadeIn()
}
})
})
</script>
</body>
</html>

View File

@ -0,0 +1,67 @@
@font-face {
font-family: "iconfont"; /* Project id 2522399 */
src: url('iconfont.woff2?t=1620285948639') format('woff2'),
url('iconfont.woff?t=1620285948639') format('woff'),
url('iconfont.ttf?t=1620285948639') format('truetype');
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-clip-plane:before {
content: "\e683";
}
.icon-clip-box:before {
content: "\e6a2";
}
.icon-firstview-filled:before {
content: "\e6c0";
}
.icon-measure-area:before {
content: "\e6c1";
}
.icon-measure-filled:before {
content: "\e6c4";
}
.icon-measure-angle:before {
content: "\e6c6";
}
.icon-measure-distance:before {
content: "\e6ca";
}
.icon-weathercontrol-filled:before {
content: "\e6cb";
}
.icon-configuration:before {
content: "\e6cc";
}
.icon-clouddownload-filled:before {
content: "\e71f";
}
.icon-cloudupload-filled:before {
content: "\e721";
}
.icon-phase-review:before {
content: "\e786";
}
.icon-data-spaceplanning:before {
content: "\e791";
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 319 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 445 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 330 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 281 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 397 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 292 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Some files were not shown because too many files have changed in this diff Show More