添加examples页面
This commit is contained in:
@ -69,8 +69,8 @@
|
|||||||
|
|
||||||
const url1 = "./demo/models/dxf/dxf_3.dxf";
|
const url1 = "./demo/models/dxf/dxf_3.dxf";
|
||||||
const url2 = "./demo/models/dxf/dxf_3_1.dxf";
|
const url2 = "./demo/models/dxf/dxf_3_1.dxf";
|
||||||
const modelConfig1 = { modelId: "dxf_1", name: "dxf 1", src: url1, ignorePaperSpace: true };
|
const modelConfig1 = { modelId: "dxf_3", name: "dxf 1", src: url1, ignorePaperSpace: true };
|
||||||
const modelConfig2 = { modelId: "dxf_2", name: "dxf 2", src: url2, ignorePaperSpace: true };
|
const modelConfig2 = { modelId: "dxf_3_1", name: "dxf 2", src: url2, ignorePaperSpace: true };
|
||||||
const config = {
|
const config = {
|
||||||
containerId: "myCanvas3",
|
containerId: "myCanvas3",
|
||||||
enableAxisGizmo: true,
|
enableAxisGizmo: true,
|
||||||
|
@ -3,12 +3,16 @@ import { FC } from 'react';
|
|||||||
import { RecoilRoot } from "recoil";
|
import { RecoilRoot } from "recoil";
|
||||||
import { Routes, Route } from 'react-router-dom';
|
import { Routes, Route } from 'react-router-dom';
|
||||||
import Demo from './pages/demo';
|
import Demo from './pages/demo';
|
||||||
|
import Examples from "./pages/examples";
|
||||||
|
|
||||||
const App: FC = () => {
|
const App: FC = () => {
|
||||||
return (
|
return (
|
||||||
<RecoilRoot>
|
<RecoilRoot>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route index path="/" element={<Demo />} />
|
<Route index path="/" element={<Demo />} />
|
||||||
|
<Route path="/examples" element={<Examples />}>
|
||||||
|
<Route path=":id" element={<Examples />} />
|
||||||
|
</Route>
|
||||||
</Routes>
|
</Routes>
|
||||||
</RecoilRoot>
|
</RecoilRoot>
|
||||||
)
|
)
|
||||||
|
@ -2,6 +2,7 @@ import NavMenu, {MenusProp} from "./components/NavMenu/NavMenu";
|
|||||||
import CodeEditor from "./components/CodeEditor/CodeEditor";
|
import CodeEditor from "./components/CodeEditor/CodeEditor";
|
||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
|
|
||||||
function Demo() {
|
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