;
22 | }
23 |
24 | export { compose };
25 |
--------------------------------------------------------------------------------
/packages/command-manager/src/create.ts:
--------------------------------------------------------------------------------
1 | import { IConstructorOf } from '@turbox3d/shared';
2 | import { Command } from './Command';
3 |
4 | // 仅作为类型标示无参数的 Command 生命周期函数
5 | class INoParamCommand {
6 | apply() {
7 | //
8 | }
9 |
10 | active() {
11 | //
12 | }
13 | }
14 |
15 | // 仅作为类型标示有参数的 Command 生命周期函数
16 | class IParamCommand {
17 | apply(param: P) {
18 | //
19 | }
20 |
21 | active(param: P) {
22 | //
23 | }
24 | }
25 |
26 | type LifeCircleClass
= P extends {} ? IParamCommand
: INoParamCommand;
27 |
28 | export type CommandType = Omit;
29 |
30 | // type E = keyof Command;
31 |
32 | // type P = Pick;
33 |
34 | /**
35 | * 构建一个 Command 基类
36 | *
37 | * 范型类型为激活时的函数参数
38 | */
39 | function create() {
40 | return Command as any as IConstructorOf & CommandType>;
41 | }
42 |
43 | export { create };
44 |
--------------------------------------------------------------------------------
/packages/command-manager/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Command } from './Command';
2 | import { CommandManager } from './CommandManager';
3 | import { isCommandManager } from './util';
4 | import { SceneTool } from './type';
5 |
6 | export {
7 | Command,
8 | CommandManager,
9 | isCommandManager,
10 | SceneTool,
11 | };
12 |
--------------------------------------------------------------------------------
/packages/command-manager/src/install.ts:
--------------------------------------------------------------------------------
1 | import { CommandManager } from './CommandManager';
2 | import { CommandType } from './create';
3 | import { ComposedCommand, IDeclaredMap } from './type';
4 |
5 | function install = IDeclaredMap>(declaredMap: M) {
6 | return class extends CommandManager {
7 | constructor() {
8 | super();
9 | Object.keys(declaredMap).forEach(key => {
10 | const command = new declaredMap[key](this);
11 | this[key] = command;
12 | });
13 | this.installed();
14 | }
15 | } as any as ComposedCommand;
16 | }
17 |
18 | export { install };
19 |
--------------------------------------------------------------------------------
/packages/command-manager/src/manager.ts:
--------------------------------------------------------------------------------
1 | import { CommandManager } from './CommandManager';
2 | import { CommandType } from './create';
3 | import { ComposedCommand, IDeclaredMap } from './type';
4 |
5 | /**
6 | * 构建一个 CommandManager 基类
7 | */
8 | function manager = IDeclaredMap>(declaredMap: M) {
9 | return class extends CommandManager {
10 | constructor() {
11 | super();
12 |
13 | Object.keys(declaredMap).forEach((key) => {
14 | const command = new declaredMap[key](this);
15 | this[key] = command;
16 | });
17 | }
18 | } as any as ComposedCommand;
19 | }
20 |
21 | export { manager };
22 |
--------------------------------------------------------------------------------
/packages/command-manager/src/type.ts:
--------------------------------------------------------------------------------
1 | import { IConstructorOf, Vec2, Vec3 } from '@turbox3d/shared';
2 | import { InteractiveConfig, ViewEntity, CoordinateType } from '@turbox3d/event-manager';
3 |
4 | export interface IDeclaredMap {
5 | [key: string]: IConstructorOf;
6 | }
7 |
8 | export type IInstanceMap> = {
9 | [K in keyof M]: InstanceType;
10 | };
11 |
12 | export type ComposedCommand> = IConstructorOf>;
13 |
14 | export interface SceneTool {
15 | updateInteractiveObject: (view: any, config?: InteractiveConfig) => void;
16 | updateCursor: (cursor?: string) => void;
17 | hitTarget: (point: { x: number; y: number }) => Partial | undefined;
18 | coordinateTransform: (point: Vec2 | Vec3, type: CoordinateType, z?: number) => Vec2 | Vec3;
19 | getCamera: () => any;
20 | getRaycaster: () => any;
21 | getScene: () => any;
22 | getRootView: () => any;
23 | getScreenShot: (
24 | sx?: number,
25 | sy?: number,
26 | w?: number,
27 | h?: number,
28 | fileType?: string,
29 | quality?: number,
30 | isBase64?: boolean
31 | ) => Promise;
32 | getApp: () => any;
33 | addTicker: (ticker: (deltaTime: number) => void) => void;
34 | removeTicker: (ticker: (deltaTime: number) => void) => void;
35 | }
36 |
--------------------------------------------------------------------------------
/packages/command-manager/src/util.ts:
--------------------------------------------------------------------------------
1 | import { CommandManager } from './CommandManager';
2 |
3 | export function isCommandManager(mgr: any): mgr is CommandManager {
4 | return mgr instanceof CommandManager;
5 | }
6 |
--------------------------------------------------------------------------------
/packages/command-manager/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/command-manager/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/design-engine/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/design-engine/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/design-engine/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/design-engine/src/assembly-entity-object/README.md:
--------------------------------------------------------------------------------
1 | # 组合实体模型
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/assembly-entity-object/index.ts:
--------------------------------------------------------------------------------
1 | import EntityObject from '../entity-object/index';
2 |
3 | export default class AssemblyEntityObject extends EntityObject {
4 | }
5 |
--------------------------------------------------------------------------------
/packages/design-engine/src/collision-engine/README.md:
--------------------------------------------------------------------------------
1 | # 碰撞引擎
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/collision-engine/index.ts:
--------------------------------------------------------------------------------
1 | export default class CollisionEngine {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/packages/design-engine/src/document-system/README.md:
--------------------------------------------------------------------------------
1 | # 文档系统
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/entity-object/README.md:
--------------------------------------------------------------------------------
1 | # 通用实体模型
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/env-system/README.md:
--------------------------------------------------------------------------------
1 | # 环境系统
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/env-system/index.ts:
--------------------------------------------------------------------------------
1 | import { Domain, reactor, mutation } from '@turbox3d/reactivity';
2 |
3 | /** 应用环境变量 */
4 | enum EAppEnv {
5 | /** 定制商品素材主插件 */
6 | CUSTOMIZE_PRODUCTS = 'customize-products',
7 | /** 定制铝合金门窗自由绘制插件 */
8 | CUSTOMIZE_DOOR_WINDOW = 'customize-door-window',
9 | }
10 |
11 | class AppEnvironmentManager extends Domain {
12 | /** 当前应用环境变量 */
13 | @reactor() appEnv = '';
14 |
15 | /** 切换应用环境 */
16 | @mutation('切换应用环境', true)
17 | switchAppEnv(appEnvId: string) {
18 | this.appEnv = appEnvId;
19 | }
20 | }
21 |
22 | /** 应用环境管理器 */
23 | const EnvSystem = {
24 | EAppEnv,
25 | AppEnvMgr: new AppEnvironmentManager(),
26 | };
27 |
28 | export default EnvSystem;
29 |
--------------------------------------------------------------------------------
/packages/design-engine/src/free-draw-command/README.md:
--------------------------------------------------------------------------------
1 | # 自由绘制指令
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/free-draw-command/index.ts:
--------------------------------------------------------------------------------
1 | export default class FreeDrawCommand {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/packages/design-engine/src/hint-command/README.md:
--------------------------------------------------------------------------------
1 | # 实体提示指令
2 |
3 | 实体的 hover 效果
4 |
--------------------------------------------------------------------------------
/packages/design-engine/src/index.ts:
--------------------------------------------------------------------------------
1 | const ENV = process.env.NODE_ENV;
2 | if (
3 | ENV !== 'production' &&
4 | ENV !== 'test' &&
5 | typeof console !== 'undefined' &&
6 | console.warn && // eslint-disable-line no-console
7 | typeof window !== 'undefined'
8 | ) {
9 | // eslint-disable-next-line no-console
10 | console.warn(
11 | 'You are using a whole package of design engine, ' +
12 | 'please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size.',
13 | );
14 | }
15 |
16 | export { default as AssemblyEntityObject } from './assembly-entity-object/index';
17 | export { default as CollisionEngine } from './collision-engine/index';
18 | export { default as DocumentSystem } from './document-system/index';
19 | export { default as EntityObject } from './entity-object/index';
20 | export { default as EnvSystem } from './env-system/index';
21 | export { default as FreeDrawCommand } from './free-draw-command/index';
22 | export { default as HintCommand } from './hint-command/index';
23 | export { default as InferenceEngine } from './inference-engine/index';
24 | export { default as LoadSystem } from './load-system/index';
25 | export { default as MaterialBrushCommand } from './material-brush-command/index';
26 | export { default as MaterialDragSystem } from './material-drag-system/index';
27 | export { default as MeasureCommand } from './measure-command/index';
28 | export { default as MountSystem } from './mount-system/index';
29 | export { default as PlacementEngine } from './placement-engine/index';
30 | export { default as RectSelectionCommand } from './rect-selection-command/index';
31 | export { default as SelectionCommand } from './selection-command/index';
32 | export { default as SpaceEngine } from './space-engine/index';
33 | export { default as UnitSystem } from './unit-system/index';
34 |
--------------------------------------------------------------------------------
/packages/design-engine/src/inference-engine/README.md:
--------------------------------------------------------------------------------
1 | # 吸附引擎
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/load-system/README.md:
--------------------------------------------------------------------------------
1 | # 资源加载系统
2 |
3 | 贴图、二进制文件、JSON 文件等
4 |
--------------------------------------------------------------------------------
/packages/design-engine/src/load-system/index.ts:
--------------------------------------------------------------------------------
1 | import { loadJSON } from '@turbox3d/shared';
2 |
3 | const LoadSystem = {
4 | loadJSON,
5 | };
6 |
7 | export default LoadSystem;
8 |
--------------------------------------------------------------------------------
/packages/design-engine/src/material-brush-command/README.md:
--------------------------------------------------------------------------------
1 | # 材质刷指令
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/material-brush-command/index.ts:
--------------------------------------------------------------------------------
1 | export default class MaterialBrushCommand {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/packages/design-engine/src/material-drag-system/README.md:
--------------------------------------------------------------------------------
1 | # 素材拖拽系统(for web 面板)
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/measure-command/README.md:
--------------------------------------------------------------------------------
1 | # 测量指令
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/measure-command/index.ts:
--------------------------------------------------------------------------------
1 | export default class MeasureCommand {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/packages/design-engine/src/mount-system/README.md:
--------------------------------------------------------------------------------
1 | # 挂载容器系统
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/mount-system/ViewMounter.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { Reactive } from '@turbox3d/reactivity-react';
3 | import EnvSystem from '../env-system/index';
4 |
5 | interface IProps extends React.PropsWithChildren {
6 | /** 挂载点 */
7 | mountPointId?: string;
8 | /** 容器节点样式 */
9 | className?: string;
10 | /** 只在当前支持的环境下渲染,离开环境自动卸载 */
11 | environments?: string[];
12 | /** style */
13 | style?: React.CSSProperties;
14 | /** 切换环境时是否需要卸载 dom */
15 | unmountDom?: boolean;
16 | }
17 |
18 | @Reactive
19 | export class EnvViewMounter extends React.Component {
20 | static defaultProps = {
21 | className: '',
22 | mountPointId: '',
23 | environments: [],
24 | style: {},
25 | unmountDom: true,
26 | };
27 |
28 | render() {
29 | const { environments, className, mountPointId, style, unmountDom } = this.props;
30 | const matched = environments!.includes(EnvSystem.AppEnvMgr.appEnv);
31 | let styles = style;
32 | if (!matched) {
33 | if (unmountDom) {
34 | return null;
35 | }
36 | styles = {
37 | ...style,
38 | display: 'none',
39 | };
40 | }
41 | return (
42 |
47 | {this.props.children}
48 |
49 | );
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/packages/design-engine/src/mount-system/index.ts:
--------------------------------------------------------------------------------
1 | import { EnvViewMounter } from './ViewMounter';
2 | import { renderPluginView } from './renderPluginView';
3 |
4 | const MountSystem = {
5 | EnvViewMounter,
6 | renderPluginView,
7 | };
8 |
9 | export default MountSystem;
10 |
--------------------------------------------------------------------------------
/packages/design-engine/src/mount-system/renderPluginView.tsx:
--------------------------------------------------------------------------------
1 | import * as ReactDOM from 'react-dom/client';
2 | import * as ReactDOMLegacy from 'react-dom';
3 | import * as React from 'react';
4 |
5 | /** 渲染插件应用视图 */
6 | export function renderPluginView(Target: React.ComponentType, pluginId: string) {
7 | const el = document.getElementById(`turbox-plugin-${pluginId}`);
8 | let containerNode: HTMLElement;
9 | if (el) {
10 | containerNode = el;
11 | } else {
12 | containerNode = document.createElement('div');
13 | containerNode.id = `turbox-plugin-${pluginId}`;
14 | containerNode.className = `turbox-plugin-${pluginId}-class`;
15 | document.body.appendChild(containerNode);
16 | }
17 | if (React.version.startsWith('18')) {
18 | const root = ReactDOM.createRoot(containerNode);
19 | root.render(React.createElement(Target));
20 | } else {
21 | ReactDOMLegacy.render(React.createElement(Target), containerNode);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/packages/design-engine/src/placement-engine/README.md:
--------------------------------------------------------------------------------
1 | # 摆放引擎
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/placement-engine/index.ts:
--------------------------------------------------------------------------------
1 | class PlacementEngine {
2 |
3 | }
4 |
5 | export default PlacementEngine;
6 |
--------------------------------------------------------------------------------
/packages/design-engine/src/rect-selection-command/README.md:
--------------------------------------------------------------------------------
1 | # 框选指令
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/rect-selection-command/index.ts:
--------------------------------------------------------------------------------
1 | export default class RectSelectionCommand {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/packages/design-engine/src/selection-command/README.md:
--------------------------------------------------------------------------------
1 | # 实体选择指令
2 |
3 | 包括整体选择、部件选择、多级选择、多选
4 |
--------------------------------------------------------------------------------
/packages/design-engine/src/selection-command/domain.ts:
--------------------------------------------------------------------------------
1 | import { Domain, mutation, reactor } from '@turbox3d/reactivity';
2 | import { batchRemove } from '@turbox3d/shared';
3 | import EntityObject from '../entity-object';
4 | import { ESelectMode } from './command';
5 |
6 | export class Selection extends Domain {
7 | @reactor() selectedEntities: EntityObject[] = [];
8 | /** 选择层级深度,多选时取最大值 */
9 | @reactor() layerDepth = 1;
10 | @reactor() selectMode = ESelectMode.OVERALL;
11 | @reactor() selectEntityTypes?: symbol[];
12 | @reactor() isMultiSelectMode = false;
13 |
14 | @mutation
15 | setMultiSelect(isMultiple: boolean) {
16 | this.isMultiSelectMode = isMultiple;
17 | }
18 |
19 | @mutation()
20 | switchSelectMode(selectMode: ESelectMode) {
21 | this.selectMode = selectMode;
22 | }
23 |
24 | @mutation
25 | setLayerDepth(layerDepth: number) {
26 | this.layerDepth = layerDepth;
27 | }
28 |
29 | @mutation()
30 | select(models: EntityObject[], onSelectHandler?: (models: EntityObject[]) => void) {
31 | if (models.length === 0) {
32 | return;
33 | }
34 | this.selectedEntities.push(...models);
35 | const layerDepths = models.map((m) => m.getParentPathChain().indexOf(m) + 1);
36 | this.setLayerDepth(Math.max(...layerDepths));
37 | onSelectHandler && onSelectHandler(models);
38 | }
39 |
40 | @mutation()
41 | unselect(models: EntityObject[], onUnselectHandler?: (models: EntityObject[]) => void) {
42 | batchRemove(this.selectedEntities, models);
43 | onUnselectHandler && onUnselectHandler(models);
44 | }
45 |
46 | @mutation()
47 | clearAllSelected(onUnselectHandler?: (models: EntityObject[]) => void) {
48 | const selected = this.selectedEntities.slice();
49 | batchRemove(this.selectedEntities, selected);
50 | onUnselectHandler && onUnselectHandler(selected);
51 | }
52 |
53 | @mutation()
54 | setSelectEntityTypes(types?: symbol[]) {
55 | this.selectEntityTypes = types;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/packages/design-engine/src/selection-command/index.ts:
--------------------------------------------------------------------------------
1 | import { SelectionCommand } from './command';
2 |
3 | export default SelectionCommand;
4 |
--------------------------------------------------------------------------------
/packages/design-engine/src/space-engine/README.md:
--------------------------------------------------------------------------------
1 | # 内空引擎
2 |
3 | * 2d 内空
4 | * 3d 内空
5 |
--------------------------------------------------------------------------------
/packages/design-engine/src/space-engine/index.ts:
--------------------------------------------------------------------------------
1 | class SpaceEngine {
2 |
3 | }
4 |
5 | export default SpaceEngine;
6 |
--------------------------------------------------------------------------------
/packages/design-engine/src/unit-system/README.md:
--------------------------------------------------------------------------------
1 | # 单位系统
2 |
--------------------------------------------------------------------------------
/packages/design-engine/src/unit-system/index.ts:
--------------------------------------------------------------------------------
1 | class UnitSystem {
2 |
3 | }
4 |
5 | export default UnitSystem;
6 |
--------------------------------------------------------------------------------
/packages/design-engine/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/design-engine/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/event-manager/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/event-manager/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/event-manager/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/event-manager/src/index.ts:
--------------------------------------------------------------------------------
1 | export {
2 | throttleInAFrame,
3 | TaskPriority,
4 | } from '@turbox3d/shared';
5 | export { Key } from './keyboard/keyCode';
6 | export {
7 | HotKey,
8 | HotKeyController,
9 | HotKeyConfig,
10 | HotKeyData,
11 | } from './keyboard';
12 | export { SceneEvent } from './interactive/sceneEvent';
13 | export { CoordinateController } from './interactive/coordinate';
14 | export {
15 | InteractiveEvent,
16 | EventType,
17 | GesturesExtra,
18 | Extra,
19 | } from './interactive/listener/type';
20 | export { InteractiveListener } from './interactive/listener/index';
21 | export { InteractiveController } from './interactive/index';
22 | export {
23 | InteractiveType,
24 | InteractiveConfig,
25 | CoordinateType,
26 | ViewEntity,
27 | } from './interactive/type';
28 | export { HotKeyEventType } from './keyboard/listener/util';
29 |
--------------------------------------------------------------------------------
/packages/event-manager/src/interactive/listener/type.ts:
--------------------------------------------------------------------------------
1 | import { Vec2 } from '@turbox3d/shared';
2 | import { NativeEventSet } from '../type';
3 |
4 | /** 标示拖拽阶段 */
5 | export enum DragStatus {
6 | Ready = 'ready',
7 | Dragging = 'dragging',
8 | End = 'end',
9 | }
10 |
11 | /**
12 | * 当次鼠标事件(down -> move -> up)的处理类型
13 | */
14 | export enum MouseDealType {
15 | /**
16 | * 作为一次 Drag 事件处理
17 | */
18 | Drag = 'drag',
19 | /**
20 | * 作为一次 Click 事件处理
21 | */
22 | Click = 'click',
23 | /** 多点触控事件 */
24 | MultiTouch = 'multi-touch',
25 | /** 按压 */
26 | Press = 'press',
27 | }
28 |
29 | /**
30 | * 可监听的交互事件类型
31 | */
32 | export enum InteractiveEvent {
33 | Click = 1, // 涵盖移动端的 tap
34 | DBClick,
35 | RightClick,
36 | DragStart, // 涵盖移动端的 pan
37 | DragMove, // 涵盖移动端的 pan
38 | DragEnd, // 涵盖移动端的 pan
39 | CarriageMove,
40 | CarriageEnd,
41 | Hover,
42 | Wheel,
43 | PinchStart,
44 | Pinch,
45 | PinchEnd,
46 | RotateStart,
47 | Rotate,
48 | RotateEnd,
49 | Press,
50 | PressUp,
51 | }
52 |
53 | export enum EventType {
54 | onClick,
55 | onDBClick,
56 | onRightClick,
57 | onDragStart,
58 | onDragMove,
59 | onDragEnd,
60 | onCarriageMove,
61 | onCarriageEnd,
62 | onHoverIn,
63 | onHoverOut,
64 | onWheel,
65 | onPinchStart,
66 | onPinch,
67 | onPinchEnd,
68 | onRotateStart,
69 | onRotate,
70 | onRotateEnd,
71 | onPress,
72 | onPressUp,
73 | }
74 |
75 | export type ICallBack = {
76 | (event: NativeEventSet, extra?: GesturesExtra | Extra): void;
77 | };
78 |
79 | export interface GesturesExtra {
80 | scale?: number;
81 | deltaScale?: number;
82 | rotate?: number;
83 | deltaRotate?: number;
84 | eventCache?: NativeEventSet[];
85 | }
86 |
87 | export interface Extra {
88 | mouseDownInfo?: Vec2;
89 | }
90 |
91 | export interface IFunc {
92 | (event: NativeEventSet, extra?: GesturesExtra | Extra): void;
93 | }
94 |
--------------------------------------------------------------------------------
/packages/event-manager/src/interactive/listener/utils.ts:
--------------------------------------------------------------------------------
1 | import { Vec2 } from '@turbox3d/shared';
2 | import { NativeEventSet } from '../type';
3 |
4 | export function isMouseMoved(mouseDownInfo: Vec2, moveEvent: NativeEventSet, tolerance: number) {
5 | const dx = mouseDownInfo.x - moveEvent.clientX;
6 | const dy = mouseDownInfo.y - moveEvent.clientY;
7 | return dx * dx + dy * dy > tolerance * tolerance;
8 | }
9 |
--------------------------------------------------------------------------------
/packages/event-manager/src/keyboard/type.ts:
--------------------------------------------------------------------------------
1 | import { HotKeyEventType } from './listener/util';
2 |
3 | export type Key = string | string[];
4 |
5 | export type Handler = (keyEventType: HotKeyEventType) => void;
6 | export type Condition = () => boolean;
7 |
8 | export interface HotKeyConfig {
9 | /**
10 | * 快捷键字符
11 | *
12 | * 单个:'ctrl+a'
13 | *
14 | * 多个:['ctrl+a', 'ctrl+b', 'meta+a']
15 | */
16 | key: Key;
17 | /**
18 | * 快捷功能名称
19 | */
20 | name?: string;
21 | /**
22 | * 快捷键功能描述
23 | */
24 | description?: string;
25 | /**
26 | * 快捷键是否露出
27 | *
28 | * @default false
29 | */
30 | show?: boolean;
31 | /**
32 | * 快捷键的额外信息(当快捷键冲突时会提示该信息)
33 | */
34 | info?: string;
35 | /**
36 | * 快捷键回调函数
37 | */
38 | handler: Handler;
39 | /**
40 | * 快捷键触发回调的条件函数
41 | *
42 | * @default () => true
43 | */
44 | condition?: Condition;
45 | }
46 |
47 | export interface HotKeyData {
48 | key: string;
49 | name?: string;
50 | description?: string;
51 | }
52 |
--------------------------------------------------------------------------------
/packages/event-manager/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/event-manager/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/_utils/README.md:
--------------------------------------------------------------------------------
1 | # 公共工具函数
2 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/angle-dimension/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh2D } from '@turbox3d/renderer-pixi';
2 | import * as PIXI from 'pixi.js';
3 | import { Vec2 } from '@turbox3d/shared';
4 | import { drawText } from '../_utils/utils';
5 |
6 | interface IXY {
7 | x: number;
8 | y: number;
9 | }
10 |
11 | interface IAngleDimensionProps {
12 | center: IXY;
13 | rotation?: number;
14 | scale?: Vec2;
15 | radius: number;
16 | startAngle: number;
17 | endAngle: number;
18 | anticlockwise: boolean;
19 | }
20 |
21 | /**
22 | * @description: 半径尺寸线
23 | */
24 | export default class AngleDimension extends Mesh2D {
25 | protected view = new PIXI.Graphics();
26 |
27 | public draw() {
28 | const graphics = this.view;
29 | graphics.clear();
30 |
31 | graphics.lineStyle(1, 0x131313);
32 | graphics.line.native = true;
33 |
34 | graphics.arc(this.props.center.x, this.props.center.y, this.props.radius, this.props.startAngle, this.props.endAngle, !this.props.anticlockwise);
35 |
36 | // calculate number text
37 | let k = -1;
38 | if (this.props.anticlockwise) k *= -1;
39 | if (this.props.endAngle % (Math.PI * 2) < this.props.startAngle % (Math.PI * 2)) k *= -1;
40 |
41 | let text = Math.abs(this.props.endAngle - this.props.startAngle) % (Math.PI * 2) * 180 / Math.PI;
42 | if (k < 0) text = 360 - text;
43 |
44 | const bisectorAngle = (this.props.startAngle + this.props.endAngle) / 2;
45 | const bisectorDir = { x: Math.cos(bisectorAngle), y: Math.sin(bisectorAngle) };
46 | drawText(graphics, text.toFixed(0), { offset: { x: this.props.center.x + 1.3 * k * this.props.radius * bisectorDir.x, y: this.props.center.y + 1.2 * k * this.props.radius * bisectorDir.y }, size: this.props.radius / 2, rotation: Math.PI / 2 + bisectorAngle });
47 |
48 | this.view.rotation = this.props.rotation ?? 0;
49 | this.view.scale.set(this.props.scale?.x ?? 1, this.props.scale?.y ?? 1);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/arrow2d/index.ts:
--------------------------------------------------------------------------------
1 | export default class Arrow2d {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/axis2d/README.md:
--------------------------------------------------------------------------------
1 | # 坐标轴 2d 控件
2 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/axis2d/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh2D } from '@turbox3d/renderer-pixi';
2 | import * as PIXI from 'pixi.js';
3 | import DrawUtils from '../draw-utils/index';
4 |
5 | interface IAxis2dProps {
6 | type?: 'front' | 'top' | 'left';
7 | }
8 |
9 | /** 坐标轴 2d 控件 */
10 | export default class Axis2d extends Mesh2D {
11 | protected view = new PIXI.Graphics();
12 |
13 | draw() {
14 | this.view.clear();
15 | this.view.zIndex = Number.MAX_SAFE_INTEGER;
16 | const red = 0xff0000; // x轴
17 | const green = 0x09ff00; // y轴
18 | const blue = 0x005cfc; // z轴
19 | let lineColors: number[] = [red, green];
20 | if (this.props.type === 'front') {
21 | lineColors = [red, green];
22 | } else if (this.props.type === 'top') {
23 | lineColors = [red, blue];
24 | } else if (this.props.type === 'left') {
25 | lineColors = [blue, green];
26 | }
27 | DrawUtils.drawLine(this.view, {
28 | x0: 0,
29 | y0: 0,
30 | x1: Number.MAX_SAFE_INTEGER,
31 | y1: 0,
32 | lineWidth: 5,
33 | lineColor: lineColors[0],
34 | alignment: 0.5,
35 | });
36 | DrawUtils.drawLine(this.view, {
37 | x0: 0,
38 | y0: 0,
39 | x1: 0,
40 | y1: Number.MAX_SAFE_INTEGER,
41 | lineWidth: 5,
42 | lineColor: lineColors[1],
43 | alignment: 0.5,
44 | });
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/circle2d/index.ts:
--------------------------------------------------------------------------------
1 | import * as PIXI from 'pixi.js';
2 | import { Mesh2D } from '@turbox3d/renderer-pixi';
3 | import { Vec2 } from '@turbox3d/shared';
4 | import DrawUtils from '../draw-utils/index';
5 |
6 | interface ICircle2DProps {
7 | center: Vec2;
8 | radius: number;
9 | rotation?: number;
10 | scale?: Vec2;
11 | lineWidth?: number;
12 | lineColor?: number;
13 | lineAlpha?: number;
14 | fillColor?: number;
15 | fillAlpha?: number;
16 | alpha?: number;
17 | alignment?: number;
18 | native?: boolean;
19 | zIndex?: number;
20 | }
21 |
22 | /** 正方形 */
23 | export default class Circle2d extends Mesh2D {
24 | protected view = new PIXI.Graphics();
25 | protected reactivePipeLine = [
26 | this.updateGeometry,
27 | this.updateMaterial,
28 | this.updatePosition,
29 | this.updateRotation,
30 | this.updateScale,
31 | ];
32 |
33 | updateGeometry() {
34 | this.view.clear();
35 | const {
36 | radius,
37 | lineWidth,
38 | lineColor,
39 | lineAlpha,
40 | fillColor,
41 | fillAlpha,
42 | alpha,
43 | alignment,
44 | native,
45 | } = this.props;
46 | DrawUtils.drawCircle(this.view, {
47 | cx: 0,
48 | cy: 0,
49 | radius,
50 | lineWidth,
51 | lineColor,
52 | lineAlpha,
53 | fillColor,
54 | fillAlpha,
55 | alpha,
56 | alignment,
57 | native,
58 | });
59 | }
60 |
61 | updateMaterial() {
62 | const { zIndex = 0 } = this.props;
63 | this.view.zIndex = zIndex;
64 | }
65 |
66 | updatePosition() {
67 | const { center } = this.props;
68 | this.view.position.set(center.x, center.y);
69 | }
70 |
71 | updateRotation() {
72 | this.view.rotation = this.props.rotation ?? 0;
73 | }
74 |
75 | updateScale() {
76 | const { scale = { x: 1, y: 1 } } = this.props;
77 | this.view.scale.set(scale.x, scale.y);
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/dimension/README.md:
--------------------------------------------------------------------------------
1 | # 尺寸线的图形控件
2 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/draw-utils/README.md:
--------------------------------------------------------------------------------
1 | # 图形绘制工具方法
2 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/draw-utils/drawCircle.ts:
--------------------------------------------------------------------------------
1 | import * as PIXI from 'pixi.js';
2 | import { IGraphicOption, setCommonOption } from './option';
3 |
4 | interface ICircleParam {
5 | cx: number;
6 | cy: number;
7 | radius: number;
8 | }
9 |
10 | export function drawCircle(graphic: PIXI.Graphics, param: ICircleParam & IGraphicOption) {
11 | // 样式配置
12 | setCommonOption(graphic, param);
13 |
14 | const { cx, cy, radius } = param;
15 | graphic.drawCircle(cx, cy, radius);
16 | graphic.endFill();
17 | }
18 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/draw-utils/drawLine.ts:
--------------------------------------------------------------------------------
1 | import * as PIXI from 'pixi.js';
2 | import { IGraphicOption, parseGraphicOption } from './option';
3 |
4 | interface ILineParam {
5 | x0: number;
6 | y0: number;
7 | x1: number;
8 | y1: number;
9 | }
10 |
11 | interface ILinesParam {
12 | points: number[];
13 | }
14 |
15 | /**
16 | * 绘制一条从 (x0, y0) 到 (x1, y1) 的线
17 | */
18 | export function drawLine(graphic: PIXI.Graphics, param: ILineParam & IGraphicOption) {
19 | // 样式配置
20 | const { lineWidth, lineColor, lineAlpha, alignment, native } = parseGraphicOption(param);
21 | graphic.lineStyle(lineWidth, lineColor, lineAlpha, alignment, native);
22 | // 坐标配置
23 | const { x0, y0, x1, y1 } = param;
24 | graphic.moveTo(x0, y0);
25 | graphic.lineTo(x1, y1);
26 | return graphic;
27 | }
28 |
29 | export function drawLines(graphic: PIXI.Graphics, param: ILinesParam & IGraphicOption) {
30 | // 样式配置
31 | const { lineWidth, lineColor, lineAlpha, alignment, native } = parseGraphicOption(param);
32 | graphic.lineStyle(lineWidth, lineColor, lineAlpha, alignment, native);
33 | // 坐标配置
34 | const [x0, y0] = param.points;
35 | graphic.moveTo(x0, y0);
36 | for (let index = 2; index < param.points.length; index += 2) {
37 | graphic.lineTo(param.points[index], param.points[index + 1]);
38 | }
39 | return graphic;
40 | }
41 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/draw-utils/drawPath.ts:
--------------------------------------------------------------------------------
1 | import * as PIXI from 'pixi.js';
2 | import { drawLine } from './drawLine';
3 | import { IGraphicOption, parseGraphicOption } from './option';
4 |
5 | interface IPathParam {
6 | path: Array<{ x: number; y: number }>;
7 | /**
8 | * 绘制的路径是否闭合
9 | *
10 | * 默认:false,不闭合
11 | */
12 | closed?: boolean;
13 | }
14 |
15 | /**
16 | * 绘制一条路径
17 | */
18 | export function drawPath(graphic: PIXI.Graphics, param: IPathParam & IGraphicOption) {
19 | const { path, closed = false } = param;
20 | const length = path.length - 1;
21 |
22 | if (length < 1) {
23 | return;
24 | }
25 |
26 | // 样式配置
27 | const { lineWidth, lineColor, lineAlpha, alignment, native } = parseGraphicOption(param);
28 | graphic.lineStyle(lineWidth, lineColor, lineAlpha, alignment, native);
29 |
30 | for (let i = 0; i < length; i++) {
31 | drawLine(graphic, {
32 | x0: path[i].x,
33 | y0: path[i].y,
34 | x1: path[i + 1].x,
35 | y1: path[i + 1].y,
36 | lineWidth,
37 | lineColor,
38 | lineAlpha,
39 | alignment,
40 | native,
41 | });
42 | }
43 |
44 | if (closed) {
45 | drawLine(graphic, {
46 | x0: path[length].x,
47 | y0: path[length].y,
48 | x1: path[0].x,
49 | y1: path[0].y,
50 | lineWidth,
51 | lineColor,
52 | lineAlpha,
53 | alignment,
54 | native,
55 | });
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/draw-utils/drawPolygon.ts:
--------------------------------------------------------------------------------
1 | import * as PIXI from 'pixi.js';
2 | import { IGraphicOption, setCommonOption } from './option';
3 |
4 | interface IPolygonParam {
5 | path: Array<{ x: number; y: number }>;
6 | }
7 |
8 | export function drawPolygon(graphic: PIXI.Graphics, param: IPolygonParam & IGraphicOption) {
9 | // 样式配置
10 | setCommonOption(graphic, param);
11 |
12 | const points = param.path.map(p => new PIXI.Point(p.x, p.y));
13 | graphic.drawPolygon(points);
14 | graphic.endFill();
15 | }
16 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/draw-utils/index.ts:
--------------------------------------------------------------------------------
1 | import { drawCircle } from './drawCircle';
2 | import { drawLine, drawLines } from './drawLine';
3 | import { drawPath } from './drawPath';
4 | import { drawPolygon } from './drawPolygon';
5 | import { drawRect } from './drawRect';
6 |
7 | const DrawUtils = {
8 | drawCircle,
9 | drawLine,
10 | drawLines,
11 | drawPath,
12 | drawPolygon,
13 | drawRect,
14 | };
15 |
16 | export default DrawUtils;
17 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/gizmo2d/README.md:
--------------------------------------------------------------------------------
1 | # gizmo 对象旋转、平移、缩放控件
2 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/grid2d/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh2D } from '@turbox3d/renderer-pixi';
2 | import { GridHelper } from './grid-helper';
3 |
4 | interface IGrid2dProps {
5 | gridWidth: number;
6 | cellSize?: number;
7 | lineWidth?: number;
8 | lineColor?: number;
9 | drawBoundaries?: boolean;
10 | zIndex?: number;
11 | }
12 |
13 | export default class Grid2d extends Mesh2D {
14 | protected view!: GridHelper;
15 |
16 | draw() {
17 | const { lineWidth = 2, lineColor = 0xffffff, drawBoundaries = true, gridWidth, cellSize = 0, zIndex = 0 } = this.props;
18 | this.view = new GridHelper(gridWidth, cellSize);
19 | this.view.lineStyle({ width: lineWidth, color: lineColor });
20 | this.view.drawBoundaries = drawBoundaries;
21 | this.view.drawGrid();
22 | this.view.position.set(-gridWidth / 2 + window.innerWidth / 2, -gridWidth / 2 + window.innerHeight / 2);
23 | this.view.zIndex = zIndex;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/index.ts:
--------------------------------------------------------------------------------
1 | const ENV = process.env.NODE_ENV;
2 | if (
3 | ENV !== 'production' &&
4 | ENV !== 'test' &&
5 | typeof console !== 'undefined' &&
6 | console.warn && // eslint-disable-line no-console
7 | typeof window !== 'undefined'
8 | ) {
9 | // eslint-disable-next-line no-console
10 | console.warn(
11 | 'You are using a whole package of graphic component pixi, ' +
12 | 'please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size.',
13 | );
14 | }
15 |
16 | export { default as Rect2d } from './rect2d/index';
17 | export { default as Circle2d } from './circle2d/index';
18 | export { default as Polygon } from './polygon/index';
19 | export { default as Placement } from './placement/index';
20 | export { default as DrawUtils } from './draw-utils/index';
21 | export { default as Dimension } from './dimension/index';
22 | export { default as RadiusDimension } from './radius-dimension/index';
23 | export { default as AngleDimension } from './angle-dimension/index';
24 | export { default as Axis2d } from './axis2d/index';
25 | export { default as Arrow2d } from './arrow2d/index';
26 | export { default as Gizmo2d } from './gizmo2d/index';
27 | export { default as Text2d } from './text2d/index';
28 | export { default as Image2d } from './image2d/index';
29 | export { default as Line2d } from './line2d/index';
30 | export { default as Grid2d } from './grid2d/index';
31 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/line2d/index.ts:
--------------------------------------------------------------------------------
1 | import { Vec2 } from '@turbox3d/shared';
2 | import { Mesh2D } from '@turbox3d/renderer-pixi';
3 | import * as PIXI from 'pixi.js';
4 | import DrawUtils from '../draw-utils';
5 |
6 | interface ILine2dProps {
7 | lineWidth?: number;
8 | lineColor?: number;
9 | alignment?: number;
10 | start: Vec2;
11 | end: Vec2;
12 | rotation?: number;
13 | scale?: Vec2;
14 | zIndex?: number;
15 | }
16 |
17 | export default class Line2d extends Mesh2D {
18 | protected view = new PIXI.Graphics();
19 |
20 | draw() {
21 | const { lineWidth = 2, lineColor = 0xffffff, start, end, alignment = 0.5, zIndex = 0 } = this.props;
22 | this.view.clear();
23 | this.view.zIndex = zIndex;
24 | DrawUtils.drawLine(this.view, {
25 | x0: start.x,
26 | y0: start.y,
27 | x1: end.x,
28 | y1: end.y,
29 | lineWidth,
30 | lineColor,
31 | alignment,
32 | });
33 | this.view.rotation = this.props.rotation ?? 0;
34 | this.view.scale.set(this.props.scale?.x ?? 1, this.props.scale?.y ?? 1);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/placement/README.md:
--------------------------------------------------------------------------------
1 | # 六面、四角摆放的控件
2 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/placement/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh2D } from '@turbox3d/renderer-pixi';
2 | import * as PIXI from 'pixi.js';
3 |
4 | export default class Placement extends Mesh2D {
5 | protected view = new PIXI.Graphics();
6 | protected reactivePipeLine = [
7 | this.updateGeometry,
8 | this.updateMaterial,
9 | this.updatePosition,
10 | this.updateRotation,
11 | this.updateScale,
12 | ];
13 |
14 | updateGeometry() {
15 | this.view.clear();
16 | }
17 |
18 | updateMaterial() {
19 | //
20 | }
21 |
22 | updatePosition() {
23 | // const { position } = this.props;
24 | // this.view.position.set(position!.x, position!.y);
25 | }
26 |
27 | updateRotation() {
28 | // this.view.rotation = this.props.rotation!;
29 | }
30 |
31 | updateScale() {
32 | // const { scale } = this.props;
33 | // this.view.scale.set(scale!.x, scale!.y);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/src/polygon/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh2D } from '@turbox3d/renderer-pixi';
2 | import { Vec2 } from '@turbox3d/shared';
3 | import * as PIXI from 'pixi.js';
4 | import DrawUtils from '../draw-utils/index';
5 |
6 | interface IPolygonProps {
7 | path: Vec2[];
8 | rotation?: number;
9 | scale?: Vec2;
10 | lineWidth?: number;
11 | lineColor?: number;
12 | lineAlpha?: number;
13 | fillColor?: number;
14 | fillAlpha?: number;
15 | alpha?: number;
16 | zIndex?: number;
17 | alignment?: number;
18 | native?: boolean;
19 | }
20 |
21 | /** 多边形 */
22 | export default class Polygon extends Mesh2D {
23 | protected view = new PIXI.Graphics();
24 | protected reactivePipeLine = [
25 | this.updateGeometry,
26 | this.updateMaterial,
27 | this.updatePosition,
28 | this.updateRotation,
29 | this.updateScale,
30 | ];
31 |
32 | updateGeometry() {
33 | this.view.clear();
34 | const {
35 | path,
36 | lineWidth,
37 | lineColor,
38 | lineAlpha,
39 | fillColor,
40 | fillAlpha,
41 | alpha,
42 | zIndex,
43 | alignment,
44 | native,
45 | } = this.props;
46 | zIndex && (this.view.zIndex = zIndex);
47 | DrawUtils.drawPolygon(this.view, {
48 | path: path.map(p => ({ x: p.x, y: p.y })),
49 | lineWidth,
50 | lineColor,
51 | lineAlpha,
52 | fillColor,
53 | fillAlpha,
54 | alpha,
55 | alignment,
56 | native,
57 | });
58 | }
59 |
60 | updateMaterial() {
61 | //
62 | }
63 |
64 | updatePosition() {
65 | // const { position } = this.props;
66 | // this.view.position.set(position!.x, position!.y);
67 | }
68 |
69 | updateRotation() {
70 | this.view.rotation = this.props.rotation ?? 0;
71 | }
72 |
73 | updateScale() {
74 | this.view.scale.set(this.props.scale?.x ?? 1, this.props.scale?.y ?? 1);
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/graphic-component-pixi/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/_utils/README.md:
--------------------------------------------------------------------------------
1 | # 公共工具函数
2 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/_utils/utils.ts:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turbox3d/turbox/417d21098c01894dd7403c3e486acf4512c26b40/packages/graphic-component-three/src/_utils/utils.ts
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/arrow3d/index.ts:
--------------------------------------------------------------------------------
1 | export default class Arrow3d {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/axis3d/README.md:
--------------------------------------------------------------------------------
1 | # 坐标轴 3d 控件
2 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/axis3d/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh3D } from '@turbox3d/renderer-three';
2 | import * as THREE from 'three';
3 |
4 | /** 坐标轴 3d 控件 */
5 | export default class Axis3d extends Mesh3D {
6 | protected view = new THREE.AxesHelper(5000);
7 | }
8 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/circle3d/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh3D } from '@turbox3d/renderer-three';
2 | import * as THREE from 'three';
3 | import { Vec3 } from '@turbox3d/shared';
4 |
5 | interface ICircleProps {
6 | radius: number;
7 | color?: number;
8 | imgUrl?: string;
9 | imgScale?: Vec3;
10 | scale?: Vec3;
11 | opacity?: number;
12 | }
13 |
14 | export default class Circle3d extends Mesh3D {
15 | sprite = new THREE.Sprite();
16 | protected view = new THREE.Mesh();
17 | protected reactivePipeLine = [this.updateGeometry, this.updateImage];
18 |
19 | async updateGeometry() {
20 | const { scale = { x: 1, y: 1, z: 1 }, radius, color, opacity = 1 } = this.props;
21 | const geometry = new THREE.CircleGeometry(radius, 32);
22 | const material = new THREE.MeshBasicMaterial({ color: color || 0xBF975B, opacity, transparent: true });
23 | (this.view as THREE.Mesh).geometry = geometry;
24 | (this.view as THREE.Mesh).material = material;
25 | this.view.scale.set(scale.x, scale.y, scale.z);
26 | }
27 |
28 | async updateImage() {
29 | const { imgScale, radius, imgUrl } = this.props;
30 | if (imgUrl) {
31 | const spriteMaterial = new THREE.SpriteMaterial();
32 | const loader = new THREE.TextureLoader();
33 | loader.setWithCredentials(true);
34 | const map = await loader.loadAsync(imgUrl).catch((err) => {
35 | console.error(err);
36 | });
37 | if (!map) {
38 | return;
39 | }
40 | spriteMaterial.map = map;
41 | spriteMaterial.map.minFilter = THREE.LinearFilter;
42 | this.sprite.scale.set(imgScale?.x || radius * 2 - 5, imgScale?.y || radius * 2 - 5, imgScale?.z || 1);
43 | this.sprite.material = spriteMaterial;
44 | this.view.add(this.sprite);
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/cube/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh3D } from '@turbox3d/renderer-three';
2 | import { Vec3 } from '@turbox3d/shared';
3 | import * as THREE from 'three';
4 |
5 | interface ICubeProps {
6 | size: Vec3;
7 | color?: number;
8 | }
9 |
10 | export default class Cube extends Mesh3D {
11 | protected reactivePipeLine = [this.updateGeometry];
12 | protected view = new THREE.Mesh();
13 |
14 | updateGeometry() {
15 | const geometry = new THREE.BoxGeometry(
16 | this.props.size.x,
17 | this.props.size.y,
18 | this.props.size.z
19 | );
20 | const material = new THREE.MeshPhongMaterial({ color: this.props.color || 0x00D000 });
21 | this.view.geometry = geometry;
22 | this.view.material = material;
23 | this.view.position.set(0, 0, 0);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/fat-line/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh3D } from '@turbox3d/renderer-three';
2 | import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js';
3 | import { Line2 } from 'three/examples/jsm/lines/Line2.js';
4 | import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry.js';
5 | import { Vec3 } from '@turbox3d/shared';
6 |
7 | interface IFatLineProps {
8 | position: Vec3;
9 | rotation: Vec3;
10 | linePositions: number[];
11 | dashed?: boolean;
12 | linewidth?: number;
13 | color?: number;
14 | dashScale?: number;
15 | dashSize?: number;
16 | gapSize?: number;
17 | looped?: boolean;
18 | }
19 |
20 | export default class FatLine extends Mesh3D {
21 | protected reactivePipeLine = [this.updateGeometry];
22 | protected view = new Line2();
23 |
24 | private updateGeometry() {
25 | const { position, rotation, linePositions, dashed = false, linewidth = 0.002, color = 0xFFE802, dashScale = 0.4, dashSize = 1, gapSize = 1, looped = false } = this.props;
26 | const geometry = new LineGeometry();
27 | geometry.setPositions(looped ? [...linePositions, linePositions[0], linePositions[1], linePositions[2]] : linePositions);
28 | const material = new LineMaterial({
29 | color,
30 | linewidth,
31 | dashed,
32 | dashScale,
33 | dashSize,
34 | gapSize,
35 | alphaToCoverage: true,
36 | });
37 | this.view.geometry = geometry;
38 | this.view.material = material;
39 | this.view.position.set(position.x, position.y, position.z);
40 | this.view.rotation.set(rotation.x, rotation.y, rotation.z);
41 | this.view.computeLineDistances();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/gizmo3d/README.md:
--------------------------------------------------------------------------------
1 | # gizmo 对象旋转、平移、缩放控件
2 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/gizmo3d/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh3D } from '@turbox3d/renderer-three';
2 |
3 | export default class Gizmo3d extends Mesh3D {
4 | protected reactivePipeLine = [
5 | this.updateGeometry,
6 | this.updateMaterial,
7 | this.updatePosition,
8 | this.updateRotation,
9 | this.updateScale,
10 | ];
11 |
12 | updateGeometry() {
13 | this.view.clear();
14 | }
15 |
16 | updateMaterial() {
17 | //
18 | }
19 |
20 | updatePosition() {
21 | // const { position } = this.props;
22 | // this.view.position.set(position!.x, position!.y);
23 | }
24 |
25 | updateRotation() {
26 | // this.view.rotation = this.props.rotation!;
27 | }
28 |
29 | updateScale() {
30 | // const { scale } = this.props;
31 | // this.view.scale.set(scale!.x, scale!.y);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/index.ts:
--------------------------------------------------------------------------------
1 | const ENV = process.env.NODE_ENV;
2 | if (
3 | ENV !== 'production' &&
4 | ENV !== 'test' &&
5 | typeof console !== 'undefined' &&
6 | console.warn && // eslint-disable-line no-console
7 | typeof window !== 'undefined'
8 | ) {
9 | // eslint-disable-next-line no-console
10 | console.warn(
11 | 'You are using a whole package of graphic component three, ' +
12 | 'please use https://www.npmjs.com/package/babel-plugin-import to reduce app bundle size.',
13 | );
14 | }
15 |
16 | export { default as Arrow3d } from './arrow3d/index';
17 | export { default as Axis3d } from './axis3d/index';
18 | export { default as Circle3d } from './circle3d/index';
19 | export { default as Cube } from './cube/index';
20 | export { default as FatLine } from './fat-line/index';
21 | export { default as Gizmo3d } from './gizmo3d/index';
22 | export { default as Rect3d } from './rect3d/index';
23 | export { default as Wireframe } from './wireframe/index';
24 | export { default as Animation3d } from './animation3d/index';
25 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/rect3d/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh3D } from '@turbox3d/renderer-three';
2 | import * as THREE from 'three';
3 |
4 | interface IRect3dProps {
5 | width: number;
6 | height: number;
7 | color?: number;
8 | side?: THREE.Side;
9 | opacity?: number;
10 | }
11 |
12 | export default class Rect3d extends Mesh3D {
13 | protected reactivePipeLine = [this.updateGeometry];
14 | protected view = new THREE.Mesh();
15 |
16 | updateGeometry() {
17 | const { width, height, color, side, opacity = 1 } = this.props;
18 | const geometry = new THREE.PlaneGeometry(width, height);
19 | const material = new THREE.MeshBasicMaterial({ color: color || 0xFFE802, opacity, transparent: true, side: side || THREE.DoubleSide });
20 | this.view.geometry = geometry;
21 | this.view.material = material;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/src/wireframe/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh3D } from '@turbox3d/renderer-three';
2 | import { Vec3 } from '@turbox3d/shared';
3 | import * as THREE from 'three';
4 | import { LineSegmentsGeometry } from 'three/examples/jsm/lines/LineSegmentsGeometry.js';
5 | import { Wireframe as WireFrame } from 'three/examples/jsm/lines/Wireframe.js';
6 | import { LineMaterial } from 'three/examples/jsm/lines/LineMaterial.js';
7 |
8 | interface IProps {
9 | size: Vec3;
10 | color?: number;
11 | lineWidth?: number;
12 | }
13 |
14 | export default class Wireframe extends Mesh3D {
15 | protected reactivePipeLine = [this.updateGeometry];
16 | protected view = new WireFrame();
17 |
18 | private updateGeometry() {
19 | const { size, color, lineWidth } = this.props;
20 | const geometry = new THREE.BoxGeometry(size.x, size.y, size.z);
21 | const wireframe = new THREE.EdgesGeometry(geometry);
22 | const material = new LineMaterial({ color: color || 0xFFE802, linewidth: lineWidth || 0.002 });
23 | const lineGeo = new LineSegmentsGeometry().fromEdgesGeometry(wireframe);
24 | this.view.geometry = lineGeo;
25 | this.view.material = material;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/graphic-component-three/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/math/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/math/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/math/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # @turbox3d/math
2 |
3 | ## 1.1.21
4 |
5 | ### Patch Changes
6 |
7 | - fix: enhance gizmo2d&text2d
8 |
9 | ## 1.1.20
10 |
11 | ### Patch Changes
12 |
13 | - fix: fix issue
14 |
15 | ## 1.1.19
16 |
17 | ### Patch Changes
18 |
19 | - fix: fix dep version
20 |
21 | ## 1.1.18
22 |
23 | ### Patch Changes
24 |
25 | - refactor: enhance code
26 |
27 | ## 1.1.17
28 |
29 | ### Patch Changes
30 |
31 | - fix: fix
32 |
33 | ## 1.1.16
34 |
35 | ### Patch Changes
36 |
37 | - feat: add grid2d&gizmo2d component
38 |
39 | ## 1.1.15
40 |
41 | ### Patch Changes
42 |
43 | - feat: add inference engine&fix rect2d&add line2d&add keyup hot key feature
44 |
45 | ## 1.1.14
46 |
47 | ### Patch Changes
48 |
49 | - fix: fix build issue
50 |
51 | ## 1.1.13
52 |
53 | ### Patch Changes
54 |
55 | - fix: update version
56 |
57 | ## 1.1.12
58 |
59 | ### Patch Changes
60 |
61 | - f188584: Fix build script
62 |
63 | ## 1.1.11
64 |
65 | ### Patch Changes
66 |
67 | - Sync code
68 |
69 | ## 1.1.10
70 |
71 | ### Patch Changes
72 |
73 | - Fix changeset issue
74 |
75 | ## 1.1.9
76 |
77 | ### Patch Changes
78 |
79 | - Upgrade deps: pixi.js->v7,three->v0.159,react->v18,react-dom->v18,typescript->v5
80 |
81 | ## 1.1.8
82 |
83 | ### Patch Changes
84 |
85 | - Move dts file to dist
86 |
87 | ## 1.1.7
88 |
89 | ### Patch Changes
90 |
91 | - Update build script&config file
92 |
93 | ## 1.1.6
94 |
95 | ### Patch Changes
96 |
97 | - Add doc gen building process
98 |
99 | ## 1.1.5
100 |
101 | ### Patch Changes
102 |
103 | - Upgrade react version
104 |
105 | ## 1.1.4
106 |
107 | ### Patch Changes
108 |
109 | - Lint change
110 |
111 | ## 1.1.3
112 |
113 | ### Patch Changes
114 |
115 | - Replace pnpm from lerna
116 |
--------------------------------------------------------------------------------
/packages/math/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/math/src/base/Tolerance.ts:
--------------------------------------------------------------------------------
1 | export const TOLERANCE = 1E-6;
2 | export const TOLERANCE_HALF = TOLERANCE * 0.5;
3 | export const TOLERANCE_SQUARE = TOLERANCE * TOLERANCE;
4 | export const TOLERANCE_SAGITTA = 1;
5 |
6 | export class Tolerance {
7 | static COS_TOL = 1e-6;
8 | static DIST_TOL = 1e-6;
9 | static NUM_TOL = 1e-6;
10 | static global = new Tolerance();
11 | static setGlobal(cosTol: number, distTol: number, numTol: number) {
12 | Tolerance.global = new Tolerance(cosTol, distTol, numTol);
13 | }
14 |
15 | cosTol: number;
16 | distTol: number;
17 | numTol: number;
18 |
19 | constructor(cosTol?: number, distTol?: number, numTol?: number) {
20 | this.cosTol = cosTol || Tolerance.COS_TOL;
21 | this.distTol = distTol || Tolerance.DIST_TOL;
22 | this.numTol = numTol || Tolerance.NUM_TOL;
23 | }
24 |
25 | /**
26 | * set cosTol by given angle
27 | * @param angle
28 | * @param isRadian true means the angle is radian, false means the angle is degree
29 | */
30 | setCosTolByAngle(angle: number, isRadian: boolean) {
31 | const flag: number = isRadian ? 1 : Math.PI / 180;
32 | this.cosTol = 1 - Math.cos(angle * flag);
33 | }
34 |
35 | clone() {
36 | return new Tolerance(this.cosTol, this.distTol, this.numTol);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/packages/math/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Box2 } from './base/Box2';
2 | import { Box3 } from './base/Box3';
3 | import { Euler } from './base/Euler';
4 | import { Interval } from './base/Interval';
5 | import { Line3 } from './base/Line3';
6 | import { MathUtils } from './MathUtils';
7 | import { Matrix3 } from './base/Matrix3';
8 | import { Matrix4 } from './base/Matrix4';
9 | import { Quaternion } from './base/Quaternion';
10 | import { Ray } from './base/Ray';
11 | import { Tolerance } from './base/Tolerance';
12 | import { Vector2 } from './base/Vector2';
13 | import { Vector3 } from './base/Vector3';
14 | import { Vector4 } from './base/Vector4';
15 |
16 | export interface Vec2 {
17 | x: number;
18 | y: number;
19 | }
20 |
21 | export interface Vec3 {
22 | x: number;
23 | y: number;
24 | z: number;
25 | }
26 |
27 | export {
28 | Box2,
29 | Box3,
30 | Euler,
31 | Interval,
32 | Line3,
33 | MathUtils,
34 | Matrix3,
35 | Matrix4,
36 | Quaternion,
37 | Ray,
38 | Tolerance,
39 | Vector2,
40 | Vector3,
41 | Vector4,
42 | };
43 |
--------------------------------------------------------------------------------
/packages/math/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/math/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/reactivity-react/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/reactivity-react/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/reactivity-react/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/reactivity-react/src/components/ErrorBoundary.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | export default class ErrorBoundary extends React.Component {
4 | state = {
5 | hasError: false,
6 | error: {
7 | message: '',
8 | },
9 | };
10 |
11 | componentDidCatch(error: Error) {
12 | this.setState({
13 | hasError: true,
14 | error,
15 | });
16 | }
17 |
18 | render() {
19 | const { message } = this.state.error;
20 | if (this.state.hasError) {
21 | return Something went wrong. Error: {message}
;
22 | }
23 | return this.props.children;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/packages/reactivity-react/src/index.ts:
--------------------------------------------------------------------------------
1 | import * as ReactDOM from 'react-dom';
2 | import { registerExternalBatchUpdate, init } from '@turbox3d/reactivity';
3 | import { Reactive } from './components/Reactive';
4 | import { IdCustomType } from './utils/index';
5 |
6 | init();
7 | registerExternalBatchUpdate({
8 | handler: ReactDOM.unstable_batchedUpdates,
9 | idCustomType: IdCustomType,
10 | });
11 |
12 | export * from '@turbox3d/reactivity';
13 | export { Reactive };
14 |
--------------------------------------------------------------------------------
/packages/reactivity-react/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js
2 | const hoistBlackList = {
3 | $$typeof: true,
4 | render: true,
5 | compare: true,
6 | type: true,
7 | };
8 |
9 | export function copyStaticProperties(base, target) {
10 | const keys = Object.keys(base);
11 | for (let index = 0; index < keys.length; index++) {
12 | const key = keys[index];
13 | if (hoistBlackList[key] === void 0) {
14 | Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(base, key)!);
15 | }
16 | }
17 | }
18 |
19 | export const IdCustomType = 'react';
20 |
--------------------------------------------------------------------------------
/packages/reactivity-react/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/reactivity-react/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/reactivity/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/reactivity/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/reactivity/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/reactivity/src/const/config.ts:
--------------------------------------------------------------------------------
1 | import { deepMerge } from '@turbox3d/shared';
2 | import { ConfigCtx } from '../interfaces';
3 |
4 | const isDev = process.env.NODE_ENV !== 'production';
5 |
6 | export let ctx: ConfigCtx = {
7 | middleware: {
8 | logger: isDev,
9 | diffLogger: true,
10 | effect: false,
11 | perf: isDev,
12 | skipNestLog: true,
13 | skipNestPerfLog: true,
14 | },
15 | timeTravel: {
16 | isActive: false,
17 | isNeedRecord: false,
18 | maxStepNumber: 20,
19 | keepActionChain: isDev,
20 | },
21 | disableReactive: false,
22 | strictMode: isDev,
23 | devTool: false,
24 | batchUpdateOnFinish: undefined,
25 | };
26 |
27 | /**
28 | * framework global config method.
29 | */
30 | export function config(conf: Partial) {
31 | ctx = deepMerge(ctx, conf);
32 | }
33 |
--------------------------------------------------------------------------------
/packages/reactivity/src/const/enums.ts:
--------------------------------------------------------------------------------
1 | export enum EDepState {
2 | NOT_OBSERVED = 'notObserved',
3 | OBSERVED = 'observed',
4 | LATEST = 'latest',
5 | }
6 |
7 | export enum ESpecialReservedKey {
8 | ARRAY_LENGTH = 'length',
9 | ITERATE = 'iterate',
10 | COMPUTED = 'computed',
11 | }
12 |
13 | export enum ECollectType {
14 | SET = 'set',
15 | MAP_SET = 'map-set',
16 | ADD = 'add',
17 | SET_ADD = 'set-add',
18 | DELETE = 'delete',
19 | MAP_DELETE = 'map-delete',
20 | SET_DELETE = 'set-delete',
21 | }
22 |
23 | export enum EMaterialType {
24 | DEFAULT = 'default',
25 | MUTATION = 'mutation',
26 | ACTION = 'action',
27 | UPDATE = 'update',
28 | EFFECT = 'effect',
29 | UNDO = 'undo',
30 | REDO = 'redo',
31 | }
32 |
33 | export enum ActionStatus {
34 | WORKING = 'working',
35 | COMPLETED = 'completed',
36 | ABORT = 'abort',
37 | }
38 |
--------------------------------------------------------------------------------
/packages/reactivity/src/const/symbol.ts:
--------------------------------------------------------------------------------
1 | import { isSupportSymbol } from '@turbox3d/shared';
2 |
3 | export const TURBOX_PREFIX = '@@TURBOX__';
4 |
5 | export function compatibleSymbol(key: string) {
6 | return isSupportSymbol() ? Symbol(key) : `${TURBOX_PREFIX}${key}`;
7 | }
8 |
9 | export const NAMESPACE = compatibleSymbol('namespace');
10 | export const REACTIVE_COMPONENT_NAME = compatibleSymbol('reactive-component-name');
11 | export const UNSUBSCRIBE_HANDLER = compatibleSymbol('unsubscribe-handler');
12 | export const MATERIAL_TYPE = `${TURBOX_PREFIX}materialType`;
13 | export const EMPTY_ACTION_NAME = `${TURBOX_PREFIX}empty`;
14 | export const DEFAULT_FIELD_NAME = `${TURBOX_PREFIX}field`;
15 |
--------------------------------------------------------------------------------
/packages/reactivity/src/core/use.ts:
--------------------------------------------------------------------------------
1 | import { compose, fail } from '@turbox3d/shared';
2 | import { Middleware, Store } from '../interfaces';
3 | import { Action } from './action';
4 | import { actionTypeChain } from './store';
5 | import { depCollector } from './collector';
6 |
7 | export const middlewares: Array = [];
8 |
9 | /**
10 | * Add middleware.
11 | */
12 | export function use(middleware: Middleware | Array, inner = true) {
13 | const arr = Array.isArray(middleware) ? middleware : [middleware];
14 | if (inner) {
15 | middlewares.unshift(...arr);
16 | } else {
17 | middlewares.push(...arr);
18 | }
19 | }
20 |
21 | export function applyMiddleware() {
22 | return (createStore: any): Store => {
23 | const store = createStore();
24 | let dispatch: any = () => {
25 | fail('Dispatching while constructing your middleware is not allowed. ' +
26 | 'Other middleware would not be applied to this dispatch.');
27 | };
28 | const exposedMethod = {
29 | getActionChain: () => {
30 | if (Action.context) {
31 | return Action.context.historyNode.actionChain.slice();
32 | }
33 | return actionTypeChain.slice();
34 | },
35 | getDependencyGraph: () => new Map(depCollector.dependencyGraph),
36 | dispatch: (...args: any[]) => dispatch(...args),
37 | };
38 | const runnerChain = middlewares.map(middleware => middleware(exposedMethod));
39 |
40 | dispatch = compose(...runnerChain)(store.dispatch);
41 |
42 | return {
43 | ...store,
44 | dispatch,
45 | };
46 | };
47 | }
48 |
--------------------------------------------------------------------------------
/packages/reactivity/src/index.ts:
--------------------------------------------------------------------------------
1 | import { use } from './core/use';
2 | import { config } from './const/config';
3 | import { mutation } from './decorators/mutation';
4 | // import { effect } from './decorators/effect';
5 | import { reactor } from './decorators/reactor';
6 | import { computed } from './decorators/computed';
7 | import { Domain, createDomain } from './core/domain';
8 | import { init } from './core/init';
9 | import { reactive, Reaction } from './core/reactive';
10 | import { TimeTravel } from './core/time-travel';
11 | import { ActionStatus } from './const/enums';
12 | import { Action } from './core/action';
13 | import { action } from './decorators/action';
14 | import { depCollector } from './core/collector';
15 | import { store, registerExternalBatchUpdate } from './core/store';
16 | import { REACTIVE_COMPONENT_NAME, UNSUBSCRIBE_HANDLER } from './const/symbol';
17 |
18 | export * from './utils/event';
19 | export * from './interfaces';
20 |
21 | init();
22 |
23 | export {
24 | reactive,
25 | // effect,
26 | mutation,
27 | computed,
28 | use,
29 | config,
30 | reactor,
31 | init,
32 | Domain,
33 | createDomain,
34 | TimeTravel,
35 | Action,
36 | ActionStatus,
37 | action,
38 | depCollector,
39 | Reaction,
40 | store,
41 | REACTIVE_COMPONENT_NAME,
42 | UNSUBSCRIBE_HANDLER,
43 | registerExternalBatchUpdate,
44 | };
45 |
--------------------------------------------------------------------------------
/packages/reactivity/src/middlewares/common.ts:
--------------------------------------------------------------------------------
1 | import { isPromise } from '@turbox3d/shared';
2 | import { DispatchedAction, Dispatch } from '../interfaces';
3 |
4 | export function normalNextReturn(next: Dispatch, dispatchedAction: DispatchedAction, callback?: () => void, errorCallback?: (error: string) => void) {
5 | const result = next(dispatchedAction);
6 | if (isPromise(result)) {
7 | return new Promise((resolve, reject) => {
8 | (result as Promise).then((res) => {
9 | callback && callback();
10 | resolve(res);
11 | }).catch((error: Error) => {
12 | errorCallback && errorCallback(error.stack || error.message);
13 | reject(error);
14 | });
15 | });
16 | }
17 | if (result && result instanceof Error) {
18 | errorCallback && errorCallback(result.stack || result.message);
19 | } else {
20 | callback && callback();
21 | }
22 | return result;
23 | }
24 |
--------------------------------------------------------------------------------
/packages/reactivity/src/middlewares/effect.ts:
--------------------------------------------------------------------------------
1 | // import { Effect, Middleware } from '../interfaces';
2 | // import { actionTypeChain } from '../core/store';
3 | // import { invariant } from '../utils/error';
4 | // import { EMaterialType } from '../const/enums';
5 | // import { Action } from '../core/action';
6 | // import { materialCallStack } from '../core/domain';
7 | // import { normalNextReturn } from './common';
8 |
9 | // function createEffectMiddleware(): Middleware {
10 | // return () => (next) => (dispatchedAction) => {
11 | // const { name, displayName, payload, type, original, action } = dispatchedAction;
12 |
13 | // if (type === EMaterialType.EFFECT) {
14 | // const length = materialCallStack.length;
15 | // if (length > 1) {
16 | // invariant(materialCallStack[length - 2] !== EMaterialType.MUTATION, 'Cannot trigger other effect while the current mutation is executing.');
17 | // }
18 |
19 | // const effect = original as Effect;
20 | // actionTypeChain.push({
21 | // name,
22 | // displayName,
23 | // });
24 |
25 | // return new Promise((resolve) => {
26 | // effect(action as Action, ...payload).then(() => {
27 | // resolve();
28 | // });
29 | // });
30 | // }
31 |
32 | // return normalNextReturn(next, dispatchedAction);
33 | // }
34 | // }
35 |
36 | // export default createEffectMiddleware();
37 |
--------------------------------------------------------------------------------
/packages/reactivity/src/middlewares/mutation.ts:
--------------------------------------------------------------------------------
1 | import { Middleware } from '../interfaces';
2 | import { actionTypeChain } from '../core/store';
3 | import { EMaterialType } from '../const/enums';
4 | import { Action } from '../core/action';
5 | import { normalNextReturn } from './common';
6 |
7 | function createMutationMiddleware(): Middleware {
8 | return () => next => (dispatchedAction) => {
9 | const { name, displayName, type, isInner } = dispatchedAction;
10 | if (isInner || (type !== EMaterialType.MUTATION && type !== EMaterialType.UPDATE)) {
11 | return normalNextReturn(next, dispatchedAction);
12 | }
13 |
14 | if (Action.context) {
15 | Action.context.historyNode.actionChain.push({
16 | name,
17 | displayName,
18 | });
19 | } else {
20 | actionTypeChain.push({
21 | name,
22 | displayName,
23 | });
24 | }
25 |
26 | return normalNextReturn(next, dispatchedAction);
27 | };
28 | }
29 |
30 | export default createMutationMiddleware();
31 |
--------------------------------------------------------------------------------
/packages/reactivity/src/middlewares/perf.ts:
--------------------------------------------------------------------------------
1 | import { Middleware } from '../interfaces';
2 | import { normalNextReturn } from './common';
3 | import { EMPTY_ACTION_NAME } from '../const/symbol';
4 | import { ctx } from '../const/config';
5 | import { materialCallStack } from '../utils/materialCallStack';
6 |
7 | function createPerfMiddleware(): Middleware {
8 | return () => next => (dispatchedAction) => {
9 | if (!ctx.middleware.perf) {
10 | return normalNextReturn(next, dispatchedAction);
11 | }
12 | const { name, displayName } = dispatchedAction;
13 | const start = performance.now();
14 |
15 | const length = materialCallStack.stack.length;
16 | if (ctx.middleware.skipNestPerfLog && length !== 1) {
17 | return normalNextReturn(next, dispatchedAction);
18 | }
19 |
20 | return normalNextReturn(next, dispatchedAction, () => {
21 | const end = performance.now();
22 | console.log(
23 | `%c[TURBOX PERF]: ${name} ${displayName !== EMPTY_ACTION_NAME ? displayName : ''} ${(end - start).toFixed(3)}ms`,
24 | 'background: #FA54FF; color: #fff; font-weight: bold; padding: 3px 5px;',
25 | );
26 | });
27 | };
28 | }
29 |
30 | export default createPerfMiddleware();
31 |
--------------------------------------------------------------------------------
/packages/reactivity/src/utils/common.ts:
--------------------------------------------------------------------------------
1 | import { Domain } from '../core/domain';
2 |
3 | export function isDomain(value: any): boolean {
4 | return value instanceof Domain;
5 | }
6 |
--------------------------------------------------------------------------------
/packages/reactivity/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/reactivity/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/renderer-core/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/renderer-core/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/renderer-core/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/renderer-core/src/__tests__/render.test.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '../component';
2 |
3 | describe('render', () => {
4 | it('render', () => {
5 | class A extends Component {
6 | render() {
7 | return [];
8 | }
9 | }
10 | class B extends Component {
11 | render() {
12 | return [];
13 | }
14 | }
15 | class Root extends Component {
16 | render() {
17 | return [
18 | {
19 | component: A,
20 | props: {},
21 | },
22 | {
23 | component: B,
24 | props: {},
25 | },
26 | ];
27 | }
28 | }
29 | });
30 | });
31 |
--------------------------------------------------------------------------------
/packages/renderer-core/src/common.ts:
--------------------------------------------------------------------------------
1 | export const IdCustomType = 'renderer';
2 |
3 | export enum NodeStatus {
4 | READY = 1,
5 | UPDATE = 2,
6 | UPDATE_INTERACTIVE = 4,
7 | UPDATE_CUSTOM_PROPS = 8,
8 | FAKE_UPDATE = 16,
9 | REMOVE = 32,
10 | CREATE = 64,
11 | }
12 |
13 | export enum NodeTag {
14 | COMPONENT = 1,
15 | SCENE = 2,
16 | MESH = 3,
17 | }
18 |
--------------------------------------------------------------------------------
/packages/renderer-core/src/index.ts:
--------------------------------------------------------------------------------
1 | import { init, registerExternalBatchUpdate } from '@turbox3d/reactivity';
2 | import { Component, PureComponent, ComponentProps } from './component';
3 | import { Element, VirtualNode, render, batchUpdate, ElementSchema, g } from './render';
4 | import { IdCustomType } from './common';
5 | import { Reactive } from './reactive';
6 | import { BaseMesh } from './mesh';
7 | import { BaseScene, SceneContext, BaseSceneProps, ViewportInfo, ViewInfo, SceneType } from './scene';
8 |
9 | init();
10 | registerExternalBatchUpdate({
11 | handler: batchUpdate,
12 | idCustomType: IdCustomType,
13 | });
14 |
15 | export {
16 | Component,
17 | PureComponent,
18 | Element,
19 | ElementSchema,
20 | VirtualNode,
21 | render,
22 | g,
23 | batchUpdate,
24 | Reactive,
25 | BaseMesh,
26 | SceneContext,
27 | BaseScene,
28 | BaseSceneProps,
29 | ViewportInfo,
30 | ViewInfo,
31 | SceneType,
32 | ComponentProps,
33 | };
34 |
--------------------------------------------------------------------------------
/packages/renderer-core/src/utils.ts:
--------------------------------------------------------------------------------
1 | import { Component } from './component';
2 | import { NodeTag } from './common';
3 |
4 | /**
5 | * 找寻类型为 BaseMesh | BaseScene 的上层组件
6 | * @param component
7 | */
8 | export function getMeshParent(component: Component) {
9 | const vNode = component._vNode;
10 |
11 | if (!vNode) {
12 | return;
13 | }
14 |
15 | let parent = vNode.parent;
16 |
17 | while (parent) {
18 | if (parent && (parent.tag === NodeTag.SCENE || parent.tag === NodeTag.MESH)) {
19 | return parent.instance;
20 | }
21 |
22 | parent = parent.parent;
23 | }
24 | }
25 |
26 | export function getSceneParent(component: Component) {
27 | const vNode = component._vNode;
28 |
29 | if (!vNode) {
30 | return;
31 | }
32 |
33 | let parent = vNode.parent;
34 |
35 | while (parent) {
36 | if (parent && parent.tag === NodeTag.SCENE) {
37 | return parent.instance;
38 | }
39 |
40 | parent = parent.parent;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/packages/renderer-core/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/renderer-core/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/renderer-pixi/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/renderer-pixi/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/renderer-pixi/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/renderer-pixi/src/Mesh2D/Mesh2D.ts:
--------------------------------------------------------------------------------
1 | import { BaseMesh, ComponentProps } from '@turbox3d/renderer-core';
2 | import { Vec2, warn } from '@turbox3d/shared';
3 | import * as PIXI from 'pixi.js';
4 |
5 | export abstract class Mesh2D extends BaseMesh {
6 | constructor(props = {} as ComponentProps) {
7 | super(props);
8 | if (this.view instanceof PIXI.Container) {
9 | this.view.sortableChildren = true;
10 | }
11 | }
12 |
13 | createDefaultView() {
14 | return new PIXI.Container();
15 | }
16 |
17 | addChildView(view: PIXI.DisplayObject) {
18 | if (this.view instanceof PIXI.Container) {
19 | this.view.addChild(view);
20 | }
21 | }
22 |
23 | clearView() {
24 | if (this.view instanceof PIXI.Graphics) {
25 | this.view.clear();
26 | }
27 | }
28 |
29 | removeFromWorld() {
30 | // 这里有可能因为父节点中主动触发了子节点的 destroy 方法,而导致无需在调用 destroy .(重复调用会报错)
31 | try {
32 | if (this.view instanceof PIXI.Container) {
33 | this.view.destroy({ children: false });
34 | } else {
35 | this.view.destroy();
36 | }
37 | } catch (e) {
38 | // 如果异常,也是该节点已经被卸载了,无需理会
39 | warn('destroy error');
40 | }
41 | }
42 |
43 | setViewInteractive(interactive: boolean) {
44 | this.view.eventMode = interactive ? 'static' : 'auto';
45 | }
46 |
47 | addViewToScene() {
48 | //
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/packages/renderer-pixi/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh2D } from './Mesh2D/Mesh2D';
2 | import { Scene2D, Scene2DSymbol } from './Scene2D/index';
3 |
4 | export * from '@turbox3d/renderer-core';
5 | export {
6 | Mesh2D,
7 | Scene2D,
8 | Scene2DSymbol,
9 | };
10 |
--------------------------------------------------------------------------------
/packages/renderer-pixi/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/renderer-pixi/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/renderer-three/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/renderer-three/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/renderer-three/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/renderer-three/src/Mesh3D/Mesh3D.ts:
--------------------------------------------------------------------------------
1 | import * as THREE from 'three';
2 | import { BaseMesh, ComponentProps } from '@turbox3d/renderer-core';
3 | import { Vec2 } from '@turbox3d/shared';
4 | import { Scene3D } from '../Scene3D/index';
5 |
6 | export abstract class Mesh3D extends BaseMesh {
7 | constructor(props = {} as ComponentProps) {
8 | super(props);
9 | }
10 |
11 | createDefaultView() {
12 | return new THREE.Group();
13 | }
14 |
15 | addChildView(view: THREE.Object3D) {
16 | this.view.add(view);
17 | }
18 |
19 | clearView() {
20 | // if (this.view instanceof THREE.Mesh) {
21 | // this.view.clear();
22 | // }
23 | }
24 |
25 | removeFromWorld() {
26 | this.view.removeFromParent();
27 | }
28 |
29 | setViewInteractive(interactive: boolean) {
30 | this.view.userData.interactive = interactive;
31 | }
32 |
33 | addViewToScene(scene3d: Scene3D, view: THREE.Object3D) {
34 | scene3d.scene!.add(view);
35 | const isCamera = this.viewType === 'camera';
36 | if (isCamera) {
37 | scene3d.camera = view as THREE.Camera;
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/packages/renderer-three/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Mesh3D } from './Mesh3D/Mesh3D';
2 | import { Scene3D, Scene3DSymbol } from './Scene3D/index';
3 |
4 | export * from '@turbox3d/renderer-core';
5 | export {
6 | Mesh3D,
7 | Scene3D,
8 | Scene3DSymbol,
9 | };
10 |
--------------------------------------------------------------------------------
/packages/renderer-three/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/renderer-three/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/shared/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/shared/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/shared/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/shared/src/__tests__/compose.test.ts:
--------------------------------------------------------------------------------
1 | import { compose } from '../compose';
2 |
3 | describe('utils -> compose', () => {
4 | it('compose', () => {
5 | const original = param => `original${param}`;
6 | const middlewares = [(next) => (param) => {
7 | console.log('111');
8 | return next(param);
9 | }, (next) => (param) => {
10 | console.log('222');
11 | return next(param);
12 | }, (next) => (param) => {
13 | console.log('333');
14 | return next(param);
15 | }];
16 | const enhanced = compose(...middlewares)(original);
17 | expect(enhanced('test')).toBe('originaltest');
18 | });
19 |
20 | it('compose one middleware', () => {
21 | const original = param => `original${param}`;
22 | const middlewares = [(next) => (param) => {
23 | console.log('111');
24 | return next(param);
25 | }];
26 | const enhanced = compose(...middlewares)(original);
27 | expect(enhanced('test')).toBe('originaltest');
28 | });
29 |
30 | it('compose no middleware', () => {
31 | const original = param => `original${param}`;
32 | const middlewares = [];
33 | const enhanced = compose(...middlewares)(original);
34 | expect(enhanced('test')).toBe('originaltest');
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/packages/shared/src/__tests__/lang.test.ts:
--------------------------------------------------------------------------------
1 | import { isReserved, isSymbol } from '../lang';
2 |
3 | describe('utils -> lang', () => {
4 | it('isReserved', () => {
5 | expect(isReserved('$global')).toBeTruthy();
6 | });
7 |
8 | it('isSymbol', () => {
9 | expect(isSymbol(Symbol('sss'))).toBeTruthy();
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/packages/shared/src/compose.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * from redux compose
3 | */
4 | export function compose(...funcs: any[]) {
5 | if (funcs.length === 0) {
6 | return arg => arg;
7 | }
8 |
9 | if (funcs.length === 1) {
10 | return funcs[0];
11 | }
12 |
13 | return funcs.reduce((a, b) => (...args) => a(b(...args)));
14 | }
15 |
--------------------------------------------------------------------------------
/packages/shared/src/decorator.ts:
--------------------------------------------------------------------------------
1 | import { toObjectTypeString, stateDecoRegExp } from './lang';
2 |
3 | export function quacksLikeADecorator(args: any[]): boolean {
4 | return (args.length === 2 || args.length === 3) && typeof args[1] === 'string';
5 | }
6 |
7 | // prop could be decorated by @reactor
8 | export const canObserve = (value: any): boolean => stateDecoRegExp.test(toObjectTypeString(value));
9 |
--------------------------------------------------------------------------------
/packages/shared/src/error.ts:
--------------------------------------------------------------------------------
1 | export const OBFUSCATED_ERROR =
2 | 'An invariant failed, however the error is obfuscated because this is an production build.';
3 |
4 | export function invariant(check: boolean, message?: string | boolean) {
5 | if (!check) throw new Error(`[turbox]: ${message || OBFUSCATED_ERROR}`);
6 | }
7 |
8 | export function fail(message: string | boolean): never {
9 | invariant(false, message);
10 | // eslint-disable-next-line no-throw-literal
11 | throw 'X';
12 | }
13 |
14 | export function warn(message: string | boolean) {
15 | console.warn(`[turbox]: ${message}`);
16 | }
17 |
--------------------------------------------------------------------------------
/packages/shared/src/event.ts:
--------------------------------------------------------------------------------
1 | class Emitter {
2 | private listeners = {};
3 |
4 | on(eventName: string, callback: (...args: any[]) => void) {
5 | const listeners = this.listeners[eventName] || [];
6 | listeners.push(callback);
7 | this.listeners[eventName] = listeners;
8 | }
9 |
10 | emit(eventName: string, ...args: any[]) {
11 | const listeners = this.listeners[eventName];
12 | if (!Array.isArray(listeners)) return;
13 | listeners.forEach((callback) => {
14 | try {
15 | callback.apply(this, args);
16 | } catch (e) {
17 | console.error(e);
18 | }
19 | });
20 | }
21 |
22 | off(eventName: string) {
23 | if (!this.listeners[eventName]) {
24 | return;
25 | }
26 | this.listeners[eventName] = [];
27 | }
28 | }
29 |
30 | export const emitter = new Emitter();
31 |
--------------------------------------------------------------------------------
/packages/shared/src/graphic.ts:
--------------------------------------------------------------------------------
1 | export interface Vec2 {
2 | x: number;
3 | y: number;
4 | }
5 |
6 | export interface Vec3 {
7 | x: number;
8 | y: number;
9 | z: number;
10 | }
11 |
12 | /** 判断点是否在矩形内 */
13 | export function pointInRect(p: Vec2, rect: Vec2[]) {
14 | const [r1, r2] = rect;
15 | const c1 = (p.x - r1.x) * (p.x - r2.x);
16 | const c2 = (p.y - r1.y) * (p.y - r2.y);
17 | return c1 <= 0 && c2 <= 0;
18 | }
19 |
20 | interface ICanvasRect {
21 | width: number;
22 | height: number;
23 | x: number;
24 | y: number;
25 | }
26 |
27 | /**
28 | * 获得点击位置相对于 canvas 的坐标
29 | * 如果输入参数不合法,或点击位置超出 canvas 的 clientRect 则返回 undefined
30 | * @param vec 事件坐标
31 | * @param canvas 要接受的 canvas 对象
32 | */
33 | export function getRelativePositionFromEvent(vec: Vec2, rect: ICanvasRect) {
34 | const point = {
35 | x: vec.x - rect.x,
36 | y: vec.y - rect.y,
37 | };
38 | if (point.x <= 0 || point.y <= 0 || point.x > rect.width || point.y > rect.height) {
39 | return undefined;
40 | }
41 | return point;
42 | }
43 |
--------------------------------------------------------------------------------
/packages/shared/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './uuid';
2 | export * from './type';
3 | export * from './task';
4 | export * from './rafTask';
5 | export * from './lang';
6 | export * from './image';
7 | export * from './graphic';
8 | export * from './event';
9 | export * from './error';
10 | export * from './deep-merge';
11 | export * from './decorator';
12 | export * from './debounce';
13 | export * from './compose';
14 | export * from './common';
15 |
--------------------------------------------------------------------------------
/packages/shared/src/lang.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * Check if a string starts with $ or _
3 | */
4 | export function isReserved(str: string): boolean {
5 | const c = (`${str}`).charCodeAt(0);
6 | return c === 0x24 || c === 0x5F;
7 | }
8 |
9 | export function isSupportProxy(): boolean {
10 | return typeof Proxy !== 'undefined';
11 | }
12 |
13 | export function isSymbol(symbol: any): boolean {
14 | return typeof symbol === 'symbol';
15 | }
16 |
17 | export function isSupportSymbol(): boolean {
18 | return typeof Symbol !== 'undefined';
19 | }
20 |
21 | export const toObjectTypeString = (value: any): string => Object.prototype.toString.call(value);
22 |
23 | export const stateDecoRegExp = /^\[object (?:Object|Array|Map|Set|WeakMap|WeakSet)\]$/;
24 |
--------------------------------------------------------------------------------
/packages/shared/src/task.ts:
--------------------------------------------------------------------------------
1 | class Task {
2 | static createTask(fn: Function, priority: number) {
3 | return new Task(fn, priority);
4 | }
5 |
6 | fn: Function;
7 | priority: number;
8 |
9 | constructor(fn: Function, priority: number) {
10 | this.fn = fn;
11 | this.priority = priority;
12 | }
13 | }
14 |
15 | export { Task };
16 |
--------------------------------------------------------------------------------
/packages/shared/src/type.ts:
--------------------------------------------------------------------------------
1 | export interface IConstructorOf {
2 | new(...args: any[]): T;
3 | }
4 |
5 | export interface IMapOf {
6 | [key: string]: T;
7 | }
8 |
9 | export type Nullable = { [K in keyof T]?: T[K] | null };
10 |
11 | export function getValue(obj: T, key: K): T[K] {
12 | return obj[key];
13 | }
14 |
15 | export interface IDictionary {
16 | [index: string]: T;
17 | }
18 |
19 | export interface INumericDictionary {
20 | [index: number]: T;
21 | }
22 |
--------------------------------------------------------------------------------
/packages/shared/src/uuid.ts:
--------------------------------------------------------------------------------
1 | const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
2 | const uuid = new Array(36);
3 |
4 | /**
5 | * Generates uuid
6 | */
7 | export function generateUUID(): string {
8 | let rnd = 0;
9 | for (let i = 0; i < 36; i++) {
10 | if (i === 8 || i === 13 || i === 18 || i === 23) {
11 | uuid[i] = '-';
12 | } else if (i === 14) {
13 | uuid[i] = '7';
14 | } else {
15 | if (rnd <= 0x02) {
16 | rnd = 0x2000000 + (Math.random() * 0x1000000) | 0;
17 | }
18 | const r = rnd & 0xf;
19 | rnd >>= 4;
20 | uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r];
21 | }
22 | }
23 | return uuid.join('');
24 | }
25 |
--------------------------------------------------------------------------------
/packages/shared/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/shared/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/turbox/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/turbox/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/turbox/README.md:
--------------------------------------------------------------------------------
1 | # 标准化通用项目
2 |
--------------------------------------------------------------------------------
/packages/turbox/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/turbox/src/__tests__/index.test.ts:
--------------------------------------------------------------------------------
1 | describe('test', () => {
2 | it('test', () => {
3 | expect(true).toBeTruthy();
4 | });
5 | });
6 |
--------------------------------------------------------------------------------
/packages/turbox/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Reactive as ReactiveReact } from '@turbox3d/reactivity-react';
2 |
3 | export * from '@turbox3d/command-manager';
4 | export * from '@turbox3d/design-engine';
5 | export * from '@turbox3d/event-manager';
6 | export * from '@turbox3d/graphic-component-pixi';
7 | export * from '@turbox3d/graphic-component-three';
8 | export * from '@turbox3d/math';
9 | export * from '@turbox3d/reactivity';
10 | export { ReactiveReact };
11 | export * from '@turbox3d/renderer-core';
12 | export * from '@turbox3d/renderer-pixi';
13 | export * from '@turbox3d/renderer-three';
14 |
--------------------------------------------------------------------------------
/packages/turbox/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/turbox/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/turbox2d/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/turbox2d/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/turbox2d/README.md:
--------------------------------------------------------------------------------
1 | # 标准化通用项目
2 |
--------------------------------------------------------------------------------
/packages/turbox2d/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/turbox2d/src/__tests__/index.test.ts:
--------------------------------------------------------------------------------
1 | describe('test', () => {
2 | it('test', () => {
3 | expect(true).toBeTruthy();
4 | });
5 | });
6 |
--------------------------------------------------------------------------------
/packages/turbox2d/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Reactive as ReactiveReact } from '@turbox3d/reactivity-react';
2 |
3 | export * from '@turbox3d/command-manager';
4 | export * from '@turbox3d/design-engine';
5 | export * from '@turbox3d/event-manager';
6 | export * from '@turbox3d/graphic-component-pixi';
7 | export * from '@turbox3d/math';
8 | export * from '@turbox3d/reactivity';
9 | export { ReactiveReact };
10 | export * from '@turbox3d/renderer-core';
11 | export * from '@turbox3d/renderer-pixi';
12 |
--------------------------------------------------------------------------------
/packages/turbox2d/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/turbox2d/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/turbox3d/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/packages/turbox3d/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/packages/turbox3d/README.md:
--------------------------------------------------------------------------------
1 | # 标准化通用项目
2 |
--------------------------------------------------------------------------------
/packages/turbox3d/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/packages/turbox3d/src/__tests__/index.test.ts:
--------------------------------------------------------------------------------
1 | describe('test', () => {
2 | it('test', () => {
3 | expect(true).toBeTruthy();
4 | });
5 | });
6 |
--------------------------------------------------------------------------------
/packages/turbox3d/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Reactive as ReactiveReact } from '@turbox3d/reactivity-react';
2 |
3 | export * from '@turbox3d/command-manager';
4 | export * from '@turbox3d/design-engine';
5 | export * from '@turbox3d/event-manager';
6 | export * from '@turbox3d/graphic-component-three';
7 | export * from '@turbox3d/math';
8 | export * from '@turbox3d/reactivity';
9 | export { ReactiveReact };
10 | export * from '@turbox3d/renderer-core';
11 | export * from '@turbox3d/renderer-three';
12 |
--------------------------------------------------------------------------------
/packages/turbox3d/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/turbox3d/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/plugins/turbox-dev-tool/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/plugins/turbox-dev-tool/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/plugins/turbox-dev-tool/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # @turbox3d/turbox-dev-tool
2 |
3 | ## 1.0.22
4 |
5 | ### Patch Changes
6 |
7 | - fix: enhance gizmo2d&text2d
8 |
9 | ## 1.0.21
10 |
11 | ### Patch Changes
12 |
13 | - fix: fix issue
14 |
15 | ## 1.0.20
16 |
17 | ### Patch Changes
18 |
19 | - fix: fix dep version
20 |
21 | ## 1.0.19
22 |
23 | ### Patch Changes
24 |
25 | - feat: add inference engine&fix rect2d&add line2d&add keyup hot key feature
26 |
27 | ## 1.0.18
28 |
29 | ### Patch Changes
30 |
31 | - fix: fix build issue
32 |
33 | ## 1.0.17
34 |
35 | ### Patch Changes
36 |
37 | - fix: update version
38 |
39 | ## 1.0.16
40 |
41 | ### Patch Changes
42 |
43 | - f188584: Fix build script
44 |
45 | ## 1.0.15
46 |
47 | ### Patch Changes
48 |
49 | - Sync code
50 |
51 | ## 1.0.14
52 |
53 | ### Patch Changes
54 |
55 | - Upgrade deps: pixi.js->v7,three->v0.159,react->v18,react-dom->v18,typescript->v5
56 |
57 | ## 1.0.13
58 |
59 | ### Patch Changes
60 |
61 | - Move dts file to dist
62 |
63 | ## 1.0.12
64 |
65 | ### Patch Changes
66 |
67 | - Update build script&config file
68 |
69 | ## 1.0.11
70 |
71 | ### Patch Changes
72 |
73 | - Add doc gen building process
74 |
75 | ## 1.0.10
76 |
77 | ### Patch Changes
78 |
79 | - Upgrade react version
80 |
81 | ## 1.0.9
82 |
83 | ### Patch Changes
84 |
85 | - Lint change
86 |
87 | ## 1.0.8
88 |
89 | ### Patch Changes
90 |
91 | - Replace pnpm from lerna
92 |
--------------------------------------------------------------------------------
/plugins/turbox-dev-tool/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/plugins/turbox-dev-tool/src/fps-monitor/fps.ts:
--------------------------------------------------------------------------------
1 | export class FPSMonitor {
2 | costTimes: number[] = [];
3 | prevTime?: number;
4 | raf?: number;
5 | maxFPS = 120;
6 |
7 | getAverageCostTimePerFrame() {
8 | const length = this.costTimes.length;
9 | if (!length) {
10 | return 0;
11 | }
12 | return this.costTimes.reduce((prev, current) => prev + current, 0) / length;
13 | }
14 |
15 | record(costTime: number) {
16 | this.costTimes.push(costTime);
17 | if (this.costTimes.length > this.maxFPS) {
18 | this.costTimes.shift();
19 | }
20 | }
21 |
22 | start(maxFPS = 120) {
23 | this.maxFPS = maxFPS;
24 | this.end();
25 | if (this.maxFPS === 60) {
26 | this.raf = requestAnimationFrame(this.monitor);
27 | } else {
28 | this.raf = window.setTimeout(this.monitor, 1000 / this.maxFPS);
29 | }
30 | }
31 |
32 | end() {
33 | if (this.maxFPS === 60) {
34 | this.raf && cancelAnimationFrame(this.raf);
35 | } else {
36 | this.raf && window.clearTimeout(this.raf);
37 | }
38 | this.costTimes = [];
39 | this.prevTime = void 0;
40 | this.maxFPS = 120;
41 | }
42 |
43 | monitor = () => {
44 | const now = performance.now();
45 | if (this.prevTime !== void 0) {
46 | this.record(now - this.prevTime);
47 | }
48 | this.prevTime = now;
49 | if (this.maxFPS === 60) {
50 | this.raf = requestAnimationFrame(this.monitor);
51 | } else {
52 | this.raf = window.setTimeout(this.monitor, 1000 / this.maxFPS);
53 | }
54 | }
55 |
56 | getFPS() {
57 | return Math.ceil(1000 / this.getAverageCostTimePerFrame());
58 | }
59 | }
60 |
61 | export const fpsMonitor = new FPSMonitor();
62 |
--------------------------------------------------------------------------------
/plugins/turbox-dev-tool/src/fps-monitor/index.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 | import { fpsMonitor } from './fps';
3 |
4 | interface IProp {
5 | className?: string;
6 | }
7 |
8 | interface IState {
9 | fps: number;
10 | }
11 |
12 | export class FPSMonitorComponent extends React.Component {
13 | state = {
14 | fps: 0,
15 | };
16 | private interval?: number;
17 |
18 | componentDidMount() {
19 | fpsMonitor.start();
20 | this.interval = window.setInterval(() => {
21 | this.setState({
22 | fps: fpsMonitor.getFPS(),
23 | });
24 | }, 1000);
25 | }
26 |
27 | componentWillUnmount() {
28 | fpsMonitor.end();
29 | this.interval && window.clearInterval(this.interval);
30 | }
31 |
32 | render() {
33 | const { className } = this.props;
34 | let color: string;
35 | if (this.state.fps >= 40) {
36 | color = '#00cc00';
37 | } else if (this.state.fps >= 20) {
38 | color = '#fdea42';
39 | } else {
40 | color = '#ff0000';
41 | }
42 |
43 | return (
44 |
45 | FPS:{this.state.fps}
46 |
47 | );
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/plugins/turbox-dev-tool/src/index.ts:
--------------------------------------------------------------------------------
1 | import { FPSMonitorComponent } from './fps-monitor/index';
2 | import { FPSMonitor } from './fps-monitor/fps';
3 |
4 | export {
5 | FPSMonitorComponent,
6 | FPSMonitor
7 | };
8 |
--------------------------------------------------------------------------------
/plugins/turbox-dev-tool/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/plugins/turbox-dev-tool/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/plugins/turbox-hot-loader/.babelrc.js:
--------------------------------------------------------------------------------
1 | const config = require('../../.babelrc.js');
2 |
3 | module.exports = {
4 | ...config(),
5 | };
6 |
--------------------------------------------------------------------------------
/plugins/turbox-hot-loader/.npmignore:
--------------------------------------------------------------------------------
1 | # npm and yarn
2 | npm-debug.log*
3 | node_modules
4 | .npmrc
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Mac
9 | .DS_Store
10 |
11 | # git
12 | .git
13 |
14 | # Editor directories and files
15 | .idea
16 | .vscode
17 |
--------------------------------------------------------------------------------
/plugins/turbox-hot-loader/jest.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../jest.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/plugins/turbox-hot-loader/src/index.ts:
--------------------------------------------------------------------------------
1 | // @ts-nocheck
2 | import { fail } from './utils';
3 | import { hot as reactComponentHot } from './components/hot';
4 | import { hot as domainHot } from './hot';
5 |
6 | declare global {
7 | interface NodeModule {
8 | i?: string;
9 | parents?: string[];
10 | }
11 | interface Window {
12 | $$turbox_hot: boolean;
13 | }
14 | }
15 |
16 | export let hot;
17 | export let hotDomain: (stores: T) => T;
18 |
19 | if (module.hot) {
20 | const cache = require.cache;
21 | if (!module.parents || module.parents.length === 0) {
22 | fail('`hot` is not supported on your system.');
23 | }
24 | const parent = cache[module.parents[0]];
25 | if (!parent) {
26 | fail('`hot` is not supported on your system.');
27 | }
28 | // remove from cache, trigger create new hot module and update ref
29 | delete cache[module.id];
30 | hot = reactComponentHot(parent);
31 | hotDomain = domainHot(parent);
32 | }
33 |
--------------------------------------------------------------------------------
/plugins/turbox-hot-loader/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | // based on https://github.com/mridgway/hoist-non-react-statics/blob/master/src/index.js
2 | const hoistBlackList = {
3 | $$typeof: true,
4 | render: true,
5 | compare: true,
6 | type: true,
7 | };
8 |
9 | export function copyStaticProperties(base, target) {
10 | const keys = Object.keys(base);
11 | for (let index = 0; index < keys.length; index++) {
12 | const key = keys[index];
13 | if (hoistBlackList[key] === void 0) {
14 | Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(base, key)!);
15 | }
16 | }
17 | }
18 |
19 | export const OBFUSCATED_ERROR =
20 | 'An invariant failed, however the error is obfuscated because this is an production build.';
21 |
22 | export function invariant(check: boolean, message?: string | boolean) {
23 | if (!check) throw new Error(`[turbox]: ${message || OBFUSCATED_ERROR}`);
24 | }
25 |
26 | export function fail(message: string | boolean): never {
27 | invariant(false, message);
28 | // eslint-disable-next-line no-throw-literal
29 | throw 'X';
30 | }
31 |
32 | export function warn(message: string | boolean) {
33 | console.warn(`[turbox]: ${message}`);
34 | }
35 |
36 | export function bind(fn, ctx) {
37 | function boundFn(a?: any) {
38 | const l: number = arguments.length;
39 | // eslint-disable-next-line no-nested-ternary
40 | return l
41 | ? l > 1
42 | // eslint-disable-next-line prefer-rest-params
43 | ? fn.apply(ctx, arguments)
44 | : fn.call(ctx, a)
45 | : fn.call(ctx);
46 | }
47 | return boundFn;
48 | }
49 |
--------------------------------------------------------------------------------
/plugins/turbox-hot-loader/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "declarationDir": "./typings",
5 | "outDir": "./ts"
6 | },
7 | "include": ["src"]
8 | }
9 |
--------------------------------------------------------------------------------
/plugins/turbox-hot-loader/webpack.config.js:
--------------------------------------------------------------------------------
1 | const config = require('../../webpack.config.js');
2 |
3 | module.exports = {
4 | ...config,
5 | };
6 |
--------------------------------------------------------------------------------
/plugins/turbox-snippets/.vscodeignore:
--------------------------------------------------------------------------------
1 | .vscode/**
2 | .vscode-test/**
3 | .gitignore
4 |
--------------------------------------------------------------------------------
/plugins/turbox-snippets/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | ## 1.0.17
4 |
5 | ### Patch Changes
6 |
7 | - fix: fix build issue
8 |
9 | ## 1.0.16
10 |
11 | ### Patch Changes
12 |
13 | - fix: update version
14 |
15 | ## 1.0.15
16 |
17 | ### Patch Changes
18 |
19 | - Update build script&config file
20 |
21 | All notable changes to the "turbox-snippets" extension will be documented in this file.
22 |
23 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file.
24 |
--------------------------------------------------------------------------------
/plugins/turbox-snippets/images/turbox.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/turbox3d/turbox/417d21098c01894dd7403c3e486acf4512c26b40/plugins/turbox-snippets/images/turbox.png
--------------------------------------------------------------------------------
/plugins/turbox-snippets/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "turbox-snippets",
3 | "displayName": "Turbox Snippets",
4 | "version": "1.0.17",
5 | "description": "Code snippets for Turbox",
6 | "author": "feifan ",
7 | "license": "MIT",
8 | "repository": {
9 | "type": "git",
10 | "url": "git+https://github.com/turbox3d/turbox.git"
11 | },
12 | "scripts": {
13 | "deploy": "pnpm exec vsce publish"
14 | },
15 | "publisher": "feifan-gff",
16 | "engines": {
17 | "vscode": "^1.28.0"
18 | },
19 | "categories": [
20 | "Snippets"
21 | ],
22 | "icon": "images/turbox.png",
23 | "contributes": {
24 | "snippets": [
25 | {
26 | "language": "javascript",
27 | "path": "./snippets/snippets.json"
28 | },
29 | {
30 | "language": "javascriptreact",
31 | "path": "./snippets/snippets.json"
32 | },
33 | {
34 | "language": "typescript",
35 | "path": "./snippets/snippets.json"
36 | },
37 | {
38 | "language": "typescriptreact",
39 | "path": "./snippets/snippets.json"
40 | }
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------
1 | packages:
2 | - 'packages/*'
3 | - 'plugins/*'
4 | link-workspace-packages: false
5 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": true,
3 | "compilerOptions": {
4 | "module": "es6",
5 | "noImplicitAny": false,
6 | "declaration": true,
7 | "strictNullChecks": true,
8 | "allowJs": false,
9 | "jsx": "react",
10 | "esModuleInterop": true,
11 | "allowSyntheticDefaultImports": true,
12 | "removeComments": false,
13 | "preserveConstEnums": true,
14 | "experimentalDecorators": true,
15 | "sourceMap": false,
16 | "downlevelIteration": true,
17 | "target": "ES2018",
18 | "moduleResolution": "node",
19 | "resolveJsonModule": true,
20 | "lib": [
21 | "DOM",
22 | "ESNext"
23 | ],
24 | "types": [
25 | "node",
26 | "jest",
27 | "webpack-env"
28 | ],
29 | "skipLibCheck": true
30 | },
31 | "include": [
32 | "packages/**/src/**/*",
33 | "plugins/**/src/**/*"
34 | ],
35 | "exclude": [
36 | "node_modules",
37 | "**/node_modules/**/*",
38 | "**/__tests__/**/*"
39 | ]
40 | }
41 |
--------------------------------------------------------------------------------
/typedoc.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://typedoc.org/schema.json",
3 | "includeVersion": true,
4 | "out": "./typedocs"
5 | }
6 |
--------------------------------------------------------------------------------