Feature/runtime cdn and plugin loader (#240)
* feat(ui): 完善 UI 布局系统和编辑器可视化工具 * refactor: 移除 ModuleRegistry,统一使用 PluginManager 插件系统 * fix: 修复 CodeQL 警告并提升测试覆盖率 * refactor: 分离运行时入口点,解决 runtime bundle 包含 React 的问题 * fix(ci): 添加 editor-core 和 editor-runtime 到 CI 依赖构建步骤 * docs: 完善 ServiceContainer 文档,新增 Symbol.for 模式和 @InjectProperty 说明 * fix(ci): 修复 type-check 失败问题 * fix(ci): 修复类型检查失败问题 * fix(ci): 修复类型检查失败问题 * fix(ci): behavior-tree 构建添加 @tauri-apps 外部依赖 * fix(ci): behavior-tree 添加 @tauri-apps/plugin-fs 类型依赖 * fix(ci): platform-web 添加缺失的 behavior-tree 依赖 * fix(lint): 移除正则表达式中不必要的转义字符
This commit is contained in:
@@ -1,216 +0,0 @@
|
||||
import { React, useRef, useCallback, forwardRef, useState, useEffect } from '@esengine/editor-runtime';
|
||||
import { useCanvasInteraction } from '../../hooks/useCanvasInteraction';
|
||||
import { EditorConfig } from '../../types';
|
||||
import { GridBackground } from './GridBackground';
|
||||
|
||||
/**
|
||||
* 画布组件属性
|
||||
*/
|
||||
interface BehaviorTreeCanvasProps {
|
||||
/**
|
||||
* 编辑器配置
|
||||
*/
|
||||
config: EditorConfig;
|
||||
|
||||
/**
|
||||
* 子组件
|
||||
*/
|
||||
children: React.ReactNode;
|
||||
|
||||
/**
|
||||
* 画布点击事件
|
||||
*/
|
||||
onClick?: (e: React.MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* 画布双击事件
|
||||
*/
|
||||
onDoubleClick?: (e: React.MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* 画布右键事件
|
||||
*/
|
||||
onContextMenu?: (e: React.MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* 鼠标移动事件
|
||||
*/
|
||||
onMouseMove?: (e: React.MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* 鼠标按下事件
|
||||
*/
|
||||
onMouseDown?: (e: React.MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* 鼠标抬起事件
|
||||
*/
|
||||
onMouseUp?: (e: React.MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* 鼠标离开事件
|
||||
*/
|
||||
onMouseLeave?: (e: React.MouseEvent) => void;
|
||||
|
||||
/**
|
||||
* 拖放事件
|
||||
*/
|
||||
onDrop?: (e: React.DragEvent) => void;
|
||||
|
||||
/**
|
||||
* 拖动悬停事件
|
||||
*/
|
||||
onDragOver?: (e: React.DragEvent) => void;
|
||||
|
||||
/**
|
||||
* 拖动进入事件
|
||||
*/
|
||||
onDragEnter?: (e: React.DragEvent) => void;
|
||||
|
||||
/**
|
||||
* 拖动离开事件
|
||||
*/
|
||||
onDragLeave?: (e: React.DragEvent) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* 行为树画布组件
|
||||
* 负责画布的渲染、缩放、平移等基础功能
|
||||
*/
|
||||
export const BehaviorTreeCanvas = forwardRef<HTMLDivElement, BehaviorTreeCanvasProps>(({
|
||||
config,
|
||||
children,
|
||||
onClick,
|
||||
onDoubleClick,
|
||||
onContextMenu,
|
||||
onMouseMove,
|
||||
onMouseDown,
|
||||
onMouseUp,
|
||||
onMouseLeave,
|
||||
onDrop,
|
||||
onDragOver,
|
||||
onDragEnter,
|
||||
onDragLeave
|
||||
}, forwardedRef) => {
|
||||
const internalRef = useRef<HTMLDivElement>(null);
|
||||
const canvasRef = (forwardedRef as React.RefObject<HTMLDivElement>) || internalRef;
|
||||
|
||||
const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 });
|
||||
|
||||
const {
|
||||
canvasOffset,
|
||||
canvasScale,
|
||||
isPanning,
|
||||
handleWheel,
|
||||
startPanning,
|
||||
updatePanning,
|
||||
stopPanning
|
||||
} = useCanvasInteraction();
|
||||
|
||||
// 监听画布尺寸变化
|
||||
useEffect(() => {
|
||||
const updateSize = () => {
|
||||
if (canvasRef.current) {
|
||||
const rect = canvasRef.current.getBoundingClientRect();
|
||||
setCanvasSize({
|
||||
width: rect.width,
|
||||
height: rect.height
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
updateSize();
|
||||
|
||||
const resizeObserver = new ResizeObserver(updateSize);
|
||||
if (canvasRef.current) {
|
||||
resizeObserver.observe(canvasRef.current);
|
||||
}
|
||||
|
||||
return () => {
|
||||
resizeObserver.disconnect();
|
||||
};
|
||||
}, [canvasRef]);
|
||||
|
||||
const handleMouseDown = useCallback((e: React.MouseEvent) => {
|
||||
if (e.button === 1 || (e.button === 0 && e.altKey)) {
|
||||
e.preventDefault();
|
||||
startPanning(e.clientX, e.clientY);
|
||||
}
|
||||
|
||||
onMouseDown?.(e);
|
||||
}, [startPanning, onMouseDown]);
|
||||
|
||||
const handleMouseMove = useCallback((e: React.MouseEvent) => {
|
||||
if (isPanning) {
|
||||
updatePanning(e.clientX, e.clientY);
|
||||
}
|
||||
|
||||
onMouseMove?.(e);
|
||||
}, [isPanning, updatePanning, onMouseMove]);
|
||||
|
||||
const handleMouseUp = useCallback((e: React.MouseEvent) => {
|
||||
if (isPanning) {
|
||||
stopPanning();
|
||||
}
|
||||
|
||||
onMouseUp?.(e);
|
||||
}, [isPanning, stopPanning, onMouseUp]);
|
||||
|
||||
const handleContextMenu = useCallback((e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
onContextMenu?.(e);
|
||||
}, [onContextMenu]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={canvasRef}
|
||||
className="behavior-tree-canvas"
|
||||
style={{
|
||||
position: 'relative',
|
||||
width: '100%',
|
||||
height: '100%',
|
||||
overflow: 'hidden',
|
||||
cursor: isPanning ? 'grabbing' : 'default',
|
||||
backgroundColor: '#1a1a1a'
|
||||
}}
|
||||
onWheel={handleWheel}
|
||||
onClick={onClick}
|
||||
onDoubleClick={onDoubleClick}
|
||||
onContextMenu={handleContextMenu}
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseMove={handleMouseMove}
|
||||
onMouseUp={handleMouseUp}
|
||||
onMouseLeave={onMouseLeave}
|
||||
onDrop={onDrop}
|
||||
onDragOver={onDragOver}
|
||||
onDragEnter={onDragEnter}
|
||||
onDragLeave={onDragLeave}
|
||||
>
|
||||
{/* 网格背景 */}
|
||||
{config.showGrid && canvasSize.width > 0 && canvasSize.height > 0 && (
|
||||
<GridBackground
|
||||
canvasOffset={canvasOffset}
|
||||
canvasScale={canvasScale}
|
||||
width={canvasSize.width}
|
||||
height={canvasSize.height}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* 内容容器(应用变换) */}
|
||||
<div
|
||||
className="canvas-content"
|
||||
style={{
|
||||
position: 'absolute',
|
||||
transformOrigin: '0 0',
|
||||
transform: `translate(${canvasOffset.x}px, ${canvasOffset.y}px) scale(${canvasScale})`,
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
BehaviorTreeCanvas.displayName = 'BehaviorTreeCanvas';
|
||||
Reference in New Issue
Block a user