@flowgram.ai/background-plugin 0.1.0-alpha.10

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.
@@ -0,0 +1,386 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __decorateClass = (decorators, target, key, kind) => {
4
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
5
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
6
+ if (decorator = decorators[i])
7
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
8
+ if (kind && result) __defProp(target, key, result);
9
+ return result;
10
+ };
11
+
12
+ // src/background-layer.tsx
13
+ import { domUtils } from "@flowgram.ai/utils";
14
+ import { Layer, observeEntity, PlaygroundConfigEntity, SCALE_WIDTH } from "@flowgram.ai/core";
15
+ var PATTERN_PREFIX = "gedit-background-pattern-";
16
+ var DEFAULT_RENDER_SIZE = 20;
17
+ var DEFAULT_DOT_SIZE = 1;
18
+ var id = 0;
19
+ var BackgroundConfig = Symbol("BackgroundConfig");
20
+ var BackgroundLayer = class extends Layer {
21
+ constructor() {
22
+ super(...arguments);
23
+ this._patternId = `${PATTERN_PREFIX}${id++}`;
24
+ this.node = domUtils.createDivWithClass("gedit-flow-background-layer");
25
+ this.grid = document.createElement("div");
26
+ }
27
+ /**
28
+ * 获取网格大小配置
29
+ */
30
+ get gridSize() {
31
+ return this.options.gridSize ?? DEFAULT_RENDER_SIZE;
32
+ }
33
+ /**
34
+ * 获取点大小配置
35
+ */
36
+ get dotSize() {
37
+ return this.options.dotSize ?? DEFAULT_DOT_SIZE;
38
+ }
39
+ /**
40
+ * 获取点颜色配置
41
+ */
42
+ get dotColor() {
43
+ return this.options.dotColor ?? "#eceeef";
44
+ }
45
+ /**
46
+ * 获取点透明度配置
47
+ */
48
+ get dotOpacity() {
49
+ return this.options.dotOpacity ?? 0.5;
50
+ }
51
+ /**
52
+ * 获取背景颜色配置
53
+ */
54
+ get backgroundColor() {
55
+ return this.options.backgroundColor ?? "transparent";
56
+ }
57
+ /**
58
+ * 获取点填充颜色配置
59
+ */
60
+ get dotFillColor() {
61
+ return this.options.dotFillColor ?? this.dotColor;
62
+ }
63
+ /**
64
+ * 获取Logo配置
65
+ */
66
+ get logoConfig() {
67
+ return this.options.logo;
68
+ }
69
+ /**
70
+ * 当前缩放比
71
+ */
72
+ get zoom() {
73
+ return this.config.finalScale;
74
+ }
75
+ onReady() {
76
+ const { firstChild } = this.pipelineNode;
77
+ this.pipelineNode.insertBefore(this.node, firstChild);
78
+ this.playgroundConfigEntity.updateConfig({
79
+ minZoom: 0.1,
80
+ maxZoom: 2
81
+ });
82
+ this.grid.style.zIndex = "-1";
83
+ this.grid.style.position = "relative";
84
+ this.node.appendChild(this.grid);
85
+ this.grid.className = "gedit-grid-svg";
86
+ if (this.backgroundColor !== "transparent") {
87
+ this.node.style.backgroundColor = this.backgroundColor;
88
+ }
89
+ }
90
+ /**
91
+ * 最小单元格大小
92
+ */
93
+ getScaleUnit() {
94
+ const { zoom } = this;
95
+ return {
96
+ realSize: this.gridSize,
97
+ // 使用配置的网格大小
98
+ renderSize: Math.round(this.gridSize * zoom * 100) / 100,
99
+ // 一个单元格渲染的大小值
100
+ zoom
101
+ // 缩放比
102
+ };
103
+ }
104
+ /**
105
+ * 绘制
106
+ */
107
+ autorun() {
108
+ const playgroundConfig = this.playgroundConfigEntity.config;
109
+ const scaleUnit = this.getScaleUnit();
110
+ const mod = scaleUnit.renderSize * 10;
111
+ const viewBoxWidth = playgroundConfig.width + mod * 2;
112
+ const viewBoxHeight = playgroundConfig.height + mod * 2;
113
+ const { scrollX } = playgroundConfig;
114
+ const { scrollY } = playgroundConfig;
115
+ const scrollXDelta = this.getScrollDelta(scrollX, mod);
116
+ const scrollYDelta = this.getScrollDelta(scrollY, mod);
117
+ domUtils.setStyle(this.node, {
118
+ left: scrollX - SCALE_WIDTH,
119
+ top: scrollY - SCALE_WIDTH
120
+ });
121
+ this.drawGrid(scaleUnit, viewBoxWidth, viewBoxHeight);
122
+ this.setSVGStyle(this.grid, {
123
+ width: viewBoxWidth,
124
+ height: viewBoxHeight,
125
+ left: SCALE_WIDTH - scrollXDelta - mod,
126
+ top: SCALE_WIDTH - scrollYDelta - mod
127
+ });
128
+ }
129
+ /**
130
+ * 计算Logo位置
131
+ */
132
+ calculateLogoPosition(viewBoxWidth, viewBoxHeight) {
133
+ if (!this.logoConfig) return { x: 0, y: 0 };
134
+ const { position = "center", offset = { x: 0, y: 0 } } = this.logoConfig;
135
+ const playgroundConfig = this.playgroundConfigEntity.config;
136
+ const scaleUnit = this.getScaleUnit();
137
+ const mod = scaleUnit.renderSize * 10;
138
+ const { scrollX, scrollY } = playgroundConfig;
139
+ const scrollXDelta = this.getScrollDelta(scrollX, mod);
140
+ const scrollYDelta = this.getScrollDelta(scrollY, mod);
141
+ const visibleLeft = mod + scrollXDelta;
142
+ const visibleTop = mod + scrollYDelta;
143
+ const visibleCenterX = visibleLeft + playgroundConfig.width / 2;
144
+ const visibleCenterY = visibleTop + playgroundConfig.height / 2;
145
+ let x = 0, y = 0;
146
+ switch (position) {
147
+ case "center":
148
+ x = visibleCenterX;
149
+ y = visibleCenterY;
150
+ break;
151
+ case "top-left":
152
+ x = visibleLeft + 100;
153
+ y = visibleTop + 100;
154
+ break;
155
+ case "top-right":
156
+ x = visibleLeft + playgroundConfig.width - 100;
157
+ y = visibleTop + 100;
158
+ break;
159
+ case "bottom-left":
160
+ x = visibleLeft + 100;
161
+ y = visibleTop + playgroundConfig.height - 100;
162
+ break;
163
+ case "bottom-right":
164
+ x = visibleLeft + playgroundConfig.width - 100;
165
+ y = visibleTop + playgroundConfig.height - 100;
166
+ break;
167
+ }
168
+ return { x: x + offset.x, y: y + offset.y };
169
+ }
170
+ /**
171
+ * 获取Logo大小
172
+ */
173
+ getLogoSize() {
174
+ if (!this.logoConfig) return 0;
175
+ const { size = "medium" } = this.logoConfig;
176
+ if (typeof size === "number") {
177
+ return size;
178
+ }
179
+ switch (size) {
180
+ case "small":
181
+ return 24;
182
+ case "medium":
183
+ return 48;
184
+ case "large":
185
+ return 72;
186
+ default:
187
+ return 48;
188
+ }
189
+ }
190
+ /**
191
+ * 颜色工具函数:将十六进制颜色转换为RGB
192
+ */
193
+ hexToRgb(hex) {
194
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
195
+ return result ? {
196
+ r: parseInt(result[1], 16),
197
+ g: parseInt(result[2], 16),
198
+ b: parseInt(result[3], 16)
199
+ } : null;
200
+ }
201
+ /**
202
+ * 颜色工具函数:调整颜色亮度
203
+ */
204
+ adjustBrightness(hex, percent) {
205
+ const rgb = this.hexToRgb(hex);
206
+ if (!rgb) return hex;
207
+ const adjust = (value) => {
208
+ const adjusted = Math.round(value + (255 - value) * percent);
209
+ return Math.max(0, Math.min(255, adjusted));
210
+ };
211
+ 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")}`;
212
+ }
213
+ /**
214
+ * 生成新拟态阴影滤镜
215
+ */
216
+ generateNeumorphismFilter(filterId, lightShadow, darkShadow, offset, blur, intensity, raised) {
217
+ const lightOffset = raised ? -offset : offset;
218
+ const darkOffset = raised ? offset : -offset;
219
+ return `
220
+ <defs>
221
+ <filter id="${filterId}" x="-50%" y="-50%" width="200%" height="200%">
222
+ <feDropShadow dx="${lightOffset}" dy="${lightOffset}" stdDeviation="${blur}" flood-color="${lightShadow}" flood-opacity="${intensity}"/>
223
+ <feDropShadow dx="${darkOffset}" dy="${darkOffset}" stdDeviation="${blur}" flood-color="${darkShadow}" flood-opacity="${intensity}"/>
224
+ </filter>
225
+ </defs>`;
226
+ }
227
+ /**
228
+ * 绘制Logo SVG内容
229
+ */
230
+ generateLogoSVG(viewBoxWidth, viewBoxHeight) {
231
+ if (!this.logoConfig) return "";
232
+ const {
233
+ text,
234
+ imageUrl,
235
+ opacity = 0.1,
236
+ color = "#cccccc",
237
+ fontSize,
238
+ fontFamily = "Arial, sans-serif",
239
+ fontWeight = "normal",
240
+ neumorphism
241
+ } = this.logoConfig;
242
+ const position = this.calculateLogoPosition(viewBoxWidth, viewBoxHeight);
243
+ const logoSize = this.getLogoSize();
244
+ let logoSVG = "";
245
+ if (imageUrl) {
246
+ logoSVG = `
247
+ <image
248
+ href="${imageUrl}"
249
+ x="${position.x - logoSize / 2}"
250
+ y="${position.y - logoSize / 2}"
251
+ width="${logoSize}"
252
+ height="${logoSize}"
253
+ opacity="${opacity}"
254
+ />`;
255
+ } else if (text) {
256
+ const actualFontSize = fontSize ?? Math.max(logoSize / 2, 12);
257
+ if (neumorphism?.enabled) {
258
+ const {
259
+ textColor,
260
+ lightShadowColor,
261
+ darkShadowColor,
262
+ shadowOffset = 6,
263
+ shadowBlur = 12,
264
+ intensity = 0.3,
265
+ raised = true
266
+ } = neumorphism;
267
+ const bgColor = this.backgroundColor !== "transparent" ? this.backgroundColor : "#f0f0f0";
268
+ const finalTextColor = textColor || bgColor;
269
+ const finalLightShadow = lightShadowColor || this.adjustBrightness(bgColor, 0.2);
270
+ const finalDarkShadow = darkShadowColor || this.adjustBrightness(bgColor, -0.2);
271
+ const filterId = `neumorphism-${this._patternId}`;
272
+ logoSVG += this.generateNeumorphismFilter(
273
+ filterId,
274
+ finalLightShadow,
275
+ finalDarkShadow,
276
+ shadowOffset,
277
+ shadowBlur,
278
+ intensity,
279
+ raised
280
+ );
281
+ logoSVG += `
282
+ <text
283
+ x="${position.x}"
284
+ y="${position.y}"
285
+ font-family="${fontFamily}"
286
+ font-size="${actualFontSize}"
287
+ font-weight="${fontWeight}"
288
+ fill="${finalTextColor}"
289
+ opacity="${opacity}"
290
+ text-anchor="middle"
291
+ dominant-baseline="middle"
292
+ filter="url(#${filterId})"
293
+ >${text}</text>`;
294
+ } else {
295
+ logoSVG = `
296
+ <text
297
+ x="${position.x}"
298
+ y="${position.y}"
299
+ font-family="${fontFamily}"
300
+ font-size="${actualFontSize}"
301
+ font-weight="${fontWeight}"
302
+ fill="${color}"
303
+ opacity="${opacity}"
304
+ text-anchor="middle"
305
+ dominant-baseline="middle"
306
+ >${text}</text>`;
307
+ }
308
+ }
309
+ return logoSVG;
310
+ }
311
+ /**
312
+ * 绘制网格
313
+ */
314
+ drawGrid(unit, viewBoxWidth, viewBoxHeight) {
315
+ const minor = unit.renderSize;
316
+ if (!this.grid) {
317
+ return;
318
+ }
319
+ const patternSize = this.dotSize * this.zoom;
320
+ let svgContent = `<svg width="100%" height="100%">`;
321
+ if (this.backgroundColor !== "transparent") {
322
+ svgContent += `<rect width="100%" height="100%" fill="${this.backgroundColor}"/>`;
323
+ }
324
+ const circleAttributes = [
325
+ `cx="${patternSize}"`,
326
+ `cy="${patternSize}"`,
327
+ `r="${patternSize}"`,
328
+ `stroke="${this.dotColor}"`,
329
+ // 只有当 dotFillColor 被明确设置且与 dotColor 不同时才添加 fill 属性
330
+ this.options.dotFillColor && this.dotFillColor !== this.dotColor ? `fill="${this.dotFillColor}"` : "",
331
+ `fill-opacity="${this.dotOpacity}"`
332
+ ].filter(Boolean).join(" ");
333
+ svgContent += `
334
+ <pattern id="${this._patternId}" width="${minor}" height="${minor}" patternUnits="userSpaceOnUse">
335
+ <circle ${circleAttributes} />
336
+ </pattern>
337
+ <rect width="100%" height="100%" fill="url(#${this._patternId})"/>`;
338
+ const logoSVG = this.generateLogoSVG(viewBoxWidth, viewBoxHeight);
339
+ if (logoSVG) {
340
+ svgContent += logoSVG;
341
+ }
342
+ svgContent += `</svg>`;
343
+ this.grid.innerHTML = svgContent;
344
+ }
345
+ setSVGStyle(svgElement, style) {
346
+ if (!svgElement) {
347
+ return;
348
+ }
349
+ svgElement.style.width = `${style.width}px`;
350
+ svgElement.style.height = `${style.height}px`;
351
+ svgElement.style.left = `${style.left}px`;
352
+ svgElement.style.top = `${style.top}px`;
353
+ }
354
+ /**
355
+ * 获取相对滚动距离
356
+ * @param realScroll
357
+ * @param mod
358
+ */
359
+ getScrollDelta(realScroll, mod) {
360
+ if (realScroll >= 0) {
361
+ return realScroll % mod;
362
+ }
363
+ return mod - Math.abs(realScroll) % mod;
364
+ }
365
+ };
366
+ BackgroundLayer.type = "WorkflowBackgroundLayer";
367
+ __decorateClass([
368
+ observeEntity(PlaygroundConfigEntity)
369
+ ], BackgroundLayer.prototype, "playgroundConfigEntity", 2);
370
+
371
+ // src/create-background-plugin.ts
372
+ import { definePluginCreator } from "@flowgram.ai/core";
373
+ var createBackgroundPlugin = definePluginCreator({
374
+ onBind: (bindConfig, opts) => {
375
+ bindConfig.bind(BackgroundConfig).toConstantValue(opts);
376
+ },
377
+ onInit: (ctx, opts) => {
378
+ ctx.playground.registerLayer(BackgroundLayer, opts);
379
+ }
380
+ });
381
+ export {
382
+ BackgroundConfig,
383
+ BackgroundLayer,
384
+ createBackgroundPlugin
385
+ };
386
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/background-layer.tsx","../../src/create-background-plugin.ts"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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 const BackgroundConfig = Symbol('BackgroundConfig');\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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { definePluginCreator } from '@flowgram.ai/core';\n\nimport { BackgroundConfig, BackgroundLayer, BackgroundLayerOptions } from './background-layer';\n\n/**\n * 点位背景插件\n */\nexport const createBackgroundPlugin = definePluginCreator<BackgroundLayerOptions>({\n onBind: (bindConfig, opts) => {\n bindConfig.bind(BackgroundConfig).toConstantValue(opts);\n },\n onInit: (ctx, opts) => {\n ctx.playground.registerLayer(BackgroundLayer, opts);\n },\n});\n"],"mappings":"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","names":[]}
@@ -0,0 +1,171 @@
1
+ import * as _flowgram_ai_core from '@flowgram.ai/core';
2
+ import { Layer, PlaygroundConfigEntity } from '@flowgram.ai/core';
3
+
4
+ /**
5
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
6
+ * SPDX-License-Identifier: MIT
7
+ */
8
+
9
+ interface BackgroundScaleUnit {
10
+ realSize: number;
11
+ renderSize: number;
12
+ zoom: number;
13
+ }
14
+ declare const BackgroundConfig: unique symbol;
15
+ interface BackgroundLayerOptions {
16
+ /** 网格间距,默认 20px */
17
+ gridSize?: number;
18
+ /** 点的大小,默认 1px */
19
+ dotSize?: number;
20
+ /** 点的颜色,默认 "#eceeef" */
21
+ dotColor?: string;
22
+ /** 点的透明度,默认 0.5 */
23
+ dotOpacity?: number;
24
+ /** 背景颜色,默认透明 */
25
+ backgroundColor?: string;
26
+ /** 点的填充颜色,默认与stroke颜色相同 */
27
+ dotFillColor?: string;
28
+ /** Logo 配置 */
29
+ logo?: {
30
+ /** Logo 文本内容 */
31
+ text?: string;
32
+ /** Logo 图片 URL */
33
+ imageUrl?: string;
34
+ /** Logo 位置,默认 'center' */
35
+ position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
36
+ /** Logo 大小,默认 'medium' */
37
+ size?: 'small' | 'medium' | 'large' | number;
38
+ /** Logo 透明度,默认 0.1 */
39
+ opacity?: number;
40
+ /** Logo 颜色(仅文本),默认 "#cccccc" */
41
+ color?: string;
42
+ /** Logo 字体大小(仅文本),默认根据 size 计算 */
43
+ fontSize?: number;
44
+ /** Logo 字体家族(仅文本),默认 'Arial, sans-serif' */
45
+ fontFamily?: string;
46
+ /** Logo 字体粗细(仅文本),默认 'normal' */
47
+ fontWeight?: 'normal' | 'bold' | 'lighter' | number;
48
+ /** 自定义偏移 */
49
+ offset?: {
50
+ x: number;
51
+ y: number;
52
+ };
53
+ /** 新拟态(Neumorphism)效果配置 */
54
+ neumorphism?: {
55
+ /** 是否启用新拟态效果,默认 false */
56
+ enabled?: boolean;
57
+ /** 主要文字颜色,应该与背景色接近,默认自动计算 */
58
+ textColor?: string;
59
+ /** 亮色阴影颜色,默认自动计算(背景色的亮色版本) */
60
+ lightShadowColor?: string;
61
+ /** 暗色阴影颜色,默认自动计算(背景色的暗色版本) */
62
+ darkShadowColor?: string;
63
+ /** 阴影偏移距离,默认 6 */
64
+ shadowOffset?: number;
65
+ /** 阴影模糊半径,默认 12 */
66
+ shadowBlur?: number;
67
+ /** 效果强度(0-1),影响阴影的透明度,默认 0.3 */
68
+ intensity?: number;
69
+ /** 凸起效果(true)还是凹陷效果(false),默认 true */
70
+ raised?: boolean;
71
+ };
72
+ };
73
+ }
74
+ /**
75
+ * dot 网格背景
76
+ */
77
+ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
78
+ static type: string;
79
+ protected playgroundConfigEntity: PlaygroundConfigEntity;
80
+ private _patternId;
81
+ node: HTMLDivElement;
82
+ grid: HTMLElement;
83
+ /**
84
+ * 获取网格大小配置
85
+ */
86
+ private get gridSize();
87
+ /**
88
+ * 获取点大小配置
89
+ */
90
+ private get dotSize();
91
+ /**
92
+ * 获取点颜色配置
93
+ */
94
+ private get dotColor();
95
+ /**
96
+ * 获取点透明度配置
97
+ */
98
+ private get dotOpacity();
99
+ /**
100
+ * 获取背景颜色配置
101
+ */
102
+ private get backgroundColor();
103
+ /**
104
+ * 获取点填充颜色配置
105
+ */
106
+ private get dotFillColor();
107
+ /**
108
+ * 获取Logo配置
109
+ */
110
+ private get logoConfig();
111
+ /**
112
+ * 当前缩放比
113
+ */
114
+ get zoom(): number;
115
+ onReady(): void;
116
+ /**
117
+ * 最小单元格大小
118
+ */
119
+ getScaleUnit(): BackgroundScaleUnit;
120
+ /**
121
+ * 绘制
122
+ */
123
+ autorun(): void;
124
+ /**
125
+ * 计算Logo位置
126
+ */
127
+ private calculateLogoPosition;
128
+ /**
129
+ * 获取Logo大小
130
+ */
131
+ private getLogoSize;
132
+ /**
133
+ * 颜色工具函数:将十六进制颜色转换为RGB
134
+ */
135
+ private hexToRgb;
136
+ /**
137
+ * 颜色工具函数:调整颜色亮度
138
+ */
139
+ private adjustBrightness;
140
+ /**
141
+ * 生成新拟态阴影滤镜
142
+ */
143
+ private generateNeumorphismFilter;
144
+ /**
145
+ * 绘制Logo SVG内容
146
+ */
147
+ private generateLogoSVG;
148
+ /**
149
+ * 绘制网格
150
+ */
151
+ protected drawGrid(unit: BackgroundScaleUnit, viewBoxWidth: number, viewBoxHeight: number): void;
152
+ protected setSVGStyle(svgElement: HTMLElement | undefined, style: {
153
+ width: number;
154
+ height: number;
155
+ left: number;
156
+ top: number;
157
+ }): void;
158
+ /**
159
+ * 获取相对滚动距离
160
+ * @param realScroll
161
+ * @param mod
162
+ */
163
+ protected getScrollDelta(realScroll: number, mod: number): number;
164
+ }
165
+
166
+ /**
167
+ * 点位背景插件
168
+ */
169
+ declare const createBackgroundPlugin: _flowgram_ai_core.PluginCreator<BackgroundLayerOptions>;
170
+
171
+ export { BackgroundConfig, BackgroundLayer, type BackgroundLayerOptions, createBackgroundPlugin };
@@ -0,0 +1,171 @@
1
+ import * as _flowgram_ai_core from '@flowgram.ai/core';
2
+ import { Layer, PlaygroundConfigEntity } from '@flowgram.ai/core';
3
+
4
+ /**
5
+ * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
6
+ * SPDX-License-Identifier: MIT
7
+ */
8
+
9
+ interface BackgroundScaleUnit {
10
+ realSize: number;
11
+ renderSize: number;
12
+ zoom: number;
13
+ }
14
+ declare const BackgroundConfig: unique symbol;
15
+ interface BackgroundLayerOptions {
16
+ /** 网格间距,默认 20px */
17
+ gridSize?: number;
18
+ /** 点的大小,默认 1px */
19
+ dotSize?: number;
20
+ /** 点的颜色,默认 "#eceeef" */
21
+ dotColor?: string;
22
+ /** 点的透明度,默认 0.5 */
23
+ dotOpacity?: number;
24
+ /** 背景颜色,默认透明 */
25
+ backgroundColor?: string;
26
+ /** 点的填充颜色,默认与stroke颜色相同 */
27
+ dotFillColor?: string;
28
+ /** Logo 配置 */
29
+ logo?: {
30
+ /** Logo 文本内容 */
31
+ text?: string;
32
+ /** Logo 图片 URL */
33
+ imageUrl?: string;
34
+ /** Logo 位置,默认 'center' */
35
+ position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
36
+ /** Logo 大小,默认 'medium' */
37
+ size?: 'small' | 'medium' | 'large' | number;
38
+ /** Logo 透明度,默认 0.1 */
39
+ opacity?: number;
40
+ /** Logo 颜色(仅文本),默认 "#cccccc" */
41
+ color?: string;
42
+ /** Logo 字体大小(仅文本),默认根据 size 计算 */
43
+ fontSize?: number;
44
+ /** Logo 字体家族(仅文本),默认 'Arial, sans-serif' */
45
+ fontFamily?: string;
46
+ /** Logo 字体粗细(仅文本),默认 'normal' */
47
+ fontWeight?: 'normal' | 'bold' | 'lighter' | number;
48
+ /** 自定义偏移 */
49
+ offset?: {
50
+ x: number;
51
+ y: number;
52
+ };
53
+ /** 新拟态(Neumorphism)效果配置 */
54
+ neumorphism?: {
55
+ /** 是否启用新拟态效果,默认 false */
56
+ enabled?: boolean;
57
+ /** 主要文字颜色,应该与背景色接近,默认自动计算 */
58
+ textColor?: string;
59
+ /** 亮色阴影颜色,默认自动计算(背景色的亮色版本) */
60
+ lightShadowColor?: string;
61
+ /** 暗色阴影颜色,默认自动计算(背景色的暗色版本) */
62
+ darkShadowColor?: string;
63
+ /** 阴影偏移距离,默认 6 */
64
+ shadowOffset?: number;
65
+ /** 阴影模糊半径,默认 12 */
66
+ shadowBlur?: number;
67
+ /** 效果强度(0-1),影响阴影的透明度,默认 0.3 */
68
+ intensity?: number;
69
+ /** 凸起效果(true)还是凹陷效果(false),默认 true */
70
+ raised?: boolean;
71
+ };
72
+ };
73
+ }
74
+ /**
75
+ * dot 网格背景
76
+ */
77
+ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
78
+ static type: string;
79
+ protected playgroundConfigEntity: PlaygroundConfigEntity;
80
+ private _patternId;
81
+ node: HTMLDivElement;
82
+ grid: HTMLElement;
83
+ /**
84
+ * 获取网格大小配置
85
+ */
86
+ private get gridSize();
87
+ /**
88
+ * 获取点大小配置
89
+ */
90
+ private get dotSize();
91
+ /**
92
+ * 获取点颜色配置
93
+ */
94
+ private get dotColor();
95
+ /**
96
+ * 获取点透明度配置
97
+ */
98
+ private get dotOpacity();
99
+ /**
100
+ * 获取背景颜色配置
101
+ */
102
+ private get backgroundColor();
103
+ /**
104
+ * 获取点填充颜色配置
105
+ */
106
+ private get dotFillColor();
107
+ /**
108
+ * 获取Logo配置
109
+ */
110
+ private get logoConfig();
111
+ /**
112
+ * 当前缩放比
113
+ */
114
+ get zoom(): number;
115
+ onReady(): void;
116
+ /**
117
+ * 最小单元格大小
118
+ */
119
+ getScaleUnit(): BackgroundScaleUnit;
120
+ /**
121
+ * 绘制
122
+ */
123
+ autorun(): void;
124
+ /**
125
+ * 计算Logo位置
126
+ */
127
+ private calculateLogoPosition;
128
+ /**
129
+ * 获取Logo大小
130
+ */
131
+ private getLogoSize;
132
+ /**
133
+ * 颜色工具函数:将十六进制颜色转换为RGB
134
+ */
135
+ private hexToRgb;
136
+ /**
137
+ * 颜色工具函数:调整颜色亮度
138
+ */
139
+ private adjustBrightness;
140
+ /**
141
+ * 生成新拟态阴影滤镜
142
+ */
143
+ private generateNeumorphismFilter;
144
+ /**
145
+ * 绘制Logo SVG内容
146
+ */
147
+ private generateLogoSVG;
148
+ /**
149
+ * 绘制网格
150
+ */
151
+ protected drawGrid(unit: BackgroundScaleUnit, viewBoxWidth: number, viewBoxHeight: number): void;
152
+ protected setSVGStyle(svgElement: HTMLElement | undefined, style: {
153
+ width: number;
154
+ height: number;
155
+ left: number;
156
+ top: number;
157
+ }): void;
158
+ /**
159
+ * 获取相对滚动距离
160
+ * @param realScroll
161
+ * @param mod
162
+ */
163
+ protected getScrollDelta(realScroll: number, mod: number): number;
164
+ }
165
+
166
+ /**
167
+ * 点位背景插件
168
+ */
169
+ declare const createBackgroundPlugin: _flowgram_ai_core.PluginCreator<BackgroundLayerOptions>;
170
+
171
+ export { BackgroundConfig, BackgroundLayer, type BackgroundLayerOptions, createBackgroundPlugin };
package/dist/index.js ADDED
@@ -0,0 +1,412 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var __decorateClass = (decorators, target, key, kind) => {
20
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
21
+ for (var i = decorators.length - 1, decorator; i >= 0; i--)
22
+ if (decorator = decorators[i])
23
+ result = (kind ? decorator(target, key, result) : decorator(result)) || result;
24
+ if (kind && result) __defProp(target, key, result);
25
+ return result;
26
+ };
27
+
28
+ // src/index.ts
29
+ var src_exports = {};
30
+ __export(src_exports, {
31
+ BackgroundConfig: () => BackgroundConfig,
32
+ BackgroundLayer: () => BackgroundLayer,
33
+ createBackgroundPlugin: () => createBackgroundPlugin
34
+ });
35
+ module.exports = __toCommonJS(src_exports);
36
+
37
+ // src/background-layer.tsx
38
+ var import_utils = require("@flowgram.ai/utils");
39
+ var import_core = require("@flowgram.ai/core");
40
+ var PATTERN_PREFIX = "gedit-background-pattern-";
41
+ var DEFAULT_RENDER_SIZE = 20;
42
+ var DEFAULT_DOT_SIZE = 1;
43
+ var id = 0;
44
+ var BackgroundConfig = Symbol("BackgroundConfig");
45
+ var BackgroundLayer = class extends import_core.Layer {
46
+ constructor() {
47
+ super(...arguments);
48
+ this._patternId = `${PATTERN_PREFIX}${id++}`;
49
+ this.node = import_utils.domUtils.createDivWithClass("gedit-flow-background-layer");
50
+ this.grid = document.createElement("div");
51
+ }
52
+ /**
53
+ * 获取网格大小配置
54
+ */
55
+ get gridSize() {
56
+ return this.options.gridSize ?? DEFAULT_RENDER_SIZE;
57
+ }
58
+ /**
59
+ * 获取点大小配置
60
+ */
61
+ get dotSize() {
62
+ return this.options.dotSize ?? DEFAULT_DOT_SIZE;
63
+ }
64
+ /**
65
+ * 获取点颜色配置
66
+ */
67
+ get dotColor() {
68
+ return this.options.dotColor ?? "#eceeef";
69
+ }
70
+ /**
71
+ * 获取点透明度配置
72
+ */
73
+ get dotOpacity() {
74
+ return this.options.dotOpacity ?? 0.5;
75
+ }
76
+ /**
77
+ * 获取背景颜色配置
78
+ */
79
+ get backgroundColor() {
80
+ return this.options.backgroundColor ?? "transparent";
81
+ }
82
+ /**
83
+ * 获取点填充颜色配置
84
+ */
85
+ get dotFillColor() {
86
+ return this.options.dotFillColor ?? this.dotColor;
87
+ }
88
+ /**
89
+ * 获取Logo配置
90
+ */
91
+ get logoConfig() {
92
+ return this.options.logo;
93
+ }
94
+ /**
95
+ * 当前缩放比
96
+ */
97
+ get zoom() {
98
+ return this.config.finalScale;
99
+ }
100
+ onReady() {
101
+ const { firstChild } = this.pipelineNode;
102
+ this.pipelineNode.insertBefore(this.node, firstChild);
103
+ this.playgroundConfigEntity.updateConfig({
104
+ minZoom: 0.1,
105
+ maxZoom: 2
106
+ });
107
+ this.grid.style.zIndex = "-1";
108
+ this.grid.style.position = "relative";
109
+ this.node.appendChild(this.grid);
110
+ this.grid.className = "gedit-grid-svg";
111
+ if (this.backgroundColor !== "transparent") {
112
+ this.node.style.backgroundColor = this.backgroundColor;
113
+ }
114
+ }
115
+ /**
116
+ * 最小单元格大小
117
+ */
118
+ getScaleUnit() {
119
+ const { zoom } = this;
120
+ return {
121
+ realSize: this.gridSize,
122
+ // 使用配置的网格大小
123
+ renderSize: Math.round(this.gridSize * zoom * 100) / 100,
124
+ // 一个单元格渲染的大小值
125
+ zoom
126
+ // 缩放比
127
+ };
128
+ }
129
+ /**
130
+ * 绘制
131
+ */
132
+ autorun() {
133
+ const playgroundConfig = this.playgroundConfigEntity.config;
134
+ const scaleUnit = this.getScaleUnit();
135
+ const mod = scaleUnit.renderSize * 10;
136
+ const viewBoxWidth = playgroundConfig.width + mod * 2;
137
+ const viewBoxHeight = playgroundConfig.height + mod * 2;
138
+ const { scrollX } = playgroundConfig;
139
+ const { scrollY } = playgroundConfig;
140
+ const scrollXDelta = this.getScrollDelta(scrollX, mod);
141
+ const scrollYDelta = this.getScrollDelta(scrollY, mod);
142
+ import_utils.domUtils.setStyle(this.node, {
143
+ left: scrollX - import_core.SCALE_WIDTH,
144
+ top: scrollY - import_core.SCALE_WIDTH
145
+ });
146
+ this.drawGrid(scaleUnit, viewBoxWidth, viewBoxHeight);
147
+ this.setSVGStyle(this.grid, {
148
+ width: viewBoxWidth,
149
+ height: viewBoxHeight,
150
+ left: import_core.SCALE_WIDTH - scrollXDelta - mod,
151
+ top: import_core.SCALE_WIDTH - scrollYDelta - mod
152
+ });
153
+ }
154
+ /**
155
+ * 计算Logo位置
156
+ */
157
+ calculateLogoPosition(viewBoxWidth, viewBoxHeight) {
158
+ if (!this.logoConfig) return { x: 0, y: 0 };
159
+ const { position = "center", offset = { x: 0, y: 0 } } = this.logoConfig;
160
+ const playgroundConfig = this.playgroundConfigEntity.config;
161
+ const scaleUnit = this.getScaleUnit();
162
+ const mod = scaleUnit.renderSize * 10;
163
+ const { scrollX, scrollY } = playgroundConfig;
164
+ const scrollXDelta = this.getScrollDelta(scrollX, mod);
165
+ const scrollYDelta = this.getScrollDelta(scrollY, mod);
166
+ const visibleLeft = mod + scrollXDelta;
167
+ const visibleTop = mod + scrollYDelta;
168
+ const visibleCenterX = visibleLeft + playgroundConfig.width / 2;
169
+ const visibleCenterY = visibleTop + playgroundConfig.height / 2;
170
+ let x = 0, y = 0;
171
+ switch (position) {
172
+ case "center":
173
+ x = visibleCenterX;
174
+ y = visibleCenterY;
175
+ break;
176
+ case "top-left":
177
+ x = visibleLeft + 100;
178
+ y = visibleTop + 100;
179
+ break;
180
+ case "top-right":
181
+ x = visibleLeft + playgroundConfig.width - 100;
182
+ y = visibleTop + 100;
183
+ break;
184
+ case "bottom-left":
185
+ x = visibleLeft + 100;
186
+ y = visibleTop + playgroundConfig.height - 100;
187
+ break;
188
+ case "bottom-right":
189
+ x = visibleLeft + playgroundConfig.width - 100;
190
+ y = visibleTop + playgroundConfig.height - 100;
191
+ break;
192
+ }
193
+ return { x: x + offset.x, y: y + offset.y };
194
+ }
195
+ /**
196
+ * 获取Logo大小
197
+ */
198
+ getLogoSize() {
199
+ if (!this.logoConfig) return 0;
200
+ const { size = "medium" } = this.logoConfig;
201
+ if (typeof size === "number") {
202
+ return size;
203
+ }
204
+ switch (size) {
205
+ case "small":
206
+ return 24;
207
+ case "medium":
208
+ return 48;
209
+ case "large":
210
+ return 72;
211
+ default:
212
+ return 48;
213
+ }
214
+ }
215
+ /**
216
+ * 颜色工具函数:将十六进制颜色转换为RGB
217
+ */
218
+ hexToRgb(hex) {
219
+ const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
220
+ return result ? {
221
+ r: parseInt(result[1], 16),
222
+ g: parseInt(result[2], 16),
223
+ b: parseInt(result[3], 16)
224
+ } : null;
225
+ }
226
+ /**
227
+ * 颜色工具函数:调整颜色亮度
228
+ */
229
+ adjustBrightness(hex, percent) {
230
+ const rgb = this.hexToRgb(hex);
231
+ if (!rgb) return hex;
232
+ const adjust = (value) => {
233
+ const adjusted = Math.round(value + (255 - value) * percent);
234
+ return Math.max(0, Math.min(255, adjusted));
235
+ };
236
+ 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")}`;
237
+ }
238
+ /**
239
+ * 生成新拟态阴影滤镜
240
+ */
241
+ generateNeumorphismFilter(filterId, lightShadow, darkShadow, offset, blur, intensity, raised) {
242
+ const lightOffset = raised ? -offset : offset;
243
+ const darkOffset = raised ? offset : -offset;
244
+ return `
245
+ <defs>
246
+ <filter id="${filterId}" x="-50%" y="-50%" width="200%" height="200%">
247
+ <feDropShadow dx="${lightOffset}" dy="${lightOffset}" stdDeviation="${blur}" flood-color="${lightShadow}" flood-opacity="${intensity}"/>
248
+ <feDropShadow dx="${darkOffset}" dy="${darkOffset}" stdDeviation="${blur}" flood-color="${darkShadow}" flood-opacity="${intensity}"/>
249
+ </filter>
250
+ </defs>`;
251
+ }
252
+ /**
253
+ * 绘制Logo SVG内容
254
+ */
255
+ generateLogoSVG(viewBoxWidth, viewBoxHeight) {
256
+ if (!this.logoConfig) return "";
257
+ const {
258
+ text,
259
+ imageUrl,
260
+ opacity = 0.1,
261
+ color = "#cccccc",
262
+ fontSize,
263
+ fontFamily = "Arial, sans-serif",
264
+ fontWeight = "normal",
265
+ neumorphism
266
+ } = this.logoConfig;
267
+ const position = this.calculateLogoPosition(viewBoxWidth, viewBoxHeight);
268
+ const logoSize = this.getLogoSize();
269
+ let logoSVG = "";
270
+ if (imageUrl) {
271
+ logoSVG = `
272
+ <image
273
+ href="${imageUrl}"
274
+ x="${position.x - logoSize / 2}"
275
+ y="${position.y - logoSize / 2}"
276
+ width="${logoSize}"
277
+ height="${logoSize}"
278
+ opacity="${opacity}"
279
+ />`;
280
+ } else if (text) {
281
+ const actualFontSize = fontSize ?? Math.max(logoSize / 2, 12);
282
+ if (neumorphism?.enabled) {
283
+ const {
284
+ textColor,
285
+ lightShadowColor,
286
+ darkShadowColor,
287
+ shadowOffset = 6,
288
+ shadowBlur = 12,
289
+ intensity = 0.3,
290
+ raised = true
291
+ } = neumorphism;
292
+ const bgColor = this.backgroundColor !== "transparent" ? this.backgroundColor : "#f0f0f0";
293
+ const finalTextColor = textColor || bgColor;
294
+ const finalLightShadow = lightShadowColor || this.adjustBrightness(bgColor, 0.2);
295
+ const finalDarkShadow = darkShadowColor || this.adjustBrightness(bgColor, -0.2);
296
+ const filterId = `neumorphism-${this._patternId}`;
297
+ logoSVG += this.generateNeumorphismFilter(
298
+ filterId,
299
+ finalLightShadow,
300
+ finalDarkShadow,
301
+ shadowOffset,
302
+ shadowBlur,
303
+ intensity,
304
+ raised
305
+ );
306
+ logoSVG += `
307
+ <text
308
+ x="${position.x}"
309
+ y="${position.y}"
310
+ font-family="${fontFamily}"
311
+ font-size="${actualFontSize}"
312
+ font-weight="${fontWeight}"
313
+ fill="${finalTextColor}"
314
+ opacity="${opacity}"
315
+ text-anchor="middle"
316
+ dominant-baseline="middle"
317
+ filter="url(#${filterId})"
318
+ >${text}</text>`;
319
+ } else {
320
+ logoSVG = `
321
+ <text
322
+ x="${position.x}"
323
+ y="${position.y}"
324
+ font-family="${fontFamily}"
325
+ font-size="${actualFontSize}"
326
+ font-weight="${fontWeight}"
327
+ fill="${color}"
328
+ opacity="${opacity}"
329
+ text-anchor="middle"
330
+ dominant-baseline="middle"
331
+ >${text}</text>`;
332
+ }
333
+ }
334
+ return logoSVG;
335
+ }
336
+ /**
337
+ * 绘制网格
338
+ */
339
+ drawGrid(unit, viewBoxWidth, viewBoxHeight) {
340
+ const minor = unit.renderSize;
341
+ if (!this.grid) {
342
+ return;
343
+ }
344
+ const patternSize = this.dotSize * this.zoom;
345
+ let svgContent = `<svg width="100%" height="100%">`;
346
+ if (this.backgroundColor !== "transparent") {
347
+ svgContent += `<rect width="100%" height="100%" fill="${this.backgroundColor}"/>`;
348
+ }
349
+ const circleAttributes = [
350
+ `cx="${patternSize}"`,
351
+ `cy="${patternSize}"`,
352
+ `r="${patternSize}"`,
353
+ `stroke="${this.dotColor}"`,
354
+ // 只有当 dotFillColor 被明确设置且与 dotColor 不同时才添加 fill 属性
355
+ this.options.dotFillColor && this.dotFillColor !== this.dotColor ? `fill="${this.dotFillColor}"` : "",
356
+ `fill-opacity="${this.dotOpacity}"`
357
+ ].filter(Boolean).join(" ");
358
+ svgContent += `
359
+ <pattern id="${this._patternId}" width="${minor}" height="${minor}" patternUnits="userSpaceOnUse">
360
+ <circle ${circleAttributes} />
361
+ </pattern>
362
+ <rect width="100%" height="100%" fill="url(#${this._patternId})"/>`;
363
+ const logoSVG = this.generateLogoSVG(viewBoxWidth, viewBoxHeight);
364
+ if (logoSVG) {
365
+ svgContent += logoSVG;
366
+ }
367
+ svgContent += `</svg>`;
368
+ this.grid.innerHTML = svgContent;
369
+ }
370
+ setSVGStyle(svgElement, style) {
371
+ if (!svgElement) {
372
+ return;
373
+ }
374
+ svgElement.style.width = `${style.width}px`;
375
+ svgElement.style.height = `${style.height}px`;
376
+ svgElement.style.left = `${style.left}px`;
377
+ svgElement.style.top = `${style.top}px`;
378
+ }
379
+ /**
380
+ * 获取相对滚动距离
381
+ * @param realScroll
382
+ * @param mod
383
+ */
384
+ getScrollDelta(realScroll, mod) {
385
+ if (realScroll >= 0) {
386
+ return realScroll % mod;
387
+ }
388
+ return mod - Math.abs(realScroll) % mod;
389
+ }
390
+ };
391
+ BackgroundLayer.type = "WorkflowBackgroundLayer";
392
+ __decorateClass([
393
+ (0, import_core.observeEntity)(import_core.PlaygroundConfigEntity)
394
+ ], BackgroundLayer.prototype, "playgroundConfigEntity", 2);
395
+
396
+ // src/create-background-plugin.ts
397
+ var import_core2 = require("@flowgram.ai/core");
398
+ var createBackgroundPlugin = (0, import_core2.definePluginCreator)({
399
+ onBind: (bindConfig, opts) => {
400
+ bindConfig.bind(BackgroundConfig).toConstantValue(opts);
401
+ },
402
+ onInit: (ctx, opts) => {
403
+ ctx.playground.registerLayer(BackgroundLayer, opts);
404
+ }
405
+ });
406
+ // Annotate the CommonJS export names for ESM import in node:
407
+ 0 && (module.exports = {
408
+ BackgroundConfig,
409
+ BackgroundLayer,
410
+ createBackgroundPlugin
411
+ });
412
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/background-layer.tsx","../src/create-background-plugin.ts"],"sourcesContent":["/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nexport * from './background-layer';\nexport * from './create-background-plugin';\n","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { 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 const BackgroundConfig = Symbol('BackgroundConfig');\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","/**\n * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates\n * SPDX-License-Identifier: MIT\n */\n\nimport { definePluginCreator } from '@flowgram.ai/core';\n\nimport { BackgroundConfig, BackgroundLayer, BackgroundLayerOptions } from './background-layer';\n\n/**\n * 点位背景插件\n */\nexport const createBackgroundPlugin = definePluginCreator<BackgroundLayerOptions>({\n onBind: (bindConfig, opts) => {\n bindConfig.bind(BackgroundConfig).toConstantValue(opts);\n },\n onInit: (ctx, opts) => {\n ctx.playground.registerLayer(BackgroundLayer, opts);\n },\n});\n"],"mappings":"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","names":["import_core"]}
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "@flowgram.ai/background-plugin",
3
+ "version": "0.1.0-alpha.10",
4
+ "homepage": "https://flowgram.ai/",
5
+ "repository": "https://github.com/bytedance/flowgram.ai",
6
+ "license": "MIT",
7
+ "exports": {
8
+ "types": "./dist/index.d.ts",
9
+ "import": "./dist/esm/index.js",
10
+ "require": "./dist/index.js"
11
+ },
12
+ "main": "./dist/index.js",
13
+ "module": "./dist/esm/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "dependencies": {
19
+ "inversify": "^6.0.1",
20
+ "reflect-metadata": "~0.2.2",
21
+ "@flowgram.ai/core": "0.1.0-alpha.10",
22
+ "@flowgram.ai/utils": "0.1.0-alpha.10"
23
+ },
24
+ "devDependencies": {
25
+ "@types/react": "^18",
26
+ "@types/react-dom": "^18",
27
+ "@vitest/coverage-v8": "^0.32.0",
28
+ "eslint": "^8.54.0",
29
+ "tsup": "^8.0.1",
30
+ "typescript": "^5.0.4",
31
+ "vitest": "^0.34.6",
32
+ "@flowgram.ai/eslint-config": "0.1.0-alpha.10",
33
+ "@flowgram.ai/ts-config": "0.1.0-alpha.10"
34
+ },
35
+ "peerDependencies": {
36
+ "react": ">=16.8",
37
+ "react-dom": ">=16.8"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public",
41
+ "registry": "https://registry.npmjs.org/"
42
+ },
43
+ "scripts": {
44
+ "build": "npm run build:fast -- --dts-resolve",
45
+ "build:fast": "tsup src/index.ts --format cjs,esm --sourcemap --legacy-output",
46
+ "build:watch": "npm run build:fast -- --dts-resolve",
47
+ "clean": "rimraf dist",
48
+ "test": "exit 0",
49
+ "test:cov": "exit 0",
50
+ "ts-check": "tsc --noEmit",
51
+ "watch": "npm run build:fast -- --dts-resolve --watch --ignore-watch dist"
52
+ }
53
+ }