添加examples页面
This commit is contained in:
@ -69,8 +69,8 @@
|
||||
|
||||
const url1 = "./demo/models/dxf/dxf_3.dxf";
|
||||
const url2 = "./demo/models/dxf/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 modelConfig1 = { modelId: "dxf_3", name: "dxf 1", src: url1, ignorePaperSpace: true };
|
||||
const modelConfig2 = { modelId: "dxf_3_1", name: "dxf 2", src: url2, ignorePaperSpace: true };
|
||||
const config = {
|
||||
containerId: "myCanvas3",
|
||||
enableAxisGizmo: true,
|
||||
|
@ -3,12 +3,16 @@ import { FC } from 'react';
|
||||
import { RecoilRoot } from "recoil";
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import Demo from './pages/demo';
|
||||
import Examples from "./pages/examples";
|
||||
|
||||
const App: FC = () => {
|
||||
return (
|
||||
<RecoilRoot>
|
||||
<Routes>
|
||||
<Route index path="/" element={<Demo />} />
|
||||
<Route path="/examples" element={<Examples />}>
|
||||
<Route path=":id" element={<Examples />} />
|
||||
</Route>
|
||||
</Routes>
|
||||
</RecoilRoot>
|
||||
)
|
||||
|
@ -2,6 +2,7 @@ import NavMenu, {MenusProp} from "./components/NavMenu/NavMenu";
|
||||
import CodeEditor from "./components/CodeEditor/CodeEditor";
|
||||
import {useEffect, useState} from "react";
|
||||
import "./index.css";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
|
||||
function Demo() {
|
||||
|
166
src/pages/examples/index.css
Normal file
166
src/pages/examples/index.css
Normal file
@ -0,0 +1,166 @@
|
||||
.examples {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
background-color: #000000;
|
||||
}
|
||||
|
||||
.examples .menu {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: -500px;
|
||||
z-index: 10;
|
||||
width: 460px;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
transition: all 300ms ease-in-out;
|
||||
}
|
||||
|
||||
.examples .menu.open {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.examples .index-button {
|
||||
position: absolute;
|
||||
font-size: 38px;
|
||||
top: 15px;
|
||||
left: 20px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
z-index: 10;
|
||||
transition: all 300ms ease-in-out;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.examples .index-button.open {
|
||||
left: 485px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.examples .content-container {
|
||||
position: absolute;
|
||||
z-index: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
opacity: 1.0;
|
||||
pointer-events: all;
|
||||
transition: all 300ms ease-in-out;
|
||||
background: lightblue;
|
||||
}
|
||||
|
||||
.examples .content-container.open {
|
||||
opacity: 0.4;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.examples .content-container iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.examples .content-overlay {
|
||||
position: absolute;
|
||||
z-index: 7;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0 auto;
|
||||
overflow: hidden;
|
||||
opacity: 1.0;
|
||||
pointer-events: none;
|
||||
transition: all 300ms ease-in-out;
|
||||
}
|
||||
|
||||
.examples .content-overlay.open {
|
||||
pointer-events: all;
|
||||
}
|
||||
|
||||
.examples .page-title {
|
||||
position: absolute;
|
||||
font-size: 1.6rem;
|
||||
top: 25px;
|
||||
left: 75px;
|
||||
text-align: left;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
z-index: 5;
|
||||
transition: all 300ms ease-in-out;
|
||||
max-width: calc(100% - 450px);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.examples .page-title.open {
|
||||
left: 545px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.examples .menu #index {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #fdfdfd;
|
||||
overflow: auto;
|
||||
border-right: 2px solid #212529;
|
||||
padding: 20px;
|
||||
padding-bottom: 100px;
|
||||
user-select: none;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
#index h1 {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
font-size: 1.8rem;
|
||||
font-weight: normal;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
#index h2 {
|
||||
font-size: 1.4rem;
|
||||
font-weight: normal;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 10px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
#index hr {
|
||||
display: block;
|
||||
unicode-bidi: isolate;
|
||||
margin-block-start: 0.5em;
|
||||
margin-block-end: 0.5em;
|
||||
margin-inline-start: auto;
|
||||
margin-inline-end: auto;
|
||||
overflow: hidden;
|
||||
border-style: inset;
|
||||
border-width: 1px;
|
||||
}
|
||||
|
||||
#index .link {
|
||||
margin-left: 0 !important;
|
||||
padding-left: 0 !important;
|
||||
padding-top: 1px;
|
||||
text-decoration: none;
|
||||
font-weight: normal;
|
||||
background: #fdfdfd;
|
||||
cursor: pointer;
|
||||
line-height: 1.5em;
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
|
||||
element.style {
|
||||
}
|
||||
#index .link:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
129
src/pages/examples/index.tsx
Normal file
129
src/pages/examples/index.tsx
Normal file
@ -0,0 +1,129 @@
|
||||
import "./index.css";
|
||||
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
|
||||
import {useEffect, useRef, useState} from "react";
|
||||
import {Routes, Route, Link, useParams} from 'react-router-dom';
|
||||
|
||||
interface MenuProp {
|
||||
title: string;
|
||||
url: string;
|
||||
}
|
||||
|
||||
interface MenusProp {
|
||||
title: string;
|
||||
subMenus: MenuProp[];
|
||||
}
|
||||
|
||||
function Examples() {
|
||||
const [collapsed, setCollapsed] = useState<boolean>(true);
|
||||
const [title, setTitle] = useState<string>("");
|
||||
const [indexData, setIndexData] = useState<string[]>([]);
|
||||
const [data, setData] = useState<MenusProp[]>([]);
|
||||
const iframeRef = useRef<HTMLIFrameElement>();
|
||||
const { id } = useParams();
|
||||
|
||||
const getCode = (url: string) => {
|
||||
if (!url) return;
|
||||
fetch(url, {mode: 'cors'}).then(data => data.text()).then((data) => {
|
||||
run(data);
|
||||
})
|
||||
}
|
||||
|
||||
const run = (code: string) => {
|
||||
const preview = document.querySelector("#preview") as HTMLElement;
|
||||
preview.innerHTML = "";
|
||||
iframeRef.current = document.createElement("iframe") as HTMLIFrameElement;
|
||||
preview.appendChild(iframeRef.current);
|
||||
if(code) {
|
||||
iframeRef.current.contentWindow?.document.open();
|
||||
iframeRef.current.contentWindow?.document.write(code);
|
||||
iframeRef.current.contentWindow?.document.close();
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
fetch("./config.json").then(data => data.json()).then((data) => {
|
||||
const indexMenus:string[] = [];
|
||||
data.forEach((menu: MenusProp) => {
|
||||
indexMenus.push(menu.title);
|
||||
});
|
||||
setIndexData(indexMenus);
|
||||
setData(data);
|
||||
});
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!id) {
|
||||
return;
|
||||
}
|
||||
const subTitle = id.split("_").join(" ");;
|
||||
data.forEach((menu: MenusProp) => {
|
||||
menu.subMenus.forEach((subMenu: MenuProp) => {
|
||||
if (subMenu.title === subTitle) {
|
||||
getCode(subMenu.url);
|
||||
setTitle(subMenu.title);
|
||||
}
|
||||
});
|
||||
});
|
||||
}, [id, data])
|
||||
|
||||
|
||||
const toggleCollapsed = () => {
|
||||
setCollapsed(!collapsed);
|
||||
}
|
||||
|
||||
const scrollToTarget = (target: string) => {
|
||||
const element = document.getElementById(target.split(" ").join("_"));
|
||||
element?.scrollIntoView();
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="examples" >
|
||||
<button className={`index-button${collapsed? " open" : ""}`} onClick={toggleCollapsed}>
|
||||
{!collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
|
||||
</button>
|
||||
<div className={`page-title${collapsed? " open" : ""}`}>{title}</div>
|
||||
<div className={`content-overlay${collapsed? " open" : ""}`} onClick={toggleCollapsed}></div>
|
||||
<div className={`content-container${collapsed? " open" : ""}`} id="preview"></div>
|
||||
<div className={`menu${collapsed? " open" : ""}`}>
|
||||
<div id="index">
|
||||
<h1>Examples</h1>
|
||||
<div>
|
||||
<h2>Index</h2>
|
||||
<hr/>
|
||||
{
|
||||
indexData.map((title: string, index: number) => {
|
||||
return (
|
||||
<div className="link" key={`${title}-${index}`} onClick={() => scrollToTarget(title)}>
|
||||
{`${index}....${title}`}
|
||||
</div>
|
||||
);
|
||||
})
|
||||
}
|
||||
<hr/>
|
||||
{
|
||||
data.map((menu: MenusProp, index: number) => {
|
||||
return (
|
||||
<div key={`${menu.title}_${index}`}>
|
||||
<h2 id={menu.title.split(" ").join("_")}>{`${index}.${menu.title}`}</h2>
|
||||
<hr/>
|
||||
{
|
||||
menu.subMenus.map((subMenu: MenuProp, subIndex: number) => {
|
||||
return (
|
||||
<div className="link" key={`${subMenu.title}_${subIndex}`}>
|
||||
<Link to={`${subMenu.title.split(" ").join("_")}`}>{subMenu.title}</Link>
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Examples;
|
Reference in New Issue
Block a user