Просмотр исходного кода

feat(free-container-plugin): 添加子画布背景支持,使用inversify依赖注入 (#420)

* feat(free-container-plugin): add sub-canvas background support with inversify

- Add inversify dependency injection support for sub-canvas background
- Use useService to get BackgroundConfig from IoC container
- Support all background options: backgroundColor, dotColor, dotSize, etc.
- Add graceful fallback when BackgroundConfig is not registered
- Generate unique SVG pattern IDs to avoid conflicts
- Remove hardcoded background color from styles
- Add @flowgram.ai/background-plugin dependency

The sub-canvas now automatically inherits background configuration
from the main canvas.

* feat(background-plugin): export BackgroundConfig and bind to IoC container

- Export BackgroundConfig symbol for use by other plugins
- Add onBind method to register BackgroundConfig in IoC container
- Enable dependency injection pattern for background configuration access

This allows sub-canvas components to access background configuration
through inversify container.

* chore: update pnpm-lock.yaml after adding background-plugin dependency

- Update lock file to include @flowgram.ai/background-plugin dependency
- Ensures consistent dependency versions across environments

---------

Co-authored-by: husky-dot <xiaozhi@172-0-8-36.lightspeed.rcsntx.sbcglobal.net>
小智 6 месяцев назад
Родитель
Сommit
dc5e7eb023

+ 3 - 0
common/config/rush/pnpm-lock.yaml

@@ -2667,6 +2667,9 @@ importers:
 
 
   ../../packages/plugins/free-container-plugin:
   ../../packages/plugins/free-container-plugin:
     dependencies:
     dependencies:
+      '@flowgram.ai/background-plugin':
+        specifier: workspace:*
+        version: link:../background-plugin
       '@flowgram.ai/core':
       '@flowgram.ai/core':
         specifier: workspace:*
         specifier: workspace:*
         version: link:../../canvas-engine/core
         version: link:../../canvas-engine/core

+ 1 - 0
packages/plugins/background-plugin/src/background-layer.tsx

@@ -12,6 +12,7 @@ const DEFAULT_RENDER_SIZE = 20;
 const DEFAULT_DOT_SIZE = 1;
 const DEFAULT_DOT_SIZE = 1;
 let id = 0;
 let id = 0;
 
 
+export const BackgroundConfig = Symbol('BackgroundConfig');
 export interface BackgroundLayerOptions {
 export interface BackgroundLayerOptions {
   /** 网格间距,默认 20px */
   /** 网格间距,默认 20px */
   gridSize?: number;
   gridSize?: number;

+ 4 - 1
packages/plugins/background-plugin/src/create-background-plugin.ts

@@ -1,11 +1,14 @@
 import { definePluginCreator } from '@flowgram.ai/core';
 import { definePluginCreator } from '@flowgram.ai/core';
 
 
-import { BackgroundLayer, BackgroundLayerOptions } from './background-layer';
+import { BackgroundConfig, BackgroundLayer, BackgroundLayerOptions } from './background-layer';
 
 
 /**
 /**
  * 点位背景插件
  * 点位背景插件
  */
  */
 export const createBackgroundPlugin = definePluginCreator<BackgroundLayerOptions>({
 export const createBackgroundPlugin = definePluginCreator<BackgroundLayerOptions>({
+  onBind: (bindConfig, opts) => {
+    bindConfig.bind(BackgroundConfig).toConstantValue(opts);
+  },
   onInit: (ctx, opts) => {
   onInit: (ctx, opts) => {
     ctx.playground.registerLayer(BackgroundLayer, opts);
     ctx.playground.registerLayer(BackgroundLayer, opts);
   },
   },

+ 1 - 0
packages/plugins/free-container-plugin/package.json

@@ -35,6 +35,7 @@
         "@flowgram.ai/renderer": "workspace:*",
         "@flowgram.ai/renderer": "workspace:*",
         "@flowgram.ai/utils": "workspace:*",
         "@flowgram.ai/utils": "workspace:*",
         "@flowgram.ai/i18n": "workspace:*",
         "@flowgram.ai/i18n": "workspace:*",
+        "@flowgram.ai/background-plugin": "workspace:*",
         "inversify": "^6.0.1",
         "inversify": "^6.0.1",
         "reflect-metadata": "~0.2.2",
         "reflect-metadata": "~0.2.2",
         "lodash": "^4.17.21"
         "lodash": "^4.17.21"

+ 38 - 4
packages/plugins/free-container-plugin/src/sub-canvas/components/background/index.tsx

@@ -1,21 +1,55 @@
 import React, { type FC } from 'react';
 import React, { type FC } from 'react';
 
 
 import { useCurrentEntity } from '@flowgram.ai/free-layout-core';
 import { useCurrentEntity } from '@flowgram.ai/free-layout-core';
+import { useService } from '@flowgram.ai/core';
+import { BackgroundConfig, BackgroundLayerOptions } from '@flowgram.ai/background-plugin';
 
 
 import { SubCanvasBackgroundStyle } from './style';
 import { SubCanvasBackgroundStyle } from './style';
 
 
 export const SubCanvasBackground: FC = () => {
 export const SubCanvasBackground: FC = () => {
   const node = useCurrentEntity();
   const node = useCurrentEntity();
+
+  // 通过 inversify 获取背景配置,如果没有配置则使用默认值
+  let backgroundConfig: BackgroundLayerOptions = {};
+  try {
+    backgroundConfig = useService<BackgroundLayerOptions>(BackgroundConfig);
+  } catch (error) {
+    // 如果 BackgroundConfig 没有注册,使用默认配置
+    // 静默处理,使用默认配置
+  }
+
+  // 获取配置值,如果没有则使用默认值
+  const gridSize = backgroundConfig.gridSize ?? 20;
+  const dotSize = backgroundConfig.dotSize ?? 1;
+  const dotColor = backgroundConfig.dotColor ?? '#eceeef';
+  const dotOpacity = backgroundConfig.dotOpacity ?? 0.5;
+  const backgroundColor = backgroundConfig.backgroundColor ?? '#f2f3f5';
+  const dotFillColor = backgroundConfig.dotFillColor ?? dotColor;
+
+  // 生成唯一的 pattern ID
+  const patternId = `sub-canvas-dot-pattern-${node.id}`;
+
   return (
   return (
-    <SubCanvasBackgroundStyle className="sub-canvas-background" data-flow-editor-selectable="true">
+    <SubCanvasBackgroundStyle
+      className="sub-canvas-background"
+      data-flow-editor-selectable="true"
+      style={{ backgroundColor: backgroundColor }}
+    >
       <svg width="100%" height="100%">
       <svg width="100%" height="100%">
-        <pattern id="sub-canvas-dot-pattern" width="20" height="20" patternUnits="userSpaceOnUse">
-          <circle cx="1" cy="1" r="1" stroke="#eceeef" fillOpacity="0.5" />
+        <pattern id={patternId} width={gridSize} height={gridSize} patternUnits="userSpaceOnUse">
+          <circle
+            cx={dotSize}
+            cy={dotSize}
+            r={dotSize}
+            stroke={dotColor}
+            fill={dotFillColor}
+            fillOpacity={dotOpacity}
+          />
         </pattern>
         </pattern>
         <rect
         <rect
           width="100%"
           width="100%"
           height="100%"
           height="100%"
-          fill="url(#sub-canvas-dot-pattern)"
+          fill={`url(#${patternId})`}
           data-node-panel-container={node.id}
           data-node-panel-container={node.id}
         />
         />
       </svg>
       </svg>

+ 1 - 1
packages/plugins/free-container-plugin/src/sub-canvas/components/background/style.ts

@@ -4,5 +4,5 @@ export const SubCanvasBackgroundStyle = styled.div`
   width: 100%;
   width: 100%;
   height: 100%;
   height: 100%;
   inset: 56px 18px 18px;
   inset: 56px 18px 18px;
-  background-color: #f2f3f5;
+  /* 背景色现在通过 style 属性动态设置 */
 `;
 `;