Compare commits
No commits in common. "5ac9cb442a31ab85c395b190e22d8c513a545ba1" and "938d5041e472a6bf1ce7b324622d5555bd8ce424" have entirely different histories.
5ac9cb442a
...
938d5041e4
1962
package-lock.json
generated
1962
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -39,7 +39,6 @@
|
|||||||
"webpack-dev-server": "^4.7.2"
|
"webpack-dev-server": "^4.7.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fluentui/react": "^8.56.0",
|
|
||||||
"@juggle/resize-observer": "^3.3.1",
|
"@juggle/resize-observer": "^3.3.1",
|
||||||
"gl-matrix": "^3.4.3",
|
"gl-matrix": "^3.4.3",
|
||||||
"react": "^17.0.2",
|
"react": "^17.0.2",
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
div.header-bar {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
import { Component, ReactNode } from "react";
|
|
||||||
import { useStatus, IMixinStatusProps } from "@Context/Status";
|
|
||||||
import { Theme, BackgroundLevel, FontLevel } from "@Component/Theme/Theme";
|
|
||||||
|
|
||||||
interface IHeaderBarProps {
|
|
||||||
height: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 头部信息栏
|
|
||||||
*/
|
|
||||||
@useStatus
|
|
||||||
class HeaderBar extends Component<IHeaderBarProps & IMixinStatusProps> {
|
|
||||||
|
|
||||||
private changeListener = () => {
|
|
||||||
this.forceUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentDidMount() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentWillUnmount() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(): ReactNode {
|
|
||||||
return <Theme
|
|
||||||
className="header-bar"
|
|
||||||
backgroundLevel={BackgroundLevel.Level1}
|
|
||||||
fontLevel={FontLevel.Level3}
|
|
||||||
style={{ height: this.props.height }}
|
|
||||||
>
|
|
||||||
Living Together | Web
|
|
||||||
</Theme>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default HeaderBar;
|
|
||||||
export { HeaderBar };
|
|
@ -1,7 +0,0 @@
|
|||||||
span.ZH_CN {
|
|
||||||
font-family: 'Microsoft Yahei', Verdana, Simsun, 'Segoe UI', Tahoma, Arial, sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.EN_US {
|
|
||||||
font-family: 'Segoe UI Web Regular', 'Segoe UI', 'Segoe WP', Tahoma, Arial, sans-serif;
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
import { Component, ReactNode, DetailedHTMLProps, HTMLAttributes } from "react";
|
|
||||||
import { useSetting, IMixinSettingProps, Language } from "@Context/Setting";
|
|
||||||
import "./Localization.scss";
|
|
||||||
|
|
||||||
import EN_US from "../../Localization/EN-US";
|
|
||||||
import ZH_CN from "../../Localization/ZH-CN";
|
|
||||||
|
|
||||||
const LanguageDataBase = {
|
|
||||||
EN_US, ZH_CN
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ILocalizationProps {
|
|
||||||
className?: string;
|
|
||||||
i18nKey: keyof typeof EN_US;
|
|
||||||
options?: Record<string, string>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function I18N(language: Language, key: keyof typeof EN_US, values?: Record<string, string>) {
|
|
||||||
let i18nValue = LanguageDataBase[language][key];
|
|
||||||
if (values) {
|
|
||||||
for (let valueKey in values) {
|
|
||||||
i18nValue = i18nValue.replaceAll(new RegExp(`\\{\\s*${valueKey}\\s*\\}`, "g"), values[valueKey]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return i18nValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 本地化组件
|
|
||||||
*/
|
|
||||||
@useSetting
|
|
||||||
class Localization extends Component<ILocalizationProps & IMixinSettingProps &
|
|
||||||
DetailedHTMLProps<
|
|
||||||
HTMLAttributes<HTMLSpanElement>, HTMLSpanElement
|
|
||||||
>
|
|
||||||
> {
|
|
||||||
|
|
||||||
private handelLanguageChange = () => {
|
|
||||||
this.forceUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentDidMount() {
|
|
||||||
if (this.props.setting) {
|
|
||||||
this.props.setting.on("language", this.handelLanguageChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentWillUnmount() {
|
|
||||||
if (this.props.setting) {
|
|
||||||
this.props.setting.off("language", this.handelLanguageChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(): ReactNode {
|
|
||||||
let language: Language = this.props.setting ? this.props.setting.language : "EN_US";
|
|
||||||
let classNameList: string[] = [];
|
|
||||||
if (this.props.className) classNameList.push(this.props.className);
|
|
||||||
classNameList.push(language);
|
|
||||||
let safeProps = {...this.props};
|
|
||||||
delete safeProps.className;
|
|
||||||
delete safeProps.setting;
|
|
||||||
delete (safeProps as any).i18nKey;
|
|
||||||
delete safeProps.options;
|
|
||||||
return <span {...safeProps} className={classNameList.join(" ")}>
|
|
||||||
{I18N(language, this.props.i18nKey, this.props.options)}
|
|
||||||
</span>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export { Localization, I18N };
|
|
@ -1,80 +0,0 @@
|
|||||||
@import "@fluentui/react/dist/sass/References";
|
|
||||||
|
|
||||||
$lt-font-size-normal: $ms-font-size-14;
|
|
||||||
$lt-font-size-lvl3: $ms-font-size-16;
|
|
||||||
$lt-font-size-lvl2: $ms-font-size-18;
|
|
||||||
$lt-font-size-lvl1: $ms-font-size-24;
|
|
||||||
|
|
||||||
$lt-font-weight-normal: $ms-font-weight-regular;
|
|
||||||
$lt-font-weight-lvl3: $ms-font-weight-semibold;
|
|
||||||
$lt-font-weight-lvl2: $ms-font-weight-semibold;
|
|
||||||
$lt-font-weight-lvl1: $ms-font-weight-bold;
|
|
||||||
|
|
||||||
// 背景颜色
|
|
||||||
$lt-bg-color-lvl1-dark: $ms-color-gray140;
|
|
||||||
$lt-bg-color-lvl2-dark: $ms-color-gray150;
|
|
||||||
$lt-bg-color-lvl3-dark: $ms-color-gray160;
|
|
||||||
$lt-bg-color-lvl4-dark: $ms-color-gray180;
|
|
||||||
$lt-bg-color-lvl5-dark: $ms-color-gray200;
|
|
||||||
|
|
||||||
// 文字颜色
|
|
||||||
$lt-font-color-normal-dark: $ms-color-gray110;
|
|
||||||
$lt-font-color-lvl3-dark: $ms-color-gray100;
|
|
||||||
$lt-font-color-lvl2-dark: $ms-color-gray100;
|
|
||||||
$lt-font-color-lvl1-dark: $ms-color-gray90;
|
|
||||||
|
|
||||||
// 背景颜色
|
|
||||||
$lt-bg-color-lvl1-light: $ms-color-gray10;
|
|
||||||
$lt-bg-color-lvl2-light: $ms-color-gray20;
|
|
||||||
$lt-bg-color-lvl3-light: $ms-color-gray30;
|
|
||||||
$lt-bg-color-lvl4-light: $ms-color-gray50;
|
|
||||||
$lt-bg-color-lvl5-light: $ms-color-gray70;
|
|
||||||
|
|
||||||
// 文字颜色
|
|
||||||
$lt-font-color-normal-light: $ms-color-gray130;
|
|
||||||
$lt-font-color-lvl3-light: $ms-color-gray140;
|
|
||||||
$lt-font-color-lvl2-light: $ms-color-gray140;
|
|
||||||
$lt-font-color-lvl1-light: $ms-color-gray150;
|
|
||||||
|
|
||||||
div.dark, div.light {
|
|
||||||
transition: all 300ms ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.dark.background-lvl1 { background-color: $lt-bg-color-lvl1-dark; }
|
|
||||||
div.dark.background-lvl2 { background-color: $lt-bg-color-lvl2-dark; }
|
|
||||||
div.dark.background-lvl3 { background-color: $lt-bg-color-lvl3-dark; }
|
|
||||||
div.dark.background-lvl4 { background-color: $lt-bg-color-lvl4-dark; }
|
|
||||||
div.dark.background-lvl5 { background-color: $lt-bg-color-lvl5-dark; }
|
|
||||||
|
|
||||||
div.light.background-lvl1 { background-color: $lt-bg-color-lvl1-light; }
|
|
||||||
div.light.background-lvl2 { background-color: $lt-bg-color-lvl2-light; }
|
|
||||||
div.light.background-lvl3 { background-color: $lt-bg-color-lvl3-light; }
|
|
||||||
div.light.background-lvl4 { background-color: $lt-bg-color-lvl4-light; }
|
|
||||||
div.light.background-lvl5 { background-color: $lt-bg-color-lvl5-light; }
|
|
||||||
|
|
||||||
div.font-normal {
|
|
||||||
font-size: $lt-font-size-normal;
|
|
||||||
font-weight: $lt-font-weight-normal;
|
|
||||||
}
|
|
||||||
div.font-lvl3 {
|
|
||||||
font-size: $lt-font-size-lvl3;
|
|
||||||
font-weight: $lt-font-weight-lvl3;
|
|
||||||
}
|
|
||||||
div.font-lvl2 {
|
|
||||||
font-size: $lt-font-size-lvl2;
|
|
||||||
font-weight: $lt-font-weight-lvl2;
|
|
||||||
}
|
|
||||||
div.font-lvl1 {
|
|
||||||
font-size: $lt-font-size-lvl1;
|
|
||||||
font-weight: $lt-font-weight-lvl1;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.dark.font-normal { color: $lt-font-color-normal-dark; }
|
|
||||||
div.dark.font-lvl3 { color: $lt-font-color-lvl3-dark; }
|
|
||||||
div.dark.font-lvl2 { color: $lt-font-color-lvl2-dark; }
|
|
||||||
div.dark.font-lvl1 { color: $lt-font-color-lvl1-dark; }
|
|
||||||
|
|
||||||
div.light.font-normal { color: $lt-font-color-normal-light; }
|
|
||||||
div.light.font-lvl3 { color: $lt-font-color-lvl3-light; }
|
|
||||||
div.light.font-lvl2 { color: $lt-font-color-lvl2-light; }
|
|
||||||
div.light.font-lvl1 { color: $lt-font-color-lvl1-light; }
|
|
@ -1,85 +0,0 @@
|
|||||||
import { useSetting, Themes, IMixinSettingProps } from "@Context/Setting";
|
|
||||||
import { Component, ReactNode, DetailedHTMLProps, HTMLAttributes } from "react";
|
|
||||||
import "./Theme.scss";
|
|
||||||
|
|
||||||
enum FontLevel {
|
|
||||||
normal = "normal",
|
|
||||||
Level3 = "lvl3",
|
|
||||||
Level2 = "lvl2",
|
|
||||||
Level1 = "lvl1"
|
|
||||||
}
|
|
||||||
|
|
||||||
enum BackgroundLevel {
|
|
||||||
Level5 = "lvl5",
|
|
||||||
Level4 = "lvl4",
|
|
||||||
Level3 = "lvl3",
|
|
||||||
Level2 = "lvl2",
|
|
||||||
Level1 = "lvl1"
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IThemeProps {
|
|
||||||
className?: string;
|
|
||||||
fontLevel?: FontLevel;
|
|
||||||
backgroundLevel?: BackgroundLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主题切换
|
|
||||||
*/
|
|
||||||
@useSetting
|
|
||||||
class Theme extends Component<
|
|
||||||
IThemeProps & IMixinSettingProps & DetailedHTMLProps<
|
|
||||||
HTMLAttributes<HTMLDivElement>, HTMLDivElement
|
|
||||||
>
|
|
||||||
> {
|
|
||||||
|
|
||||||
private handelThemeChange = () => {
|
|
||||||
this.forceUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentDidMount() {
|
|
||||||
if (this.props.setting) {
|
|
||||||
this.props.setting.on("themes", this.handelThemeChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public componentWillUnmount() {
|
|
||||||
if (this.props.setting) {
|
|
||||||
this.props.setting.off("themes", this.handelThemeChange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(): ReactNode {
|
|
||||||
|
|
||||||
const setting = this.props.setting;
|
|
||||||
const classNameList: string[] = [];
|
|
||||||
|
|
||||||
if (this.props.className) {
|
|
||||||
classNameList.push(this.props.className);
|
|
||||||
}
|
|
||||||
|
|
||||||
const theme = setting ? setting.themes : Themes.dark;
|
|
||||||
classNameList.push(theme === Themes.light ? "light" : "dark");
|
|
||||||
|
|
||||||
if (this.props.fontLevel) {
|
|
||||||
classNameList.push(`font-${this.props.fontLevel}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.props.backgroundLevel) {
|
|
||||||
classNameList.push(`background-${this.props.backgroundLevel}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const propsObj = {...this.props};
|
|
||||||
delete propsObj.className;
|
|
||||||
delete propsObj.setting;
|
|
||||||
delete propsObj.backgroundLevel;
|
|
||||||
delete propsObj.fontLevel;
|
|
||||||
|
|
||||||
return <div {...propsObj} className={`${classNameList.join(" ")}`}>
|
|
||||||
{ this.props.children }
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Theme;
|
|
||||||
export { Theme, FontLevel, BackgroundLevel };
|
|
@ -1,65 +0,0 @@
|
|||||||
import { createContext, Component, FunctionComponent } from "react";
|
|
||||||
import { Emitter } from "@Model/Emitter";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主题模式
|
|
||||||
*/
|
|
||||||
enum Themes {
|
|
||||||
light = 1,
|
|
||||||
dark = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
type Language = "ZH_CN" | "EN_US";
|
|
||||||
|
|
||||||
class Setting extends Emitter<
|
|
||||||
Setting & {change: keyof Setting}
|
|
||||||
> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主题
|
|
||||||
*/
|
|
||||||
public themes: Themes = Themes.dark;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 语言
|
|
||||||
*/
|
|
||||||
public language: Language = "EN_US";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置参数
|
|
||||||
*/
|
|
||||||
public setProps<P extends keyof Setting>(key: P, value: Setting[P]) {
|
|
||||||
this[key] = value as any;
|
|
||||||
this.emit("change", key);
|
|
||||||
this.emit(key as any, value as any);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IMixinSettingProps {
|
|
||||||
setting?: Setting;
|
|
||||||
}
|
|
||||||
|
|
||||||
const SettingContext = createContext<Setting>(new Setting());
|
|
||||||
|
|
||||||
SettingContext.displayName = "Setting";
|
|
||||||
const SettingProvider = SettingContext.Provider;
|
|
||||||
const SettingConsumer = SettingContext.Consumer;
|
|
||||||
|
|
||||||
type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修饰器
|
|
||||||
*/
|
|
||||||
function useSetting<R extends RenderComponent>(components: R): R {
|
|
||||||
return ((props: any) => {
|
|
||||||
const C = components;
|
|
||||||
return <SettingConsumer>
|
|
||||||
{(setting: Setting) => <C {...props} setting={setting}></C>}
|
|
||||||
</SettingConsumer>
|
|
||||||
}) as any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
Themes, Setting, SettingContext, useSetting, Language,
|
|
||||||
IMixinSettingProps, SettingProvider, SettingConsumer
|
|
||||||
};
|
|
@ -1,53 +0,0 @@
|
|||||||
import { createContext, Component, FunctionComponent } from "react";
|
|
||||||
import { Emitter } from "@Model/Emitter";
|
|
||||||
import { Model } from "@Model/Model";
|
|
||||||
import { Archive } from "@Model/Archive";
|
|
||||||
import { AbstractRenderer } from "@Model/Renderer";
|
|
||||||
|
|
||||||
class Status extends Emitter<{}> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 渲染器
|
|
||||||
*/
|
|
||||||
public renderer: AbstractRenderer = undefined as any;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件状态
|
|
||||||
*/
|
|
||||||
public archive: Archive = new Archive();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模型状态
|
|
||||||
*/
|
|
||||||
public model: Model = new Model();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IMixinStatusProps {
|
|
||||||
status?: Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
const StatusContext = createContext<Status>(new Status());
|
|
||||||
|
|
||||||
StatusContext.displayName = "Status";
|
|
||||||
const StatusProvider = StatusContext.Provider;
|
|
||||||
const StatusConsumer = StatusContext.Consumer;
|
|
||||||
|
|
||||||
type RenderComponent = (new (...p: any) => Component<any, any, any>) | FunctionComponent<any>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修饰器
|
|
||||||
*/
|
|
||||||
function useStatus<R extends RenderComponent>(components: R): R {
|
|
||||||
return ((props: any) => {
|
|
||||||
const C = components;
|
|
||||||
return <StatusConsumer>
|
|
||||||
{(status: Status) => <C {...props} status={status}></C>}
|
|
||||||
</StatusConsumer>
|
|
||||||
}) as any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export {
|
|
||||||
Status, StatusContext, useStatus,
|
|
||||||
IMixinStatusProps, StatusProvider, StatusConsumer
|
|
||||||
};
|
|
@ -5,9 +5,7 @@ import { GLContext } from "./GLContext";
|
|||||||
import { Camera } from "./Camera";
|
import { Camera } from "./Camera";
|
||||||
import { Clock } from "@GLRender/Clock";
|
import { Clock } from "@GLRender/Clock";
|
||||||
|
|
||||||
interface IRendererOwnParams {
|
interface IRendererOwnParams {}
|
||||||
canvas: HTMLCanvasElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染器参数
|
* 渲染器参数
|
||||||
@ -40,7 +38,7 @@ abstract class BasicRenderer<
|
|||||||
*/
|
*/
|
||||||
protected clock: Clock;
|
protected clock: Clock;
|
||||||
|
|
||||||
public constructor(param: Partial<M & IRendererParams> = {}) {
|
public constructor(canvas: HTMLCanvasElement, param: Partial<M & IRendererParams> = {}) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
// 初始化参数
|
// 初始化参数
|
||||||
@ -52,7 +50,7 @@ abstract class BasicRenderer<
|
|||||||
} as M & IRendererParams;
|
} as M & IRendererParams;
|
||||||
|
|
||||||
// 实例化画布对象
|
// 实例化画布对象
|
||||||
this.canvas = new GLCanvas(param.canvas, this.param);
|
this.canvas = new GLCanvas(canvas, this.param);
|
||||||
|
|
||||||
// 实例化摄像机
|
// 实例化摄像机
|
||||||
this.camera = new Camera(this.canvas);
|
this.camera = new Camera(this.canvas);
|
||||||
@ -156,7 +154,7 @@ abstract class BasicRenderer<
|
|||||||
/**
|
/**
|
||||||
* 初始化
|
* 初始化
|
||||||
*/
|
*/
|
||||||
abstract onLoad(): this;
|
abstract onLoad(): void;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 渲染器执行
|
* 渲染器执行
|
||||||
|
@ -34,7 +34,7 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
|
|||||||
*/
|
*/
|
||||||
private objectPool = new Map<ObjectID, DisplayObject>();
|
private objectPool = new Map<ObjectID, DisplayObject>();
|
||||||
|
|
||||||
public onLoad(): this {
|
public onLoad(): void {
|
||||||
|
|
||||||
// 自动调节分辨率
|
// 自动调节分辨率
|
||||||
this.autoResize();
|
this.autoResize();
|
||||||
@ -69,8 +69,6 @@ class ClassicRenderer extends BasicRenderer<{}, IClassicRendererParams> {
|
|||||||
// setInterval(() => {
|
// setInterval(() => {
|
||||||
// this.basicGroup.upLoadData(new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2));
|
// this.basicGroup.upLoadData(new Array(100 * 3).fill(0).map(() => (Math.random() - .5) * 2));
|
||||||
// }, 500);
|
// }, 500);
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loop(t: number): void {
|
loop(t: number): void {
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
const EN_US = {
|
|
||||||
"EN_US": "English (US)",
|
|
||||||
"ZH_CN": "Chinese (Simplified)"
|
|
||||||
}
|
|
||||||
export default EN_US;
|
|
@ -1,5 +0,0 @@
|
|||||||
const ZH_CN = {
|
|
||||||
"EN_US": "英语 (美国)",
|
|
||||||
"ZH_CN": "中文 (简体)"
|
|
||||||
}
|
|
||||||
export default ZH_CN;
|
|
0
source/Localization/en-US.json
Normal file
0
source/Localization/en-US.json
Normal file
0
source/Localization/zh-CN.json
Normal file
0
source/Localization/zh-CN.json
Normal file
@ -1,42 +0,0 @@
|
|||||||
import { Emitter, EventType, EventMixin } from "./Emitter";
|
|
||||||
|
|
||||||
interface IArchiveEvent {
|
|
||||||
save: Archive;
|
|
||||||
load: Archive;
|
|
||||||
}
|
|
||||||
|
|
||||||
class Archive<
|
|
||||||
M extends any = any,
|
|
||||||
E extends Record<EventType, any> = {}
|
|
||||||
> extends Emitter<E> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否为新文件
|
|
||||||
*/
|
|
||||||
public isNewFile: boolean = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件名
|
|
||||||
*/
|
|
||||||
public fileName?: string;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件数据
|
|
||||||
*/
|
|
||||||
public fileData?: M;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存文件
|
|
||||||
* 模型转换为文件
|
|
||||||
*/
|
|
||||||
public save() {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 加载文件为模型
|
|
||||||
* return Model
|
|
||||||
*/
|
|
||||||
public load() {};
|
|
||||||
}
|
|
||||||
|
|
||||||
export { Archive };
|
|
||||||
export default Archive;
|
|
@ -21,8 +21,10 @@ class Laboratory extends Component {
|
|||||||
throw new Error("Laboratory: 重复引用 canvas 节点");
|
throw new Error("Laboratory: 重复引用 canvas 节点");
|
||||||
}
|
}
|
||||||
|
|
||||||
const renderer = new ClassicRenderer({ className: "canvas" }).onLoad();
|
const canvas = document.createElement("canvas");
|
||||||
|
const renderer = new ClassicRenderer(canvas, { className: "canvas" });
|
||||||
this.canvasContRef.current.appendChild(renderer.canvas.dom);
|
this.canvasContRef.current.appendChild(renderer.canvas.dom);
|
||||||
|
renderer.onLoad();
|
||||||
|
|
||||||
let model = new Model().bindRenderer(renderer);
|
let model = new Model().bindRenderer(renderer);
|
||||||
let group = model.addGroup();
|
let group = model.addGroup();
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
div.app-root {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
@ -1,70 +1,13 @@
|
|||||||
import { Component, ReactNode } from "react";
|
import { Component, ReactNode, createRef } from "react";
|
||||||
import { SettingProvider, Setting } from "@Context/Setting";
|
|
||||||
import { HeaderBar } from "@Component/HeaderBar/HeaderBar";
|
|
||||||
import { Theme, FontLevel, BackgroundLevel } from "@Component/Theme/Theme";
|
|
||||||
import { Localization } from "@Component/Localization/Localization";
|
|
||||||
import { Entry } from "../Entry/Entry";
|
import { Entry } from "../Entry/Entry";
|
||||||
import { StatusProvider, Status } from "@Context/Status";
|
|
||||||
import { ClassicRenderer } from "@GLRender/ClassicRenderer";
|
|
||||||
import "./SimulatorWeb.scss";
|
import "./SimulatorWeb.scss";
|
||||||
|
|
||||||
class SimulatorWeb extends Component {
|
class SimulatorWeb extends Component {
|
||||||
|
|
||||||
/**
|
private canvasContRef = createRef<HTMLDivElement>();
|
||||||
* 全局设置
|
|
||||||
*/
|
|
||||||
private setting: Setting;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 全局状态
|
|
||||||
*/
|
|
||||||
private status: Status;
|
|
||||||
|
|
||||||
public constructor(props: any) {
|
|
||||||
super(props);
|
|
||||||
|
|
||||||
// TODO: 这里要读取设置
|
|
||||||
this.setting = new Setting();
|
|
||||||
(window as any).setting = (this.setting as any);
|
|
||||||
|
|
||||||
// TODO: 这里要读取存档
|
|
||||||
this.status = new Status();
|
|
||||||
this.status.renderer = new ClassicRenderer({ className: "canvas" }).onLoad();
|
|
||||||
this.status.model.bindRenderer(this.status.renderer);
|
|
||||||
|
|
||||||
// 测试代码
|
|
||||||
if (true) {
|
|
||||||
let group = this.status.model.addGroup();
|
|
||||||
let range = this.status.model.addRange();
|
|
||||||
range.color = [.1, .5, .9];
|
|
||||||
group.new(100);
|
|
||||||
group.color = [.8, .1, .6];
|
|
||||||
group.individuals.forEach((individual) => {
|
|
||||||
individual.position[0] = (Math.random() - .5) * 2;
|
|
||||||
individual.position[1] = (Math.random() - .5) * 2;
|
|
||||||
individual.position[2] = (Math.random() - .5) * 2;
|
|
||||||
})
|
|
||||||
this.status.model.update(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
(window as any).s = this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(): ReactNode {
|
public render(): ReactNode {
|
||||||
return <SettingProvider value={this.setting}>
|
return <div>Web</div>
|
||||||
<StatusProvider value={this.status}>
|
|
||||||
{this.renderContent()}
|
|
||||||
</StatusProvider>
|
|
||||||
</SettingProvider>
|
|
||||||
}
|
|
||||||
|
|
||||||
private renderContent(): ReactNode {
|
|
||||||
return <Theme
|
|
||||||
className="app-root"
|
|
||||||
backgroundLevel={BackgroundLevel.Level5}
|
|
||||||
>
|
|
||||||
<HeaderBar height={45}/>
|
|
||||||
</Theme>
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compileOnSave": true,
|
"compileOnSave": true,
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"experimentalDecorators": true,
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"alwaysStrict": true,
|
"alwaysStrict": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
@ -25,12 +23,6 @@
|
|||||||
],
|
],
|
||||||
"@GLRender/*": [
|
"@GLRender/*": [
|
||||||
"./source/GLRender/*"
|
"./source/GLRender/*"
|
||||||
],
|
|
||||||
"@Context/*": [
|
|
||||||
"./source/Context/*"
|
|
||||||
],
|
|
||||||
"@Component/*": [
|
|
||||||
"./source/Component/*"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user