@flowgram.ai/background-plugin 0.2.14 → 0.2.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/esm/index.js CHANGED
@@ -10,11 +10,11 @@ var __decorateClass = (decorators, target, key, kind) => {
10
10
  };
11
11
 
12
12
  // src/background-layer.tsx
13
- import { Layer, observeEntity, PlaygroundConfigEntity, SCALE_WIDTH } from "@flowgram.ai/core";
14
13
  import { domUtils } from "@flowgram.ai/utils";
14
+ import { Layer, observeEntity, PlaygroundConfigEntity, SCALE_WIDTH } from "@flowgram.ai/core";
15
15
  var PATTERN_PREFIX = "gedit-background-pattern-";
16
- var RENDER_SIZE = 20;
17
- var DOT_SIZE = 1;
16
+ var DEFAULT_RENDER_SIZE = 20;
17
+ var DEFAULT_DOT_SIZE = 1;
18
18
  var id = 0;
19
19
  var BackgroundLayer = class extends Layer {
20
20
  constructor() {
@@ -23,6 +23,48 @@ var BackgroundLayer = class extends Layer {
23
23
  this.node = domUtils.createDivWithClass("gedit-flow-background-layer");
24
24
  this.grid = document.createElement("div");
25
25
  }
26
+ /**
27
+ * 获取网格大小配置
28
+ */
29
+ get gridSize() {
30
+ return this.options.gridSize ?? DEFAULT_RENDER_SIZE;
31
+ }
32
+ /**
33
+ * 获取点大小配置
34
+ */
35
+ get dotSize() {
36
+ return this.options.dotSize ?? DEFAULT_DOT_SIZE;
37
+ }
38
+ /**
39
+ * 获取点颜色配置
40
+ */
41
+ get dotColor() {
42
+ return this.options.dotColor ?? "#eceeef";
43
+ }
44
+ /**
45
+ * 获取点透明度配置
46
+ */
47
+ get dotOpacity() {
48
+ return this.options.dotOpacity ?? 0.5;
49
+ }
50
+ /**
51
+ * 获取背景颜色配置
52
+ */
53
+ get backgroundColor() {
54
+ return this.options.backgroundColor ?? "transparent";
55
+ }
56
+ /**
57
+ * 获取点填充颜色配置
58
+ */
59
+ get dotFillColor() {
60
+ return this.options.dotFillColor ?? this.dotColor;
61
+ }
62
+ /**
63
+ * 获取Logo配置
64
+ */
65
+ get logoConfig() {
66
+ return this.options.logo;
67
+ }
26
68
  /**
27
69
  * 当前缩放比
28
70
  */
@@ -40,6 +82,9 @@ var BackgroundLayer = class extends Layer {
40
82
  this.grid.style.position = "relative";
41
83
  this.node.appendChild(this.grid);
42
84
  this.grid.className = "gedit-grid-svg";
85
+ if (this.backgroundColor !== "transparent") {
86
+ this.node.style.backgroundColor = this.backgroundColor;
87
+ }
43
88
  }
44
89
  /**
45
90
  * 最小单元格大小
@@ -47,9 +92,9 @@ var BackgroundLayer = class extends Layer {
47
92
  getScaleUnit() {
48
93
  const { zoom } = this;
49
94
  return {
50
- realSize: RENDER_SIZE,
51
- // 一个单元格代表的真实大小
52
- renderSize: Math.round(RENDER_SIZE * zoom * 100) / 100,
95
+ realSize: this.gridSize,
96
+ // 使用配置的网格大小
97
+ renderSize: Math.round(this.gridSize * zoom * 100) / 100,
53
98
  // 一个单元格渲染的大小值
54
99
  zoom
55
100
  // 缩放比
@@ -72,7 +117,7 @@ var BackgroundLayer = class extends Layer {
72
117
  left: scrollX - SCALE_WIDTH,
73
118
  top: scrollY - SCALE_WIDTH
74
119
  });
75
- this.drawGrid(scaleUnit);
120
+ this.drawGrid(scaleUnit, viewBoxWidth, viewBoxHeight);
76
121
  this.setSVGStyle(this.grid, {
77
122
  width: viewBoxWidth,
78
123
  height: viewBoxHeight,
@@ -80,29 +125,221 @@ var BackgroundLayer = class extends Layer {
80
125
  top: SCALE_WIDTH - scrollYDelta - mod
81
126
  });
82
127
  }
128
+ /**
129
+ * 计算Logo位置
130
+ */
131
+ calculateLogoPosition(viewBoxWidth, viewBoxHeight) {
132
+ if (!this.logoConfig) return { x: 0, y: 0 };
133
+ const { position = "center", offset = { x: 0, y: 0 } } = this.logoConfig;
134
+ const playgroundConfig = this.playgroundConfigEntity.config;
135
+ const scaleUnit = this.getScaleUnit();
136
+ const mod = scaleUnit.renderSize * 10;
137
+ const { scrollX, scrollY } = playgroundConfig;
138
+ const scrollXDelta = this.getScrollDelta(scrollX, mod);
139
+ const scrollYDelta = this.getScrollDelta(scrollY, mod);
140
+ const visibleLeft = mod + scrollXDelta;
141
+ const visibleTop = mod + scrollYDelta;
142
+ const visibleCenterX = visibleLeft + playgroundConfig.width / 2;
143
+ const visibleCenterY = visibleTop + playgroundConfig.height / 2;
144
+ let x = 0, y = 0;
145
+ switch (position) {
146
+ case "center":
147
+ x = visibleCenterX;
148
+ y = visibleCenterY;
149
+ break;
150
+ case "top-left":
151
+ x = visibleLeft + 100;
152
+ y = visibleTop + 100;
153
+ break;
154
+ case "top-right":
155
+ x = visibleLeft + playgroundConfig.width - 100;
156
+ y = visibleTop + 100;
157
+ break;
158
+ case "bottom-left":
159
+ x = visibleLeft + 100;
160
+ y = visibleTop + playgroundConfig.height - 100;
161
+ break;
162
+ case "bottom-right":
163
+ x = visibleLeft + playgroundConfig.width - 100;
164
+ y = visibleTop + playgroundConfig.height - 100;
165
+ break;
166
+ }
167
+ return { x: x + offset.x, y: y + offset.y };
168
+ }
169
+ /**
170
+ * 获取Logo大小
171
+ */
172
+ getLogoSize() {
173
+ if (!this.logoConfig) return 0;
174
+ const { size = "medium" } = this.logoConfig;
175
+ if (typeof size === "number") {
176
+ return size;
177
+ }
178
+ switch (size) {
179
+ case "small":
180
+ return 24;
181
+ case "medium":
182
+ return 48;
183
+ case "large":
184
+ return 72;
185
+ default:
186
+ return 48;
187
+ }
188
+ }
189
+ /**
190
+ * 颜色工具函数:将十六进制颜色转换为RGB
191
+ */
192
+ hexToRgb(hex) {
193
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
194
+ return result ? {
195
+ r: parseInt(result[1], 16),
196
+ g: parseInt(result[2], 16),
197
+ b: parseInt(result[3], 16)
198
+ } : null;
199
+ }
200
+ /**
201
+ * 颜色工具函数:调整颜色亮度
202
+ */
203
+ adjustBrightness(hex, percent) {
204
+ const rgb = this.hexToRgb(hex);
205
+ if (!rgb) return hex;
206
+ const adjust = (value) => {
207
+ const adjusted = Math.round(value + (255 - value) * percent);
208
+ return Math.max(0, Math.min(255, adjusted));
209
+ };
210
+ return `#${adjust(rgb.r).toString(16).padStart(2, "0")}${adjust(rgb.g).toString(16).padStart(2, "0")}${adjust(rgb.b).toString(16).padStart(2, "0")}`;
211
+ }
212
+ /**
213
+ * 生成新拟态阴影滤镜
214
+ */
215
+ generateNeumorphismFilter(filterId, lightShadow, darkShadow, offset, blur, intensity, raised) {
216
+ const lightOffset = raised ? -offset : offset;
217
+ const darkOffset = raised ? offset : -offset;
218
+ return `
219
+ <defs>
220
+ <filter id="${filterId}" x="-50%" y="-50%" width="200%" height="200%">
221
+ <feDropShadow dx="${lightOffset}" dy="${lightOffset}" stdDeviation="${blur}" flood-color="${lightShadow}" flood-opacity="${intensity}"/>
222
+ <feDropShadow dx="${darkOffset}" dy="${darkOffset}" stdDeviation="${blur}" flood-color="${darkShadow}" flood-opacity="${intensity}"/>
223
+ </filter>
224
+ </defs>`;
225
+ }
226
+ /**
227
+ * 绘制Logo SVG内容
228
+ */
229
+ generateLogoSVG(viewBoxWidth, viewBoxHeight) {
230
+ if (!this.logoConfig) return "";
231
+ const {
232
+ text,
233
+ imageUrl,
234
+ opacity = 0.1,
235
+ color = "#cccccc",
236
+ fontSize,
237
+ fontFamily = "Arial, sans-serif",
238
+ fontWeight = "normal",
239
+ neumorphism
240
+ } = this.logoConfig;
241
+ const position = this.calculateLogoPosition(viewBoxWidth, viewBoxHeight);
242
+ const logoSize = this.getLogoSize();
243
+ let logoSVG = "";
244
+ if (imageUrl) {
245
+ logoSVG = `
246
+ <image
247
+ href="${imageUrl}"
248
+ x="${position.x - logoSize / 2}"
249
+ y="${position.y - logoSize / 2}"
250
+ width="${logoSize}"
251
+ height="${logoSize}"
252
+ opacity="${opacity}"
253
+ />`;
254
+ } else if (text) {
255
+ const actualFontSize = fontSize ?? Math.max(logoSize / 2, 12);
256
+ if (neumorphism?.enabled) {
257
+ const {
258
+ textColor,
259
+ lightShadowColor,
260
+ darkShadowColor,
261
+ shadowOffset = 6,
262
+ shadowBlur = 12,
263
+ intensity = 0.3,
264
+ raised = true
265
+ } = neumorphism;
266
+ const bgColor = this.backgroundColor !== "transparent" ? this.backgroundColor : "#f0f0f0";
267
+ const finalTextColor = textColor || bgColor;
268
+ const finalLightShadow = lightShadowColor || this.adjustBrightness(bgColor, 0.2);
269
+ const finalDarkShadow = darkShadowColor || this.adjustBrightness(bgColor, -0.2);
270
+ const filterId = `neumorphism-${this._patternId}`;
271
+ logoSVG += this.generateNeumorphismFilter(
272
+ filterId,
273
+ finalLightShadow,
274
+ finalDarkShadow,
275
+ shadowOffset,
276
+ shadowBlur,
277
+ intensity,
278
+ raised
279
+ );
280
+ logoSVG += `
281
+ <text
282
+ x="${position.x}"
283
+ y="${position.y}"
284
+ font-family="${fontFamily}"
285
+ font-size="${actualFontSize}"
286
+ font-weight="${fontWeight}"
287
+ fill="${finalTextColor}"
288
+ opacity="${opacity}"
289
+ text-anchor="middle"
290
+ dominant-baseline="middle"
291
+ filter="url(#${filterId})"
292
+ >${text}</text>`;
293
+ } else {
294
+ logoSVG = `
295
+ <text
296
+ x="${position.x}"
297
+ y="${position.y}"
298
+ font-family="${fontFamily}"
299
+ font-size="${actualFontSize}"
300
+ font-weight="${fontWeight}"
301
+ fill="${color}"
302
+ opacity="${opacity}"
303
+ text-anchor="middle"
304
+ dominant-baseline="middle"
305
+ >${text}</text>`;
306
+ }
307
+ }
308
+ return logoSVG;
309
+ }
83
310
  /**
84
311
  * 绘制网格
85
312
  */
86
- drawGrid(unit) {
313
+ drawGrid(unit, viewBoxWidth, viewBoxHeight) {
87
314
  const minor = unit.renderSize;
88
315
  if (!this.grid) {
89
316
  return;
90
317
  }
91
- const patternSize = DOT_SIZE * this.zoom;
92
- const newContent = `
93
- <svg width="100%" height="100%">
318
+ const patternSize = this.dotSize * this.zoom;
319
+ let svgContent = `<svg width="100%" height="100%">`;
320
+ if (this.backgroundColor !== "transparent") {
321
+ svgContent += `<rect width="100%" height="100%" fill="${this.backgroundColor}"/>`;
322
+ }
323
+ const circleAttributes = [
324
+ `cx="${patternSize}"`,
325
+ `cy="${patternSize}"`,
326
+ `r="${patternSize}"`,
327
+ `stroke="${this.dotColor}"`,
328
+ // 只有当 dotFillColor 被明确设置且与 dotColor 不同时才添加 fill 属性
329
+ this.options.dotFillColor && this.dotFillColor !== this.dotColor ? `fill="${this.dotFillColor}"` : "",
330
+ `fill-opacity="${this.dotOpacity}"`
331
+ ].filter(Boolean).join(" ");
332
+ svgContent += `
94
333
  <pattern id="${this._patternId}" width="${minor}" height="${minor}" patternUnits="userSpaceOnUse">
95
- <circle
96
- cx="${patternSize}"
97
- cy="${patternSize}"
98
- r="${patternSize}"
99
- stroke="#eceeef"
100
- fill-opacity="0.5"
101
- />
334
+ <circle ${circleAttributes} />
102
335
  </pattern>
103
- <rect width="100%" height="100%" fill="url(#${this._patternId})"/>
104
- </svg>`;
105
- this.grid.innerHTML = newContent;
336
+ <rect width="100%" height="100%" fill="url(#${this._patternId})"/>`;
337
+ const logoSVG = this.generateLogoSVG(viewBoxWidth, viewBoxHeight);
338
+ if (logoSVG) {
339
+ svgContent += logoSVG;
340
+ }
341
+ svgContent += `</svg>`;
342
+ this.grid.innerHTML = svgContent;
106
343
  }
107
344
  setSVGStyle(svgElement, style) {
108
345
  if (!svgElement) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/background-layer.tsx","../../src/create-background-plugin.ts"],"sourcesContent":["import { Layer, observeEntity, PlaygroundConfigEntity, SCALE_WIDTH } from '@flowgram.ai/core';\nimport { domUtils } from '@flowgram.ai/utils';\n\ninterface BackgroundScaleUnit {\n realSize: number;\n renderSize: number;\n zoom: number;\n}\n\nconst PATTERN_PREFIX = 'gedit-background-pattern-';\nconst RENDER_SIZE = 20;\nconst DOT_SIZE = 1;\nlet id = 0;\nexport interface BackgroundLayerOptions {\n // 预留配置项目\n}\n/**\n * dot 网格背景\n */\nexport class BackgroundLayer extends Layer<BackgroundLayerOptions> {\n static type = 'WorkflowBackgroundLayer';\n\n @observeEntity(PlaygroundConfigEntity)\n protected playgroundConfigEntity: PlaygroundConfigEntity;\n\n private _patternId = `${PATTERN_PREFIX}${id++}`;\n\n node = domUtils.createDivWithClass('gedit-flow-background-layer');\n\n grid: HTMLElement = document.createElement('div');\n\n /**\n * 当前缩放比\n */\n get zoom(): number {\n return this.config.finalScale;\n }\n\n onReady() {\n const { firstChild } = this.pipelineNode;\n // 背景插入到最下边\n this.pipelineNode.insertBefore(this.node, firstChild);\n // 初始化设置最大 200% 最小 10% 缩放\n this.playgroundConfigEntity.updateConfig({\n minZoom: 0.1,\n maxZoom: 2,\n });\n // 确保点的位置在线条的下方\n this.grid.style.zIndex = '-1';\n this.grid.style.position = 'relative';\n this.node.appendChild(this.grid);\n this.grid.className = 'gedit-grid-svg';\n }\n\n /**\n * 最小单元格大小\n */\n getScaleUnit(): BackgroundScaleUnit {\n const { zoom } = this;\n\n return {\n realSize: RENDER_SIZE, // 一个单元格代表的真实大小\n renderSize: Math.round(RENDER_SIZE * zoom * 100) / 100, // 一个单元格渲染的大小值\n zoom, // 缩放比\n };\n }\n\n /**\n * 绘制\n */\n autorun(): void {\n const playgroundConfig = this.playgroundConfigEntity.config;\n const scaleUnit = this.getScaleUnit();\n const mod = scaleUnit.renderSize * 10;\n const viewBoxWidth = playgroundConfig.width + mod * 2;\n const viewBoxHeight = playgroundConfig.height + mod * 2;\n const { scrollX } = playgroundConfig;\n const { scrollY } = playgroundConfig;\n const scrollXDelta = this.getScrollDelta(scrollX, mod);\n const scrollYDelta = this.getScrollDelta(scrollY, mod);\n domUtils.setStyle(this.node, {\n left: scrollX - SCALE_WIDTH,\n top: scrollY - SCALE_WIDTH,\n });\n this.drawGrid(scaleUnit);\n // 设置网格\n this.setSVGStyle(this.grid, {\n width: viewBoxWidth,\n height: viewBoxHeight,\n left: SCALE_WIDTH - scrollXDelta - mod,\n top: SCALE_WIDTH - scrollYDelta - mod,\n });\n }\n\n /**\n * 绘制网格\n */\n protected drawGrid(unit: BackgroundScaleUnit): void {\n const minor = unit.renderSize;\n if (!this.grid) {\n return;\n }\n const patternSize = DOT_SIZE * this.zoom;\n const newContent = `\n <svg width=\"100%\" height=\"100%\">\n <pattern id=\"${this._patternId}\" width=\"${minor}\" height=\"${minor}\" patternUnits=\"userSpaceOnUse\">\n <circle\n cx=\"${patternSize}\"\n cy=\"${patternSize}\"\n r=\"${patternSize}\"\n stroke=\"#eceeef\"\n fill-opacity=\"0.5\"\n />\n </pattern>\n <rect width=\"100%\" height=\"100%\" fill=\"url(#${this._patternId})\"/>\n </svg>`;\n this.grid.innerHTML = newContent;\n }\n\n protected setSVGStyle(\n svgElement: HTMLElement | undefined,\n style: { width: number; height: number; left: number; top: number },\n ): void {\n if (!svgElement) {\n return;\n }\n\n svgElement.style.width = `${style.width}px`;\n svgElement.style.height = `${style.height}px`;\n svgElement.style.left = `${style.left}px`;\n svgElement.style.top = `${style.top}px`;\n }\n\n /**\n * 获取相对滚动距离\n * @param realScroll\n * @param mod\n */\n protected getScrollDelta(realScroll: number, mod: number): number {\n // 正向滚动不用补差\n if (realScroll >= 0) {\n return realScroll % mod;\n }\n return mod - (Math.abs(realScroll) % mod);\n }\n}\n","import { definePluginCreator } from '@flowgram.ai/core';\n\nimport { BackgroundLayer, BackgroundLayerOptions } from './background-layer';\n\n/**\n * 点位背景插件\n */\nexport const createBackgroundPlugin = definePluginCreator<BackgroundLayerOptions>({\n onInit: (ctx, opts) => {\n ctx.playground.registerLayer(BackgroundLayer, opts);\n },\n});\n"],"mappings":";;;;;;;;;;;;AAAA,SAAS,OAAO,eAAe,wBAAwB,mBAAmB;AAC1E,SAAS,gBAAgB;AAQzB,IAAM,iBAAiB;AACvB,IAAM,cAAc;AACpB,IAAM,WAAW;AACjB,IAAI,KAAK;AAOF,IAAM,kBAAN,cAA8B,MAA8B;AAAA,EAA5D;AAAA;AAML,SAAQ,aAAa,GAAG,cAAc,GAAG,IAAI;AAE7C,gBAAO,SAAS,mBAAmB,6BAA6B;AAEhE,gBAAoB,SAAS,cAAc,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAKhD,IAAI,OAAe;AACjB,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,UAAU;AACR,UAAM,EAAE,WAAW,IAAI,KAAK;AAE5B,SAAK,aAAa,aAAa,KAAK,MAAM,UAAU;AAEpD,SAAK,uBAAuB,aAAa;AAAA,MACvC,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC;AAED,SAAK,KAAK,MAAM,SAAS;AACzB,SAAK,KAAK,MAAM,WAAW;AAC3B,SAAK,KAAK,YAAY,KAAK,IAAI;AAC/B,SAAK,KAAK,YAAY;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,eAAoC;AAClC,UAAM,EAAE,KAAK,IAAI;AAEjB,WAAO;AAAA,MACL,UAAU;AAAA;AAAA,MACV,YAAY,KAAK,MAAM,cAAc,OAAO,GAAG,IAAI;AAAA;AAAA,MACnD;AAAA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,UAAgB;AACd,UAAM,mBAAmB,KAAK,uBAAuB;AACrD,UAAM,YAAY,KAAK,aAAa;AACpC,UAAM,MAAM,UAAU,aAAa;AACnC,UAAM,eAAe,iBAAiB,QAAQ,MAAM;AACpD,UAAM,gBAAgB,iBAAiB,SAAS,MAAM;AACtD,UAAM,EAAE,QAAQ,IAAI;AACpB,UAAM,EAAE,QAAQ,IAAI;AACpB,UAAM,eAAe,KAAK,eAAe,SAAS,GAAG;AACrD,UAAM,eAAe,KAAK,eAAe,SAAS,GAAG;AACrD,aAAS,SAAS,KAAK,MAAM;AAAA,MAC3B,MAAM,UAAU;AAAA,MAChB,KAAK,UAAU;AAAA,IACjB,CAAC;AACD,SAAK,SAAS,SAAS;AAEvB,SAAK,YAAY,KAAK,MAAM;AAAA,MAC1B,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,MAAM,cAAc,eAAe;AAAA,MACnC,KAAK,cAAc,eAAe;AAAA,IACpC,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKU,SAAS,MAAiC;AAClD,UAAM,QAAQ,KAAK;AACnB,QAAI,CAAC,KAAK,MAAM;AACd;AAAA,IACF;AACA,UAAM,cAAc,WAAW,KAAK;AACpC,UAAM,aAAa;AAAA;AAAA,qBAEF,KAAK,UAAU,YAAY,KAAK,aAAa,KAAK;AAAA;AAAA,gBAEvD,WAAW;AAAA,gBACX,WAAW;AAAA,eACZ,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA,oDAK0B,KAAK,UAAU;AAAA;AAE/D,SAAK,KAAK,YAAY;AAAA,EACxB;AAAA,EAEU,YACR,YACA,OACM;AACN,QAAI,CAAC,YAAY;AACf;AAAA,IACF;AAEA,eAAW,MAAM,QAAQ,GAAG,MAAM,KAAK;AACvC,eAAW,MAAM,SAAS,GAAG,MAAM,MAAM;AACzC,eAAW,MAAM,OAAO,GAAG,MAAM,IAAI;AACrC,eAAW,MAAM,MAAM,GAAG,MAAM,GAAG;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOU,eAAe,YAAoB,KAAqB;AAEhE,QAAI,cAAc,GAAG;AACnB,aAAO,aAAa;AAAA,IACtB;AACA,WAAO,MAAO,KAAK,IAAI,UAAU,IAAI;AAAA,EACvC;AACF;AA9Ha,gBACJ,OAAO;AAGJ;AAAA,EADT,cAAc,sBAAsB;AAAA,GAH1B,gBAID;;;ACvBZ,SAAS,2BAA2B;AAO7B,IAAM,yBAAyB,oBAA4C;AAAA,EAChF,QAAQ,CAAC,KAAK,SAAS;AACrB,QAAI,WAAW,cAAc,iBAAiB,IAAI;AAAA,EACpD;AACF,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../src/background-layer.tsx","../../src/create-background-plugin.ts"],"sourcesContent":["import { domUtils } from '@flowgram.ai/utils';\nimport { Layer, observeEntity, PlaygroundConfigEntity, SCALE_WIDTH } from '@flowgram.ai/core';\n\ninterface BackgroundScaleUnit {\n realSize: number;\n renderSize: number;\n zoom: number;\n}\n\nconst PATTERN_PREFIX = 'gedit-background-pattern-';\nconst DEFAULT_RENDER_SIZE = 20;\nconst DEFAULT_DOT_SIZE = 1;\nlet id = 0;\n\nexport interface BackgroundLayerOptions {\n /** 网格间距,默认 20px */\n gridSize?: number;\n /** 点的大小,默认 1px */\n dotSize?: number;\n /** 点的颜色,默认 \"#eceeef\" */\n dotColor?: string;\n /** 点的透明度,默认 0.5 */\n dotOpacity?: number;\n /** 背景颜色,默认透明 */\n backgroundColor?: string;\n /** 点的填充颜色,默认与stroke颜色相同 */\n dotFillColor?: string;\n /** Logo 配置 */\n logo?: {\n /** Logo 文本内容 */\n text?: string;\n /** Logo 图片 URL */\n imageUrl?: string;\n /** Logo 位置,默认 'center' */\n position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n /** Logo 大小,默认 'medium' */\n size?: 'small' | 'medium' | 'large' | number;\n /** Logo 透明度,默认 0.1 */\n opacity?: number;\n /** Logo 颜色(仅文本),默认 \"#cccccc\" */\n color?: string;\n /** Logo 字体大小(仅文本),默认根据 size 计算 */\n fontSize?: number;\n /** Logo 字体家族(仅文本),默认 'Arial, sans-serif' */\n fontFamily?: string;\n /** Logo 字体粗细(仅文本),默认 'normal' */\n fontWeight?: 'normal' | 'bold' | 'lighter' | number;\n /** 自定义偏移 */\n offset?: { x: number; y: number };\n /** 新拟态(Neumorphism)效果配置 */\n neumorphism?: {\n /** 是否启用新拟态效果,默认 false */\n enabled?: boolean;\n /** 主要文字颜色,应该与背景色接近,默认自动计算 */\n textColor?: string;\n /** 亮色阴影颜色,默认自动计算(背景色的亮色版本) */\n lightShadowColor?: string;\n /** 暗色阴影颜色,默认自动计算(背景色的暗色版本) */\n darkShadowColor?: string;\n /** 阴影偏移距离,默认 6 */\n shadowOffset?: number;\n /** 阴影模糊半径,默认 12 */\n shadowBlur?: number;\n /** 效果强度(0-1),影响阴影的透明度,默认 0.3 */\n intensity?: number;\n /** 凸起效果(true)还是凹陷效果(false),默认 true */\n raised?: boolean;\n };\n };\n}\n\n/**\n * dot 网格背景\n */\nexport class BackgroundLayer extends Layer<BackgroundLayerOptions> {\n static type = 'WorkflowBackgroundLayer';\n\n @observeEntity(PlaygroundConfigEntity)\n protected playgroundConfigEntity: PlaygroundConfigEntity;\n\n private _patternId = `${PATTERN_PREFIX}${id++}`;\n\n node = domUtils.createDivWithClass('gedit-flow-background-layer');\n\n grid: HTMLElement = document.createElement('div');\n\n /**\n * 获取网格大小配置\n */\n private get gridSize(): number {\n return this.options.gridSize ?? DEFAULT_RENDER_SIZE;\n }\n\n /**\n * 获取点大小配置\n */\n private get dotSize(): number {\n return this.options.dotSize ?? DEFAULT_DOT_SIZE;\n }\n\n /**\n * 获取点颜色配置\n */\n private get dotColor(): string {\n return this.options.dotColor ?? '#eceeef';\n }\n\n /**\n * 获取点透明度配置\n */\n private get dotOpacity(): number {\n return this.options.dotOpacity ?? 0.5;\n }\n\n /**\n * 获取背景颜色配置\n */\n private get backgroundColor(): string {\n return this.options.backgroundColor ?? 'transparent';\n }\n\n /**\n * 获取点填充颜色配置\n */\n private get dotFillColor(): string {\n return this.options.dotFillColor ?? this.dotColor;\n }\n\n /**\n * 获取Logo配置\n */\n private get logoConfig() {\n return this.options.logo;\n }\n\n /**\n * 当前缩放比\n */\n get zoom(): number {\n return this.config.finalScale;\n }\n\n onReady() {\n const { firstChild } = this.pipelineNode;\n // 背景插入到最下边\n this.pipelineNode.insertBefore(this.node, firstChild);\n // 初始化设置最大 200% 最小 10% 缩放\n this.playgroundConfigEntity.updateConfig({\n minZoom: 0.1,\n maxZoom: 2,\n });\n // 确保点的位置在线条的下方\n this.grid.style.zIndex = '-1';\n this.grid.style.position = 'relative';\n this.node.appendChild(this.grid);\n this.grid.className = 'gedit-grid-svg';\n\n // 设置背景颜色\n if (this.backgroundColor !== 'transparent') {\n this.node.style.backgroundColor = this.backgroundColor;\n }\n }\n\n /**\n * 最小单元格大小\n */\n getScaleUnit(): BackgroundScaleUnit {\n const { zoom } = this;\n\n return {\n realSize: this.gridSize, // 使用配置的网格大小\n renderSize: Math.round(this.gridSize * zoom * 100) / 100, // 一个单元格渲染的大小值\n zoom, // 缩放比\n };\n }\n\n /**\n * 绘制\n */\n autorun(): void {\n const playgroundConfig = this.playgroundConfigEntity.config;\n const scaleUnit = this.getScaleUnit();\n const mod = scaleUnit.renderSize * 10;\n const viewBoxWidth = playgroundConfig.width + mod * 2;\n const viewBoxHeight = playgroundConfig.height + mod * 2;\n const { scrollX } = playgroundConfig;\n const { scrollY } = playgroundConfig;\n const scrollXDelta = this.getScrollDelta(scrollX, mod);\n const scrollYDelta = this.getScrollDelta(scrollY, mod);\n domUtils.setStyle(this.node, {\n left: scrollX - SCALE_WIDTH,\n top: scrollY - SCALE_WIDTH,\n });\n this.drawGrid(scaleUnit, viewBoxWidth, viewBoxHeight);\n // 设置网格\n this.setSVGStyle(this.grid, {\n width: viewBoxWidth,\n height: viewBoxHeight,\n left: SCALE_WIDTH - scrollXDelta - mod,\n top: SCALE_WIDTH - scrollYDelta - mod,\n });\n }\n\n /**\n * 计算Logo位置\n */\n private calculateLogoPosition(\n viewBoxWidth: number,\n viewBoxHeight: number\n ): { x: number; y: number } {\n if (!this.logoConfig) return { x: 0, y: 0 };\n\n const { position = 'center', offset = { x: 0, y: 0 } } = this.logoConfig;\n const playgroundConfig = this.playgroundConfigEntity.config;\n const scaleUnit = this.getScaleUnit();\n const mod = scaleUnit.renderSize * 10;\n\n // 计算SVG内的相对位置,使Logo相对于可视区域固定\n const { scrollX, scrollY } = playgroundConfig;\n const scrollXDelta = this.getScrollDelta(scrollX, mod);\n const scrollYDelta = this.getScrollDelta(scrollY, mod);\n\n // 可视区域的基准点(相对于SVG坐标系)\n const visibleLeft = mod + scrollXDelta;\n const visibleTop = mod + scrollYDelta;\n const visibleCenterX = visibleLeft + playgroundConfig.width / 2;\n const visibleCenterY = visibleTop + playgroundConfig.height / 2;\n\n let x = 0,\n y = 0;\n\n switch (position) {\n case 'center':\n x = visibleCenterX;\n y = visibleCenterY;\n break;\n case 'top-left':\n x = visibleLeft + 100;\n y = visibleTop + 100;\n break;\n case 'top-right':\n x = visibleLeft + playgroundConfig.width - 100;\n y = visibleTop + 100;\n break;\n case 'bottom-left':\n x = visibleLeft + 100;\n y = visibleTop + playgroundConfig.height - 100;\n break;\n case 'bottom-right':\n x = visibleLeft + playgroundConfig.width - 100;\n y = visibleTop + playgroundConfig.height - 100;\n break;\n }\n\n return { x: x + offset.x, y: y + offset.y };\n }\n\n /**\n * 获取Logo大小\n */\n private getLogoSize(): number {\n if (!this.logoConfig) return 0;\n\n const { size = 'medium' } = this.logoConfig;\n\n if (typeof size === 'number') {\n return size;\n }\n\n switch (size) {\n case 'small':\n return 24;\n case 'medium':\n return 48;\n case 'large':\n return 72;\n default:\n return 48;\n }\n }\n\n /**\n * 颜色工具函数:将十六进制颜色转换为RGB\n */\n private hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16),\n }\n : null;\n }\n\n /**\n * 颜色工具函数:调整颜色亮度\n */\n private adjustBrightness(hex: string, percent: number): string {\n const rgb = this.hexToRgb(hex);\n if (!rgb) return hex;\n\n const adjust = (value: number) => {\n const adjusted = Math.round(value + (255 - value) * percent);\n return Math.max(0, Math.min(255, adjusted));\n };\n\n return `#${adjust(rgb.r).toString(16).padStart(2, '0')}${adjust(rgb.g)\n .toString(16)\n .padStart(2, '0')}${adjust(rgb.b).toString(16).padStart(2, '0')}`;\n }\n\n /**\n * 生成新拟态阴影滤镜\n */\n private generateNeumorphismFilter(\n filterId: string,\n lightShadow: string,\n darkShadow: string,\n offset: number,\n blur: number,\n intensity: number,\n raised: boolean\n ): string {\n const lightOffset = raised ? -offset : offset;\n const darkOffset = raised ? offset : -offset;\n\n return `\n <defs>\n <filter id=\"${filterId}\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feDropShadow dx=\"${lightOffset}\" dy=\"${lightOffset}\" stdDeviation=\"${blur}\" flood-color=\"${lightShadow}\" flood-opacity=\"${intensity}\"/>\n <feDropShadow dx=\"${darkOffset}\" dy=\"${darkOffset}\" stdDeviation=\"${blur}\" flood-color=\"${darkShadow}\" flood-opacity=\"${intensity}\"/>\n </filter>\n </defs>`;\n }\n\n /**\n * 绘制Logo SVG内容\n */\n private generateLogoSVG(viewBoxWidth: number, viewBoxHeight: number): string {\n if (!this.logoConfig) return '';\n\n const {\n text,\n imageUrl,\n opacity = 0.1,\n color = '#cccccc',\n fontSize,\n fontFamily = 'Arial, sans-serif',\n fontWeight = 'normal',\n neumorphism,\n } = this.logoConfig;\n const position = this.calculateLogoPosition(viewBoxWidth, viewBoxHeight);\n const logoSize = this.getLogoSize();\n\n let logoSVG = '';\n\n if (imageUrl) {\n // 图片Logo(暂不支持3D效果)\n logoSVG = `\n <image\n href=\"${imageUrl}\"\n x=\"${position.x - logoSize / 2}\"\n y=\"${position.y - logoSize / 2}\"\n width=\"${logoSize}\"\n height=\"${logoSize}\"\n opacity=\"${opacity}\"\n />`;\n } else if (text) {\n // 文本Logo\n const actualFontSize = fontSize ?? Math.max(logoSize / 2, 12);\n\n // 检查是否启用新拟态效果\n if (neumorphism?.enabled) {\n const {\n textColor,\n lightShadowColor,\n darkShadowColor,\n shadowOffset = 6,\n shadowBlur = 12,\n intensity = 0.3,\n raised = true,\n } = neumorphism;\n\n // 自动计算颜色(如果未提供)\n const bgColor = this.backgroundColor !== 'transparent' ? this.backgroundColor : '#f0f0f0';\n const finalTextColor = textColor || bgColor;\n const finalLightShadow = lightShadowColor || this.adjustBrightness(bgColor, 0.2);\n const finalDarkShadow = darkShadowColor || this.adjustBrightness(bgColor, -0.2);\n\n const filterId = `neumorphism-${this._patternId}`;\n\n // 添加新拟态滤镜定义\n logoSVG += this.generateNeumorphismFilter(\n filterId,\n finalLightShadow,\n finalDarkShadow,\n shadowOffset,\n shadowBlur,\n intensity,\n raised\n );\n\n // 创建新拟态文本\n logoSVG += `\n <text\n x=\"${position.x}\"\n y=\"${position.y}\"\n font-family=\"${fontFamily}\"\n font-size=\"${actualFontSize}\"\n font-weight=\"${fontWeight}\"\n fill=\"${finalTextColor}\"\n opacity=\"${opacity}\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n filter=\"url(#${filterId})\"\n >${text}</text>`;\n } else {\n // 普通文本(无3D效果)\n logoSVG = `\n <text\n x=\"${position.x}\"\n y=\"${position.y}\"\n font-family=\"${fontFamily}\"\n font-size=\"${actualFontSize}\"\n font-weight=\"${fontWeight}\"\n fill=\"${color}\"\n opacity=\"${opacity}\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n >${text}</text>`;\n }\n }\n\n return logoSVG;\n }\n\n /**\n * 绘制网格\n */\n protected drawGrid(unit: BackgroundScaleUnit, viewBoxWidth: number, viewBoxHeight: number): void {\n const minor = unit.renderSize;\n if (!this.grid) {\n return;\n }\n const patternSize = this.dotSize * this.zoom;\n\n // 构建SVG内容,根据是否有背景颜色决定是否添加背景矩形\n let svgContent = `<svg width=\"100%\" height=\"100%\">`;\n\n // 如果设置了背景颜色,先绘制背景矩形\n if (this.backgroundColor !== 'transparent') {\n svgContent += `<rect width=\"100%\" height=\"100%\" fill=\"${this.backgroundColor}\"/>`;\n }\n\n // 添加点阵图案\n // 构建圆圈属性,保持与原始实现的兼容性\n const circleAttributes = [\n `cx=\"${patternSize}\"`,\n `cy=\"${patternSize}\"`,\n `r=\"${patternSize}\"`,\n `stroke=\"${this.dotColor}\"`,\n // 只有当 dotFillColor 被明确设置且与 dotColor 不同时才添加 fill 属性\n this.options.dotFillColor && this.dotFillColor !== this.dotColor\n ? `fill=\"${this.dotFillColor}\"`\n : '',\n `fill-opacity=\"${this.dotOpacity}\"`,\n ]\n .filter(Boolean)\n .join(' ');\n\n svgContent += `\n <pattern id=\"${this._patternId}\" width=\"${minor}\" height=\"${minor}\" patternUnits=\"userSpaceOnUse\">\n <circle ${circleAttributes} />\n </pattern>\n <rect width=\"100%\" height=\"100%\" fill=\"url(#${this._patternId})\"/>`;\n\n // 添加Logo\n const logoSVG = this.generateLogoSVG(viewBoxWidth, viewBoxHeight);\n if (logoSVG) {\n svgContent += logoSVG;\n }\n\n svgContent += `</svg>`;\n\n this.grid.innerHTML = svgContent;\n }\n\n protected setSVGStyle(\n svgElement: HTMLElement | undefined,\n style: { width: number; height: number; left: number; top: number }\n ): void {\n if (!svgElement) {\n return;\n }\n\n svgElement.style.width = `${style.width}px`;\n svgElement.style.height = `${style.height}px`;\n svgElement.style.left = `${style.left}px`;\n svgElement.style.top = `${style.top}px`;\n }\n\n /**\n * 获取相对滚动距离\n * @param realScroll\n * @param mod\n */\n protected getScrollDelta(realScroll: number, mod: number): number {\n // 正向滚动不用补差\n if (realScroll >= 0) {\n return realScroll % mod;\n }\n return mod - (Math.abs(realScroll) % mod);\n }\n}\n","import { definePluginCreator } from '@flowgram.ai/core';\n\nimport { BackgroundLayer, BackgroundLayerOptions } from './background-layer';\n\n/**\n * 点位背景插件\n */\nexport const createBackgroundPlugin = definePluginCreator<BackgroundLayerOptions>({\n onInit: (ctx, opts) => {\n ctx.playground.registerLayer(BackgroundLayer, opts);\n },\n});\n"],"mappings":"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","names":[]}
package/dist/index.d.mts CHANGED
@@ -7,6 +7,63 @@ interface BackgroundScaleUnit {
7
7
  zoom: number;
8
8
  }
9
9
  interface BackgroundLayerOptions {
10
+ /** 网格间距,默认 20px */
11
+ gridSize?: number;
12
+ /** 点的大小,默认 1px */
13
+ dotSize?: number;
14
+ /** 点的颜色,默认 "#eceeef" */
15
+ dotColor?: string;
16
+ /** 点的透明度,默认 0.5 */
17
+ dotOpacity?: number;
18
+ /** 背景颜色,默认透明 */
19
+ backgroundColor?: string;
20
+ /** 点的填充颜色,默认与stroke颜色相同 */
21
+ dotFillColor?: string;
22
+ /** Logo 配置 */
23
+ logo?: {
24
+ /** Logo 文本内容 */
25
+ text?: string;
26
+ /** Logo 图片 URL */
27
+ imageUrl?: string;
28
+ /** Logo 位置,默认 'center' */
29
+ position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
30
+ /** Logo 大小,默认 'medium' */
31
+ size?: 'small' | 'medium' | 'large' | number;
32
+ /** Logo 透明度,默认 0.1 */
33
+ opacity?: number;
34
+ /** Logo 颜色(仅文本),默认 "#cccccc" */
35
+ color?: string;
36
+ /** Logo 字体大小(仅文本),默认根据 size 计算 */
37
+ fontSize?: number;
38
+ /** Logo 字体家族(仅文本),默认 'Arial, sans-serif' */
39
+ fontFamily?: string;
40
+ /** Logo 字体粗细(仅文本),默认 'normal' */
41
+ fontWeight?: 'normal' | 'bold' | 'lighter' | number;
42
+ /** 自定义偏移 */
43
+ offset?: {
44
+ x: number;
45
+ y: number;
46
+ };
47
+ /** 新拟态(Neumorphism)效果配置 */
48
+ neumorphism?: {
49
+ /** 是否启用新拟态效果,默认 false */
50
+ enabled?: boolean;
51
+ /** 主要文字颜色,应该与背景色接近,默认自动计算 */
52
+ textColor?: string;
53
+ /** 亮色阴影颜色,默认自动计算(背景色的亮色版本) */
54
+ lightShadowColor?: string;
55
+ /** 暗色阴影颜色,默认自动计算(背景色的暗色版本) */
56
+ darkShadowColor?: string;
57
+ /** 阴影偏移距离,默认 6 */
58
+ shadowOffset?: number;
59
+ /** 阴影模糊半径,默认 12 */
60
+ shadowBlur?: number;
61
+ /** 效果强度(0-1),影响阴影的透明度,默认 0.3 */
62
+ intensity?: number;
63
+ /** 凸起效果(true)还是凹陷效果(false),默认 true */
64
+ raised?: boolean;
65
+ };
66
+ };
10
67
  }
11
68
  /**
12
69
  * dot 网格背景
@@ -17,6 +74,34 @@ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
17
74
  private _patternId;
18
75
  node: HTMLDivElement;
19
76
  grid: HTMLElement;
77
+ /**
78
+ * 获取网格大小配置
79
+ */
80
+ private get gridSize();
81
+ /**
82
+ * 获取点大小配置
83
+ */
84
+ private get dotSize();
85
+ /**
86
+ * 获取点颜色配置
87
+ */
88
+ private get dotColor();
89
+ /**
90
+ * 获取点透明度配置
91
+ */
92
+ private get dotOpacity();
93
+ /**
94
+ * 获取背景颜色配置
95
+ */
96
+ private get backgroundColor();
97
+ /**
98
+ * 获取点填充颜色配置
99
+ */
100
+ private get dotFillColor();
101
+ /**
102
+ * 获取Logo配置
103
+ */
104
+ private get logoConfig();
20
105
  /**
21
106
  * 当前缩放比
22
107
  */
@@ -30,10 +115,34 @@ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
30
115
  * 绘制
31
116
  */
32
117
  autorun(): void;
118
+ /**
119
+ * 计算Logo位置
120
+ */
121
+ private calculateLogoPosition;
122
+ /**
123
+ * 获取Logo大小
124
+ */
125
+ private getLogoSize;
126
+ /**
127
+ * 颜色工具函数:将十六进制颜色转换为RGB
128
+ */
129
+ private hexToRgb;
130
+ /**
131
+ * 颜色工具函数:调整颜色亮度
132
+ */
133
+ private adjustBrightness;
134
+ /**
135
+ * 生成新拟态阴影滤镜
136
+ */
137
+ private generateNeumorphismFilter;
138
+ /**
139
+ * 绘制Logo SVG内容
140
+ */
141
+ private generateLogoSVG;
33
142
  /**
34
143
  * 绘制网格
35
144
  */
36
- protected drawGrid(unit: BackgroundScaleUnit): void;
145
+ protected drawGrid(unit: BackgroundScaleUnit, viewBoxWidth: number, viewBoxHeight: number): void;
37
146
  protected setSVGStyle(svgElement: HTMLElement | undefined, style: {
38
147
  width: number;
39
148
  height: number;
package/dist/index.d.ts CHANGED
@@ -7,6 +7,63 @@ interface BackgroundScaleUnit {
7
7
  zoom: number;
8
8
  }
9
9
  interface BackgroundLayerOptions {
10
+ /** 网格间距,默认 20px */
11
+ gridSize?: number;
12
+ /** 点的大小,默认 1px */
13
+ dotSize?: number;
14
+ /** 点的颜色,默认 "#eceeef" */
15
+ dotColor?: string;
16
+ /** 点的透明度,默认 0.5 */
17
+ dotOpacity?: number;
18
+ /** 背景颜色,默认透明 */
19
+ backgroundColor?: string;
20
+ /** 点的填充颜色,默认与stroke颜色相同 */
21
+ dotFillColor?: string;
22
+ /** Logo 配置 */
23
+ logo?: {
24
+ /** Logo 文本内容 */
25
+ text?: string;
26
+ /** Logo 图片 URL */
27
+ imageUrl?: string;
28
+ /** Logo 位置,默认 'center' */
29
+ position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
30
+ /** Logo 大小,默认 'medium' */
31
+ size?: 'small' | 'medium' | 'large' | number;
32
+ /** Logo 透明度,默认 0.1 */
33
+ opacity?: number;
34
+ /** Logo 颜色(仅文本),默认 "#cccccc" */
35
+ color?: string;
36
+ /** Logo 字体大小(仅文本),默认根据 size 计算 */
37
+ fontSize?: number;
38
+ /** Logo 字体家族(仅文本),默认 'Arial, sans-serif' */
39
+ fontFamily?: string;
40
+ /** Logo 字体粗细(仅文本),默认 'normal' */
41
+ fontWeight?: 'normal' | 'bold' | 'lighter' | number;
42
+ /** 自定义偏移 */
43
+ offset?: {
44
+ x: number;
45
+ y: number;
46
+ };
47
+ /** 新拟态(Neumorphism)效果配置 */
48
+ neumorphism?: {
49
+ /** 是否启用新拟态效果,默认 false */
50
+ enabled?: boolean;
51
+ /** 主要文字颜色,应该与背景色接近,默认自动计算 */
52
+ textColor?: string;
53
+ /** 亮色阴影颜色,默认自动计算(背景色的亮色版本) */
54
+ lightShadowColor?: string;
55
+ /** 暗色阴影颜色,默认自动计算(背景色的暗色版本) */
56
+ darkShadowColor?: string;
57
+ /** 阴影偏移距离,默认 6 */
58
+ shadowOffset?: number;
59
+ /** 阴影模糊半径,默认 12 */
60
+ shadowBlur?: number;
61
+ /** 效果强度(0-1),影响阴影的透明度,默认 0.3 */
62
+ intensity?: number;
63
+ /** 凸起效果(true)还是凹陷效果(false),默认 true */
64
+ raised?: boolean;
65
+ };
66
+ };
10
67
  }
11
68
  /**
12
69
  * dot 网格背景
@@ -17,6 +74,34 @@ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
17
74
  private _patternId;
18
75
  node: HTMLDivElement;
19
76
  grid: HTMLElement;
77
+ /**
78
+ * 获取网格大小配置
79
+ */
80
+ private get gridSize();
81
+ /**
82
+ * 获取点大小配置
83
+ */
84
+ private get dotSize();
85
+ /**
86
+ * 获取点颜色配置
87
+ */
88
+ private get dotColor();
89
+ /**
90
+ * 获取点透明度配置
91
+ */
92
+ private get dotOpacity();
93
+ /**
94
+ * 获取背景颜色配置
95
+ */
96
+ private get backgroundColor();
97
+ /**
98
+ * 获取点填充颜色配置
99
+ */
100
+ private get dotFillColor();
101
+ /**
102
+ * 获取Logo配置
103
+ */
104
+ private get logoConfig();
20
105
  /**
21
106
  * 当前缩放比
22
107
  */
@@ -30,10 +115,34 @@ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
30
115
  * 绘制
31
116
  */
32
117
  autorun(): void;
118
+ /**
119
+ * 计算Logo位置
120
+ */
121
+ private calculateLogoPosition;
122
+ /**
123
+ * 获取Logo大小
124
+ */
125
+ private getLogoSize;
126
+ /**
127
+ * 颜色工具函数:将十六进制颜色转换为RGB
128
+ */
129
+ private hexToRgb;
130
+ /**
131
+ * 颜色工具函数:调整颜色亮度
132
+ */
133
+ private adjustBrightness;
134
+ /**
135
+ * 生成新拟态阴影滤镜
136
+ */
137
+ private generateNeumorphismFilter;
138
+ /**
139
+ * 绘制Logo SVG内容
140
+ */
141
+ private generateLogoSVG;
33
142
  /**
34
143
  * 绘制网格
35
144
  */
36
- protected drawGrid(unit: BackgroundScaleUnit): void;
145
+ protected drawGrid(unit: BackgroundScaleUnit, viewBoxWidth: number, viewBoxHeight: number): void;
37
146
  protected setSVGStyle(svgElement: HTMLElement | undefined, style: {
38
147
  width: number;
39
148
  height: number;
package/dist/index.js CHANGED
@@ -34,11 +34,11 @@ __export(src_exports, {
34
34
  module.exports = __toCommonJS(src_exports);
35
35
 
36
36
  // src/background-layer.tsx
37
- var import_core = require("@flowgram.ai/core");
38
37
  var import_utils = require("@flowgram.ai/utils");
38
+ var import_core = require("@flowgram.ai/core");
39
39
  var PATTERN_PREFIX = "gedit-background-pattern-";
40
- var RENDER_SIZE = 20;
41
- var DOT_SIZE = 1;
40
+ var DEFAULT_RENDER_SIZE = 20;
41
+ var DEFAULT_DOT_SIZE = 1;
42
42
  var id = 0;
43
43
  var BackgroundLayer = class extends import_core.Layer {
44
44
  constructor() {
@@ -47,6 +47,48 @@ var BackgroundLayer = class extends import_core.Layer {
47
47
  this.node = import_utils.domUtils.createDivWithClass("gedit-flow-background-layer");
48
48
  this.grid = document.createElement("div");
49
49
  }
50
+ /**
51
+ * 获取网格大小配置
52
+ */
53
+ get gridSize() {
54
+ return this.options.gridSize ?? DEFAULT_RENDER_SIZE;
55
+ }
56
+ /**
57
+ * 获取点大小配置
58
+ */
59
+ get dotSize() {
60
+ return this.options.dotSize ?? DEFAULT_DOT_SIZE;
61
+ }
62
+ /**
63
+ * 获取点颜色配置
64
+ */
65
+ get dotColor() {
66
+ return this.options.dotColor ?? "#eceeef";
67
+ }
68
+ /**
69
+ * 获取点透明度配置
70
+ */
71
+ get dotOpacity() {
72
+ return this.options.dotOpacity ?? 0.5;
73
+ }
74
+ /**
75
+ * 获取背景颜色配置
76
+ */
77
+ get backgroundColor() {
78
+ return this.options.backgroundColor ?? "transparent";
79
+ }
80
+ /**
81
+ * 获取点填充颜色配置
82
+ */
83
+ get dotFillColor() {
84
+ return this.options.dotFillColor ?? this.dotColor;
85
+ }
86
+ /**
87
+ * 获取Logo配置
88
+ */
89
+ get logoConfig() {
90
+ return this.options.logo;
91
+ }
50
92
  /**
51
93
  * 当前缩放比
52
94
  */
@@ -64,6 +106,9 @@ var BackgroundLayer = class extends import_core.Layer {
64
106
  this.grid.style.position = "relative";
65
107
  this.node.appendChild(this.grid);
66
108
  this.grid.className = "gedit-grid-svg";
109
+ if (this.backgroundColor !== "transparent") {
110
+ this.node.style.backgroundColor = this.backgroundColor;
111
+ }
67
112
  }
68
113
  /**
69
114
  * 最小单元格大小
@@ -71,9 +116,9 @@ var BackgroundLayer = class extends import_core.Layer {
71
116
  getScaleUnit() {
72
117
  const { zoom } = this;
73
118
  return {
74
- realSize: RENDER_SIZE,
75
- // 一个单元格代表的真实大小
76
- renderSize: Math.round(RENDER_SIZE * zoom * 100) / 100,
119
+ realSize: this.gridSize,
120
+ // 使用配置的网格大小
121
+ renderSize: Math.round(this.gridSize * zoom * 100) / 100,
77
122
  // 一个单元格渲染的大小值
78
123
  zoom
79
124
  // 缩放比
@@ -96,7 +141,7 @@ var BackgroundLayer = class extends import_core.Layer {
96
141
  left: scrollX - import_core.SCALE_WIDTH,
97
142
  top: scrollY - import_core.SCALE_WIDTH
98
143
  });
99
- this.drawGrid(scaleUnit);
144
+ this.drawGrid(scaleUnit, viewBoxWidth, viewBoxHeight);
100
145
  this.setSVGStyle(this.grid, {
101
146
  width: viewBoxWidth,
102
147
  height: viewBoxHeight,
@@ -104,29 +149,221 @@ var BackgroundLayer = class extends import_core.Layer {
104
149
  top: import_core.SCALE_WIDTH - scrollYDelta - mod
105
150
  });
106
151
  }
152
+ /**
153
+ * 计算Logo位置
154
+ */
155
+ calculateLogoPosition(viewBoxWidth, viewBoxHeight) {
156
+ if (!this.logoConfig) return { x: 0, y: 0 };
157
+ const { position = "center", offset = { x: 0, y: 0 } } = this.logoConfig;
158
+ const playgroundConfig = this.playgroundConfigEntity.config;
159
+ const scaleUnit = this.getScaleUnit();
160
+ const mod = scaleUnit.renderSize * 10;
161
+ const { scrollX, scrollY } = playgroundConfig;
162
+ const scrollXDelta = this.getScrollDelta(scrollX, mod);
163
+ const scrollYDelta = this.getScrollDelta(scrollY, mod);
164
+ const visibleLeft = mod + scrollXDelta;
165
+ const visibleTop = mod + scrollYDelta;
166
+ const visibleCenterX = visibleLeft + playgroundConfig.width / 2;
167
+ const visibleCenterY = visibleTop + playgroundConfig.height / 2;
168
+ let x = 0, y = 0;
169
+ switch (position) {
170
+ case "center":
171
+ x = visibleCenterX;
172
+ y = visibleCenterY;
173
+ break;
174
+ case "top-left":
175
+ x = visibleLeft + 100;
176
+ y = visibleTop + 100;
177
+ break;
178
+ case "top-right":
179
+ x = visibleLeft + playgroundConfig.width - 100;
180
+ y = visibleTop + 100;
181
+ break;
182
+ case "bottom-left":
183
+ x = visibleLeft + 100;
184
+ y = visibleTop + playgroundConfig.height - 100;
185
+ break;
186
+ case "bottom-right":
187
+ x = visibleLeft + playgroundConfig.width - 100;
188
+ y = visibleTop + playgroundConfig.height - 100;
189
+ break;
190
+ }
191
+ return { x: x + offset.x, y: y + offset.y };
192
+ }
193
+ /**
194
+ * 获取Logo大小
195
+ */
196
+ getLogoSize() {
197
+ if (!this.logoConfig) return 0;
198
+ const { size = "medium" } = this.logoConfig;
199
+ if (typeof size === "number") {
200
+ return size;
201
+ }
202
+ switch (size) {
203
+ case "small":
204
+ return 24;
205
+ case "medium":
206
+ return 48;
207
+ case "large":
208
+ return 72;
209
+ default:
210
+ return 48;
211
+ }
212
+ }
213
+ /**
214
+ * 颜色工具函数:将十六进制颜色转换为RGB
215
+ */
216
+ hexToRgb(hex) {
217
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
218
+ return result ? {
219
+ r: parseInt(result[1], 16),
220
+ g: parseInt(result[2], 16),
221
+ b: parseInt(result[3], 16)
222
+ } : null;
223
+ }
224
+ /**
225
+ * 颜色工具函数:调整颜色亮度
226
+ */
227
+ adjustBrightness(hex, percent) {
228
+ const rgb = this.hexToRgb(hex);
229
+ if (!rgb) return hex;
230
+ const adjust = (value) => {
231
+ const adjusted = Math.round(value + (255 - value) * percent);
232
+ return Math.max(0, Math.min(255, adjusted));
233
+ };
234
+ return `#${adjust(rgb.r).toString(16).padStart(2, "0")}${adjust(rgb.g).toString(16).padStart(2, "0")}${adjust(rgb.b).toString(16).padStart(2, "0")}`;
235
+ }
236
+ /**
237
+ * 生成新拟态阴影滤镜
238
+ */
239
+ generateNeumorphismFilter(filterId, lightShadow, darkShadow, offset, blur, intensity, raised) {
240
+ const lightOffset = raised ? -offset : offset;
241
+ const darkOffset = raised ? offset : -offset;
242
+ return `
243
+ <defs>
244
+ <filter id="${filterId}" x="-50%" y="-50%" width="200%" height="200%">
245
+ <feDropShadow dx="${lightOffset}" dy="${lightOffset}" stdDeviation="${blur}" flood-color="${lightShadow}" flood-opacity="${intensity}"/>
246
+ <feDropShadow dx="${darkOffset}" dy="${darkOffset}" stdDeviation="${blur}" flood-color="${darkShadow}" flood-opacity="${intensity}"/>
247
+ </filter>
248
+ </defs>`;
249
+ }
250
+ /**
251
+ * 绘制Logo SVG内容
252
+ */
253
+ generateLogoSVG(viewBoxWidth, viewBoxHeight) {
254
+ if (!this.logoConfig) return "";
255
+ const {
256
+ text,
257
+ imageUrl,
258
+ opacity = 0.1,
259
+ color = "#cccccc",
260
+ fontSize,
261
+ fontFamily = "Arial, sans-serif",
262
+ fontWeight = "normal",
263
+ neumorphism
264
+ } = this.logoConfig;
265
+ const position = this.calculateLogoPosition(viewBoxWidth, viewBoxHeight);
266
+ const logoSize = this.getLogoSize();
267
+ let logoSVG = "";
268
+ if (imageUrl) {
269
+ logoSVG = `
270
+ <image
271
+ href="${imageUrl}"
272
+ x="${position.x - logoSize / 2}"
273
+ y="${position.y - logoSize / 2}"
274
+ width="${logoSize}"
275
+ height="${logoSize}"
276
+ opacity="${opacity}"
277
+ />`;
278
+ } else if (text) {
279
+ const actualFontSize = fontSize ?? Math.max(logoSize / 2, 12);
280
+ if (neumorphism?.enabled) {
281
+ const {
282
+ textColor,
283
+ lightShadowColor,
284
+ darkShadowColor,
285
+ shadowOffset = 6,
286
+ shadowBlur = 12,
287
+ intensity = 0.3,
288
+ raised = true
289
+ } = neumorphism;
290
+ const bgColor = this.backgroundColor !== "transparent" ? this.backgroundColor : "#f0f0f0";
291
+ const finalTextColor = textColor || bgColor;
292
+ const finalLightShadow = lightShadowColor || this.adjustBrightness(bgColor, 0.2);
293
+ const finalDarkShadow = darkShadowColor || this.adjustBrightness(bgColor, -0.2);
294
+ const filterId = `neumorphism-${this._patternId}`;
295
+ logoSVG += this.generateNeumorphismFilter(
296
+ filterId,
297
+ finalLightShadow,
298
+ finalDarkShadow,
299
+ shadowOffset,
300
+ shadowBlur,
301
+ intensity,
302
+ raised
303
+ );
304
+ logoSVG += `
305
+ <text
306
+ x="${position.x}"
307
+ y="${position.y}"
308
+ font-family="${fontFamily}"
309
+ font-size="${actualFontSize}"
310
+ font-weight="${fontWeight}"
311
+ fill="${finalTextColor}"
312
+ opacity="${opacity}"
313
+ text-anchor="middle"
314
+ dominant-baseline="middle"
315
+ filter="url(#${filterId})"
316
+ >${text}</text>`;
317
+ } else {
318
+ logoSVG = `
319
+ <text
320
+ x="${position.x}"
321
+ y="${position.y}"
322
+ font-family="${fontFamily}"
323
+ font-size="${actualFontSize}"
324
+ font-weight="${fontWeight}"
325
+ fill="${color}"
326
+ opacity="${opacity}"
327
+ text-anchor="middle"
328
+ dominant-baseline="middle"
329
+ >${text}</text>`;
330
+ }
331
+ }
332
+ return logoSVG;
333
+ }
107
334
  /**
108
335
  * 绘制网格
109
336
  */
110
- drawGrid(unit) {
337
+ drawGrid(unit, viewBoxWidth, viewBoxHeight) {
111
338
  const minor = unit.renderSize;
112
339
  if (!this.grid) {
113
340
  return;
114
341
  }
115
- const patternSize = DOT_SIZE * this.zoom;
116
- const newContent = `
117
- <svg width="100%" height="100%">
342
+ const patternSize = this.dotSize * this.zoom;
343
+ let svgContent = `<svg width="100%" height="100%">`;
344
+ if (this.backgroundColor !== "transparent") {
345
+ svgContent += `<rect width="100%" height="100%" fill="${this.backgroundColor}"/>`;
346
+ }
347
+ const circleAttributes = [
348
+ `cx="${patternSize}"`,
349
+ `cy="${patternSize}"`,
350
+ `r="${patternSize}"`,
351
+ `stroke="${this.dotColor}"`,
352
+ // 只有当 dotFillColor 被明确设置且与 dotColor 不同时才添加 fill 属性
353
+ this.options.dotFillColor && this.dotFillColor !== this.dotColor ? `fill="${this.dotFillColor}"` : "",
354
+ `fill-opacity="${this.dotOpacity}"`
355
+ ].filter(Boolean).join(" ");
356
+ svgContent += `
118
357
  <pattern id="${this._patternId}" width="${minor}" height="${minor}" patternUnits="userSpaceOnUse">
119
- <circle
120
- cx="${patternSize}"
121
- cy="${patternSize}"
122
- r="${patternSize}"
123
- stroke="#eceeef"
124
- fill-opacity="0.5"
125
- />
358
+ <circle ${circleAttributes} />
126
359
  </pattern>
127
- <rect width="100%" height="100%" fill="url(#${this._patternId})"/>
128
- </svg>`;
129
- this.grid.innerHTML = newContent;
360
+ <rect width="100%" height="100%" fill="url(#${this._patternId})"/>`;
361
+ const logoSVG = this.generateLogoSVG(viewBoxWidth, viewBoxHeight);
362
+ if (logoSVG) {
363
+ svgContent += logoSVG;
364
+ }
365
+ svgContent += `</svg>`;
366
+ this.grid.innerHTML = svgContent;
130
367
  }
131
368
  setSVGStyle(svgElement, style) {
132
369
  if (!svgElement) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/background-layer.tsx","../src/create-background-plugin.ts"],"sourcesContent":["export * from './background-layer';\nexport * from './create-background-plugin';\n","import { Layer, observeEntity, PlaygroundConfigEntity, SCALE_WIDTH } from '@flowgram.ai/core';\nimport { domUtils } from '@flowgram.ai/utils';\n\ninterface BackgroundScaleUnit {\n realSize: number;\n renderSize: number;\n zoom: number;\n}\n\nconst PATTERN_PREFIX = 'gedit-background-pattern-';\nconst RENDER_SIZE = 20;\nconst DOT_SIZE = 1;\nlet id = 0;\nexport interface BackgroundLayerOptions {\n // 预留配置项目\n}\n/**\n * dot 网格背景\n */\nexport class BackgroundLayer extends Layer<BackgroundLayerOptions> {\n static type = 'WorkflowBackgroundLayer';\n\n @observeEntity(PlaygroundConfigEntity)\n protected playgroundConfigEntity: PlaygroundConfigEntity;\n\n private _patternId = `${PATTERN_PREFIX}${id++}`;\n\n node = domUtils.createDivWithClass('gedit-flow-background-layer');\n\n grid: HTMLElement = document.createElement('div');\n\n /**\n * 当前缩放比\n */\n get zoom(): number {\n return this.config.finalScale;\n }\n\n onReady() {\n const { firstChild } = this.pipelineNode;\n // 背景插入到最下边\n this.pipelineNode.insertBefore(this.node, firstChild);\n // 初始化设置最大 200% 最小 10% 缩放\n this.playgroundConfigEntity.updateConfig({\n minZoom: 0.1,\n maxZoom: 2,\n });\n // 确保点的位置在线条的下方\n this.grid.style.zIndex = '-1';\n this.grid.style.position = 'relative';\n this.node.appendChild(this.grid);\n this.grid.className = 'gedit-grid-svg';\n }\n\n /**\n * 最小单元格大小\n */\n getScaleUnit(): BackgroundScaleUnit {\n const { zoom } = this;\n\n return {\n realSize: RENDER_SIZE, // 一个单元格代表的真实大小\n renderSize: Math.round(RENDER_SIZE * zoom * 100) / 100, // 一个单元格渲染的大小值\n zoom, // 缩放比\n };\n }\n\n /**\n * 绘制\n */\n autorun(): void {\n const playgroundConfig = this.playgroundConfigEntity.config;\n const scaleUnit = this.getScaleUnit();\n const mod = scaleUnit.renderSize * 10;\n const viewBoxWidth = playgroundConfig.width + mod * 2;\n const viewBoxHeight = playgroundConfig.height + mod * 2;\n const { scrollX } = playgroundConfig;\n const { scrollY } = playgroundConfig;\n const scrollXDelta = this.getScrollDelta(scrollX, mod);\n const scrollYDelta = this.getScrollDelta(scrollY, mod);\n domUtils.setStyle(this.node, {\n left: scrollX - SCALE_WIDTH,\n top: scrollY - SCALE_WIDTH,\n });\n this.drawGrid(scaleUnit);\n // 设置网格\n this.setSVGStyle(this.grid, {\n width: viewBoxWidth,\n height: viewBoxHeight,\n left: SCALE_WIDTH - scrollXDelta - mod,\n top: SCALE_WIDTH - scrollYDelta - mod,\n });\n }\n\n /**\n * 绘制网格\n */\n protected drawGrid(unit: BackgroundScaleUnit): void {\n const minor = unit.renderSize;\n if (!this.grid) {\n return;\n }\n const patternSize = DOT_SIZE * this.zoom;\n const newContent = `\n <svg width=\"100%\" height=\"100%\">\n <pattern id=\"${this._patternId}\" width=\"${minor}\" height=\"${minor}\" patternUnits=\"userSpaceOnUse\">\n <circle\n cx=\"${patternSize}\"\n cy=\"${patternSize}\"\n r=\"${patternSize}\"\n stroke=\"#eceeef\"\n fill-opacity=\"0.5\"\n />\n </pattern>\n <rect width=\"100%\" height=\"100%\" fill=\"url(#${this._patternId})\"/>\n </svg>`;\n this.grid.innerHTML = newContent;\n }\n\n protected setSVGStyle(\n svgElement: HTMLElement | undefined,\n style: { width: number; height: number; left: number; top: number },\n ): void {\n if (!svgElement) {\n return;\n }\n\n svgElement.style.width = `${style.width}px`;\n svgElement.style.height = `${style.height}px`;\n svgElement.style.left = `${style.left}px`;\n svgElement.style.top = `${style.top}px`;\n }\n\n /**\n * 获取相对滚动距离\n * @param realScroll\n * @param mod\n */\n protected getScrollDelta(realScroll: number, mod: number): number {\n // 正向滚动不用补差\n if (realScroll >= 0) {\n return realScroll % mod;\n }\n return mod - (Math.abs(realScroll) % mod);\n }\n}\n","import { definePluginCreator } from '@flowgram.ai/core';\n\nimport { BackgroundLayer, BackgroundLayerOptions } from './background-layer';\n\n/**\n * 点位背景插件\n */\nexport const createBackgroundPlugin = definePluginCreator<BackgroundLayerOptions>({\n onInit: (ctx, opts) => {\n ctx.playground.registerLayer(BackgroundLayer, opts);\n },\n});\n"],"mappings":"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","names":["import_core"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/background-layer.tsx","../src/create-background-plugin.ts"],"sourcesContent":["export * from './background-layer';\nexport * from './create-background-plugin';\n","import { domUtils } from '@flowgram.ai/utils';\nimport { Layer, observeEntity, PlaygroundConfigEntity, SCALE_WIDTH } from '@flowgram.ai/core';\n\ninterface BackgroundScaleUnit {\n realSize: number;\n renderSize: number;\n zoom: number;\n}\n\nconst PATTERN_PREFIX = 'gedit-background-pattern-';\nconst DEFAULT_RENDER_SIZE = 20;\nconst DEFAULT_DOT_SIZE = 1;\nlet id = 0;\n\nexport interface BackgroundLayerOptions {\n /** 网格间距,默认 20px */\n gridSize?: number;\n /** 点的大小,默认 1px */\n dotSize?: number;\n /** 点的颜色,默认 \"#eceeef\" */\n dotColor?: string;\n /** 点的透明度,默认 0.5 */\n dotOpacity?: number;\n /** 背景颜色,默认透明 */\n backgroundColor?: string;\n /** 点的填充颜色,默认与stroke颜色相同 */\n dotFillColor?: string;\n /** Logo 配置 */\n logo?: {\n /** Logo 文本内容 */\n text?: string;\n /** Logo 图片 URL */\n imageUrl?: string;\n /** Logo 位置,默认 'center' */\n position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';\n /** Logo 大小,默认 'medium' */\n size?: 'small' | 'medium' | 'large' | number;\n /** Logo 透明度,默认 0.1 */\n opacity?: number;\n /** Logo 颜色(仅文本),默认 \"#cccccc\" */\n color?: string;\n /** Logo 字体大小(仅文本),默认根据 size 计算 */\n fontSize?: number;\n /** Logo 字体家族(仅文本),默认 'Arial, sans-serif' */\n fontFamily?: string;\n /** Logo 字体粗细(仅文本),默认 'normal' */\n fontWeight?: 'normal' | 'bold' | 'lighter' | number;\n /** 自定义偏移 */\n offset?: { x: number; y: number };\n /** 新拟态(Neumorphism)效果配置 */\n neumorphism?: {\n /** 是否启用新拟态效果,默认 false */\n enabled?: boolean;\n /** 主要文字颜色,应该与背景色接近,默认自动计算 */\n textColor?: string;\n /** 亮色阴影颜色,默认自动计算(背景色的亮色版本) */\n lightShadowColor?: string;\n /** 暗色阴影颜色,默认自动计算(背景色的暗色版本) */\n darkShadowColor?: string;\n /** 阴影偏移距离,默认 6 */\n shadowOffset?: number;\n /** 阴影模糊半径,默认 12 */\n shadowBlur?: number;\n /** 效果强度(0-1),影响阴影的透明度,默认 0.3 */\n intensity?: number;\n /** 凸起效果(true)还是凹陷效果(false),默认 true */\n raised?: boolean;\n };\n };\n}\n\n/**\n * dot 网格背景\n */\nexport class BackgroundLayer extends Layer<BackgroundLayerOptions> {\n static type = 'WorkflowBackgroundLayer';\n\n @observeEntity(PlaygroundConfigEntity)\n protected playgroundConfigEntity: PlaygroundConfigEntity;\n\n private _patternId = `${PATTERN_PREFIX}${id++}`;\n\n node = domUtils.createDivWithClass('gedit-flow-background-layer');\n\n grid: HTMLElement = document.createElement('div');\n\n /**\n * 获取网格大小配置\n */\n private get gridSize(): number {\n return this.options.gridSize ?? DEFAULT_RENDER_SIZE;\n }\n\n /**\n * 获取点大小配置\n */\n private get dotSize(): number {\n return this.options.dotSize ?? DEFAULT_DOT_SIZE;\n }\n\n /**\n * 获取点颜色配置\n */\n private get dotColor(): string {\n return this.options.dotColor ?? '#eceeef';\n }\n\n /**\n * 获取点透明度配置\n */\n private get dotOpacity(): number {\n return this.options.dotOpacity ?? 0.5;\n }\n\n /**\n * 获取背景颜色配置\n */\n private get backgroundColor(): string {\n return this.options.backgroundColor ?? 'transparent';\n }\n\n /**\n * 获取点填充颜色配置\n */\n private get dotFillColor(): string {\n return this.options.dotFillColor ?? this.dotColor;\n }\n\n /**\n * 获取Logo配置\n */\n private get logoConfig() {\n return this.options.logo;\n }\n\n /**\n * 当前缩放比\n */\n get zoom(): number {\n return this.config.finalScale;\n }\n\n onReady() {\n const { firstChild } = this.pipelineNode;\n // 背景插入到最下边\n this.pipelineNode.insertBefore(this.node, firstChild);\n // 初始化设置最大 200% 最小 10% 缩放\n this.playgroundConfigEntity.updateConfig({\n minZoom: 0.1,\n maxZoom: 2,\n });\n // 确保点的位置在线条的下方\n this.grid.style.zIndex = '-1';\n this.grid.style.position = 'relative';\n this.node.appendChild(this.grid);\n this.grid.className = 'gedit-grid-svg';\n\n // 设置背景颜色\n if (this.backgroundColor !== 'transparent') {\n this.node.style.backgroundColor = this.backgroundColor;\n }\n }\n\n /**\n * 最小单元格大小\n */\n getScaleUnit(): BackgroundScaleUnit {\n const { zoom } = this;\n\n return {\n realSize: this.gridSize, // 使用配置的网格大小\n renderSize: Math.round(this.gridSize * zoom * 100) / 100, // 一个单元格渲染的大小值\n zoom, // 缩放比\n };\n }\n\n /**\n * 绘制\n */\n autorun(): void {\n const playgroundConfig = this.playgroundConfigEntity.config;\n const scaleUnit = this.getScaleUnit();\n const mod = scaleUnit.renderSize * 10;\n const viewBoxWidth = playgroundConfig.width + mod * 2;\n const viewBoxHeight = playgroundConfig.height + mod * 2;\n const { scrollX } = playgroundConfig;\n const { scrollY } = playgroundConfig;\n const scrollXDelta = this.getScrollDelta(scrollX, mod);\n const scrollYDelta = this.getScrollDelta(scrollY, mod);\n domUtils.setStyle(this.node, {\n left: scrollX - SCALE_WIDTH,\n top: scrollY - SCALE_WIDTH,\n });\n this.drawGrid(scaleUnit, viewBoxWidth, viewBoxHeight);\n // 设置网格\n this.setSVGStyle(this.grid, {\n width: viewBoxWidth,\n height: viewBoxHeight,\n left: SCALE_WIDTH - scrollXDelta - mod,\n top: SCALE_WIDTH - scrollYDelta - mod,\n });\n }\n\n /**\n * 计算Logo位置\n */\n private calculateLogoPosition(\n viewBoxWidth: number,\n viewBoxHeight: number\n ): { x: number; y: number } {\n if (!this.logoConfig) return { x: 0, y: 0 };\n\n const { position = 'center', offset = { x: 0, y: 0 } } = this.logoConfig;\n const playgroundConfig = this.playgroundConfigEntity.config;\n const scaleUnit = this.getScaleUnit();\n const mod = scaleUnit.renderSize * 10;\n\n // 计算SVG内的相对位置,使Logo相对于可视区域固定\n const { scrollX, scrollY } = playgroundConfig;\n const scrollXDelta = this.getScrollDelta(scrollX, mod);\n const scrollYDelta = this.getScrollDelta(scrollY, mod);\n\n // 可视区域的基准点(相对于SVG坐标系)\n const visibleLeft = mod + scrollXDelta;\n const visibleTop = mod + scrollYDelta;\n const visibleCenterX = visibleLeft + playgroundConfig.width / 2;\n const visibleCenterY = visibleTop + playgroundConfig.height / 2;\n\n let x = 0,\n y = 0;\n\n switch (position) {\n case 'center':\n x = visibleCenterX;\n y = visibleCenterY;\n break;\n case 'top-left':\n x = visibleLeft + 100;\n y = visibleTop + 100;\n break;\n case 'top-right':\n x = visibleLeft + playgroundConfig.width - 100;\n y = visibleTop + 100;\n break;\n case 'bottom-left':\n x = visibleLeft + 100;\n y = visibleTop + playgroundConfig.height - 100;\n break;\n case 'bottom-right':\n x = visibleLeft + playgroundConfig.width - 100;\n y = visibleTop + playgroundConfig.height - 100;\n break;\n }\n\n return { x: x + offset.x, y: y + offset.y };\n }\n\n /**\n * 获取Logo大小\n */\n private getLogoSize(): number {\n if (!this.logoConfig) return 0;\n\n const { size = 'medium' } = this.logoConfig;\n\n if (typeof size === 'number') {\n return size;\n }\n\n switch (size) {\n case 'small':\n return 24;\n case 'medium':\n return 48;\n case 'large':\n return 72;\n default:\n return 48;\n }\n }\n\n /**\n * 颜色工具函数:将十六进制颜色转换为RGB\n */\n private hexToRgb(hex: string): { r: number; g: number; b: number } | null {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16),\n }\n : null;\n }\n\n /**\n * 颜色工具函数:调整颜色亮度\n */\n private adjustBrightness(hex: string, percent: number): string {\n const rgb = this.hexToRgb(hex);\n if (!rgb) return hex;\n\n const adjust = (value: number) => {\n const adjusted = Math.round(value + (255 - value) * percent);\n return Math.max(0, Math.min(255, adjusted));\n };\n\n return `#${adjust(rgb.r).toString(16).padStart(2, '0')}${adjust(rgb.g)\n .toString(16)\n .padStart(2, '0')}${adjust(rgb.b).toString(16).padStart(2, '0')}`;\n }\n\n /**\n * 生成新拟态阴影滤镜\n */\n private generateNeumorphismFilter(\n filterId: string,\n lightShadow: string,\n darkShadow: string,\n offset: number,\n blur: number,\n intensity: number,\n raised: boolean\n ): string {\n const lightOffset = raised ? -offset : offset;\n const darkOffset = raised ? offset : -offset;\n\n return `\n <defs>\n <filter id=\"${filterId}\" x=\"-50%\" y=\"-50%\" width=\"200%\" height=\"200%\">\n <feDropShadow dx=\"${lightOffset}\" dy=\"${lightOffset}\" stdDeviation=\"${blur}\" flood-color=\"${lightShadow}\" flood-opacity=\"${intensity}\"/>\n <feDropShadow dx=\"${darkOffset}\" dy=\"${darkOffset}\" stdDeviation=\"${blur}\" flood-color=\"${darkShadow}\" flood-opacity=\"${intensity}\"/>\n </filter>\n </defs>`;\n }\n\n /**\n * 绘制Logo SVG内容\n */\n private generateLogoSVG(viewBoxWidth: number, viewBoxHeight: number): string {\n if (!this.logoConfig) return '';\n\n const {\n text,\n imageUrl,\n opacity = 0.1,\n color = '#cccccc',\n fontSize,\n fontFamily = 'Arial, sans-serif',\n fontWeight = 'normal',\n neumorphism,\n } = this.logoConfig;\n const position = this.calculateLogoPosition(viewBoxWidth, viewBoxHeight);\n const logoSize = this.getLogoSize();\n\n let logoSVG = '';\n\n if (imageUrl) {\n // 图片Logo(暂不支持3D效果)\n logoSVG = `\n <image\n href=\"${imageUrl}\"\n x=\"${position.x - logoSize / 2}\"\n y=\"${position.y - logoSize / 2}\"\n width=\"${logoSize}\"\n height=\"${logoSize}\"\n opacity=\"${opacity}\"\n />`;\n } else if (text) {\n // 文本Logo\n const actualFontSize = fontSize ?? Math.max(logoSize / 2, 12);\n\n // 检查是否启用新拟态效果\n if (neumorphism?.enabled) {\n const {\n textColor,\n lightShadowColor,\n darkShadowColor,\n shadowOffset = 6,\n shadowBlur = 12,\n intensity = 0.3,\n raised = true,\n } = neumorphism;\n\n // 自动计算颜色(如果未提供)\n const bgColor = this.backgroundColor !== 'transparent' ? this.backgroundColor : '#f0f0f0';\n const finalTextColor = textColor || bgColor;\n const finalLightShadow = lightShadowColor || this.adjustBrightness(bgColor, 0.2);\n const finalDarkShadow = darkShadowColor || this.adjustBrightness(bgColor, -0.2);\n\n const filterId = `neumorphism-${this._patternId}`;\n\n // 添加新拟态滤镜定义\n logoSVG += this.generateNeumorphismFilter(\n filterId,\n finalLightShadow,\n finalDarkShadow,\n shadowOffset,\n shadowBlur,\n intensity,\n raised\n );\n\n // 创建新拟态文本\n logoSVG += `\n <text\n x=\"${position.x}\"\n y=\"${position.y}\"\n font-family=\"${fontFamily}\"\n font-size=\"${actualFontSize}\"\n font-weight=\"${fontWeight}\"\n fill=\"${finalTextColor}\"\n opacity=\"${opacity}\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n filter=\"url(#${filterId})\"\n >${text}</text>`;\n } else {\n // 普通文本(无3D效果)\n logoSVG = `\n <text\n x=\"${position.x}\"\n y=\"${position.y}\"\n font-family=\"${fontFamily}\"\n font-size=\"${actualFontSize}\"\n font-weight=\"${fontWeight}\"\n fill=\"${color}\"\n opacity=\"${opacity}\"\n text-anchor=\"middle\"\n dominant-baseline=\"middle\"\n >${text}</text>`;\n }\n }\n\n return logoSVG;\n }\n\n /**\n * 绘制网格\n */\n protected drawGrid(unit: BackgroundScaleUnit, viewBoxWidth: number, viewBoxHeight: number): void {\n const minor = unit.renderSize;\n if (!this.grid) {\n return;\n }\n const patternSize = this.dotSize * this.zoom;\n\n // 构建SVG内容,根据是否有背景颜色决定是否添加背景矩形\n let svgContent = `<svg width=\"100%\" height=\"100%\">`;\n\n // 如果设置了背景颜色,先绘制背景矩形\n if (this.backgroundColor !== 'transparent') {\n svgContent += `<rect width=\"100%\" height=\"100%\" fill=\"${this.backgroundColor}\"/>`;\n }\n\n // 添加点阵图案\n // 构建圆圈属性,保持与原始实现的兼容性\n const circleAttributes = [\n `cx=\"${patternSize}\"`,\n `cy=\"${patternSize}\"`,\n `r=\"${patternSize}\"`,\n `stroke=\"${this.dotColor}\"`,\n // 只有当 dotFillColor 被明确设置且与 dotColor 不同时才添加 fill 属性\n this.options.dotFillColor && this.dotFillColor !== this.dotColor\n ? `fill=\"${this.dotFillColor}\"`\n : '',\n `fill-opacity=\"${this.dotOpacity}\"`,\n ]\n .filter(Boolean)\n .join(' ');\n\n svgContent += `\n <pattern id=\"${this._patternId}\" width=\"${minor}\" height=\"${minor}\" patternUnits=\"userSpaceOnUse\">\n <circle ${circleAttributes} />\n </pattern>\n <rect width=\"100%\" height=\"100%\" fill=\"url(#${this._patternId})\"/>`;\n\n // 添加Logo\n const logoSVG = this.generateLogoSVG(viewBoxWidth, viewBoxHeight);\n if (logoSVG) {\n svgContent += logoSVG;\n }\n\n svgContent += `</svg>`;\n\n this.grid.innerHTML = svgContent;\n }\n\n protected setSVGStyle(\n svgElement: HTMLElement | undefined,\n style: { width: number; height: number; left: number; top: number }\n ): void {\n if (!svgElement) {\n return;\n }\n\n svgElement.style.width = `${style.width}px`;\n svgElement.style.height = `${style.height}px`;\n svgElement.style.left = `${style.left}px`;\n svgElement.style.top = `${style.top}px`;\n }\n\n /**\n * 获取相对滚动距离\n * @param realScroll\n * @param mod\n */\n protected getScrollDelta(realScroll: number, mod: number): number {\n // 正向滚动不用补差\n if (realScroll >= 0) {\n return realScroll % mod;\n }\n return mod - (Math.abs(realScroll) % mod);\n }\n}\n","import { definePluginCreator } from '@flowgram.ai/core';\n\nimport { BackgroundLayer, BackgroundLayerOptions } from './background-layer';\n\n/**\n * 点位背景插件\n */\nexport const createBackgroundPlugin = definePluginCreator<BackgroundLayerOptions>({\n onInit: (ctx, opts) => {\n ctx.playground.registerLayer(BackgroundLayer, opts);\n },\n});\n"],"mappings":"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","names":["import_core"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flowgram.ai/background-plugin",
3
- "version": "0.2.14",
3
+ "version": "0.2.15",
4
4
  "homepage": "https://flowgram.ai/",
5
5
  "repository": "https://github.com/bytedance/flowgram.ai",
6
6
  "license": "MIT",
@@ -18,8 +18,8 @@
18
18
  "dependencies": {
19
19
  "inversify": "^6.0.1",
20
20
  "reflect-metadata": "~0.2.2",
21
- "@flowgram.ai/utils": "0.2.14",
22
- "@flowgram.ai/core": "0.2.14"
21
+ "@flowgram.ai/core": "0.2.15",
22
+ "@flowgram.ai/utils": "0.2.15"
23
23
  },
24
24
  "devDependencies": {
25
25
  "@types/react": "^18",
@@ -29,8 +29,8 @@
29
29
  "tsup": "^8.0.1",
30
30
  "typescript": "^5.0.4",
31
31
  "vitest": "^0.34.6",
32
- "@flowgram.ai/eslint-config": "0.2.14",
33
- "@flowgram.ai/ts-config": "0.2.14"
32
+ "@flowgram.ai/eslint-config": "0.2.15",
33
+ "@flowgram.ai/ts-config": "0.2.15"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "react": ">=16.8",