@flowgram.ai/background-plugin 0.2.14 → 0.2.16
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 +263 -21
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +112 -2
- package/dist/index.d.ts +112 -2
- package/dist/index.js +264 -21
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/esm/index.js
CHANGED
|
@@ -10,12 +10,13 @@ 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
|
|
17
|
-
var
|
|
16
|
+
var DEFAULT_RENDER_SIZE = 20;
|
|
17
|
+
var DEFAULT_DOT_SIZE = 1;
|
|
18
18
|
var id = 0;
|
|
19
|
+
var BackgroundConfig = Symbol("BackgroundConfig");
|
|
19
20
|
var BackgroundLayer = class extends Layer {
|
|
20
21
|
constructor() {
|
|
21
22
|
super(...arguments);
|
|
@@ -23,6 +24,48 @@ var BackgroundLayer = class extends Layer {
|
|
|
23
24
|
this.node = domUtils.createDivWithClass("gedit-flow-background-layer");
|
|
24
25
|
this.grid = document.createElement("div");
|
|
25
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
|
+
}
|
|
26
69
|
/**
|
|
27
70
|
* 当前缩放比
|
|
28
71
|
*/
|
|
@@ -40,6 +83,9 @@ var BackgroundLayer = class extends Layer {
|
|
|
40
83
|
this.grid.style.position = "relative";
|
|
41
84
|
this.node.appendChild(this.grid);
|
|
42
85
|
this.grid.className = "gedit-grid-svg";
|
|
86
|
+
if (this.backgroundColor !== "transparent") {
|
|
87
|
+
this.node.style.backgroundColor = this.backgroundColor;
|
|
88
|
+
}
|
|
43
89
|
}
|
|
44
90
|
/**
|
|
45
91
|
* 最小单元格大小
|
|
@@ -47,9 +93,9 @@ var BackgroundLayer = class extends Layer {
|
|
|
47
93
|
getScaleUnit() {
|
|
48
94
|
const { zoom } = this;
|
|
49
95
|
return {
|
|
50
|
-
realSize:
|
|
51
|
-
//
|
|
52
|
-
renderSize: Math.round(
|
|
96
|
+
realSize: this.gridSize,
|
|
97
|
+
// 使用配置的网格大小
|
|
98
|
+
renderSize: Math.round(this.gridSize * zoom * 100) / 100,
|
|
53
99
|
// 一个单元格渲染的大小值
|
|
54
100
|
zoom
|
|
55
101
|
// 缩放比
|
|
@@ -72,7 +118,7 @@ var BackgroundLayer = class extends Layer {
|
|
|
72
118
|
left: scrollX - SCALE_WIDTH,
|
|
73
119
|
top: scrollY - SCALE_WIDTH
|
|
74
120
|
});
|
|
75
|
-
this.drawGrid(scaleUnit);
|
|
121
|
+
this.drawGrid(scaleUnit, viewBoxWidth, viewBoxHeight);
|
|
76
122
|
this.setSVGStyle(this.grid, {
|
|
77
123
|
width: viewBoxWidth,
|
|
78
124
|
height: viewBoxHeight,
|
|
@@ -80,29 +126,221 @@ var BackgroundLayer = class extends Layer {
|
|
|
80
126
|
top: SCALE_WIDTH - scrollYDelta - mod
|
|
81
127
|
});
|
|
82
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
|
+
}
|
|
83
311
|
/**
|
|
84
312
|
* 绘制网格
|
|
85
313
|
*/
|
|
86
|
-
drawGrid(unit) {
|
|
314
|
+
drawGrid(unit, viewBoxWidth, viewBoxHeight) {
|
|
87
315
|
const minor = unit.renderSize;
|
|
88
316
|
if (!this.grid) {
|
|
89
317
|
return;
|
|
90
318
|
}
|
|
91
|
-
const patternSize =
|
|
92
|
-
|
|
93
|
-
|
|
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 += `
|
|
94
334
|
<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
|
-
/>
|
|
335
|
+
<circle ${circleAttributes} />
|
|
102
336
|
</pattern>
|
|
103
|
-
<rect width="100%" height="100%" fill="url(#${this._patternId})"
|
|
104
|
-
|
|
105
|
-
|
|
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;
|
|
106
344
|
}
|
|
107
345
|
setSVGStyle(svgElement, style) {
|
|
108
346
|
if (!svgElement) {
|
|
@@ -133,11 +371,15 @@ __decorateClass([
|
|
|
133
371
|
// src/create-background-plugin.ts
|
|
134
372
|
import { definePluginCreator } from "@flowgram.ai/core";
|
|
135
373
|
var createBackgroundPlugin = definePluginCreator({
|
|
374
|
+
onBind: (bindConfig, opts) => {
|
|
375
|
+
bindConfig.bind(BackgroundConfig).toConstantValue(opts);
|
|
376
|
+
},
|
|
136
377
|
onInit: (ctx, opts) => {
|
|
137
378
|
ctx.playground.registerLayer(BackgroundLayer, opts);
|
|
138
379
|
}
|
|
139
380
|
});
|
|
140
381
|
export {
|
|
382
|
+
BackgroundConfig,
|
|
141
383
|
BackgroundLayer,
|
|
142
384
|
createBackgroundPlugin
|
|
143
385
|
};
|
package/dist/esm/index.js.map
CHANGED
|
@@ -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":"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","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 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","import { 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":[]}
|
package/dist/index.d.mts
CHANGED
|
@@ -6,7 +6,65 @@ interface BackgroundScaleUnit {
|
|
|
6
6
|
renderSize: number;
|
|
7
7
|
zoom: number;
|
|
8
8
|
}
|
|
9
|
+
declare const BackgroundConfig: unique symbol;
|
|
9
10
|
interface BackgroundLayerOptions {
|
|
11
|
+
/** 网格间距,默认 20px */
|
|
12
|
+
gridSize?: number;
|
|
13
|
+
/** 点的大小,默认 1px */
|
|
14
|
+
dotSize?: number;
|
|
15
|
+
/** 点的颜色,默认 "#eceeef" */
|
|
16
|
+
dotColor?: string;
|
|
17
|
+
/** 点的透明度,默认 0.5 */
|
|
18
|
+
dotOpacity?: number;
|
|
19
|
+
/** 背景颜色,默认透明 */
|
|
20
|
+
backgroundColor?: string;
|
|
21
|
+
/** 点的填充颜色,默认与stroke颜色相同 */
|
|
22
|
+
dotFillColor?: string;
|
|
23
|
+
/** Logo 配置 */
|
|
24
|
+
logo?: {
|
|
25
|
+
/** Logo 文本内容 */
|
|
26
|
+
text?: string;
|
|
27
|
+
/** Logo 图片 URL */
|
|
28
|
+
imageUrl?: string;
|
|
29
|
+
/** Logo 位置,默认 'center' */
|
|
30
|
+
position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
31
|
+
/** Logo 大小,默认 'medium' */
|
|
32
|
+
size?: 'small' | 'medium' | 'large' | number;
|
|
33
|
+
/** Logo 透明度,默认 0.1 */
|
|
34
|
+
opacity?: number;
|
|
35
|
+
/** Logo 颜色(仅文本),默认 "#cccccc" */
|
|
36
|
+
color?: string;
|
|
37
|
+
/** Logo 字体大小(仅文本),默认根据 size 计算 */
|
|
38
|
+
fontSize?: number;
|
|
39
|
+
/** Logo 字体家族(仅文本),默认 'Arial, sans-serif' */
|
|
40
|
+
fontFamily?: string;
|
|
41
|
+
/** Logo 字体粗细(仅文本),默认 'normal' */
|
|
42
|
+
fontWeight?: 'normal' | 'bold' | 'lighter' | number;
|
|
43
|
+
/** 自定义偏移 */
|
|
44
|
+
offset?: {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
};
|
|
48
|
+
/** 新拟态(Neumorphism)效果配置 */
|
|
49
|
+
neumorphism?: {
|
|
50
|
+
/** 是否启用新拟态效果,默认 false */
|
|
51
|
+
enabled?: boolean;
|
|
52
|
+
/** 主要文字颜色,应该与背景色接近,默认自动计算 */
|
|
53
|
+
textColor?: string;
|
|
54
|
+
/** 亮色阴影颜色,默认自动计算(背景色的亮色版本) */
|
|
55
|
+
lightShadowColor?: string;
|
|
56
|
+
/** 暗色阴影颜色,默认自动计算(背景色的暗色版本) */
|
|
57
|
+
darkShadowColor?: string;
|
|
58
|
+
/** 阴影偏移距离,默认 6 */
|
|
59
|
+
shadowOffset?: number;
|
|
60
|
+
/** 阴影模糊半径,默认 12 */
|
|
61
|
+
shadowBlur?: number;
|
|
62
|
+
/** 效果强度(0-1),影响阴影的透明度,默认 0.3 */
|
|
63
|
+
intensity?: number;
|
|
64
|
+
/** 凸起效果(true)还是凹陷效果(false),默认 true */
|
|
65
|
+
raised?: boolean;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
10
68
|
}
|
|
11
69
|
/**
|
|
12
70
|
* dot 网格背景
|
|
@@ -17,6 +75,34 @@ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
|
|
|
17
75
|
private _patternId;
|
|
18
76
|
node: HTMLDivElement;
|
|
19
77
|
grid: HTMLElement;
|
|
78
|
+
/**
|
|
79
|
+
* 获取网格大小配置
|
|
80
|
+
*/
|
|
81
|
+
private get gridSize();
|
|
82
|
+
/**
|
|
83
|
+
* 获取点大小配置
|
|
84
|
+
*/
|
|
85
|
+
private get dotSize();
|
|
86
|
+
/**
|
|
87
|
+
* 获取点颜色配置
|
|
88
|
+
*/
|
|
89
|
+
private get dotColor();
|
|
90
|
+
/**
|
|
91
|
+
* 获取点透明度配置
|
|
92
|
+
*/
|
|
93
|
+
private get dotOpacity();
|
|
94
|
+
/**
|
|
95
|
+
* 获取背景颜色配置
|
|
96
|
+
*/
|
|
97
|
+
private get backgroundColor();
|
|
98
|
+
/**
|
|
99
|
+
* 获取点填充颜色配置
|
|
100
|
+
*/
|
|
101
|
+
private get dotFillColor();
|
|
102
|
+
/**
|
|
103
|
+
* 获取Logo配置
|
|
104
|
+
*/
|
|
105
|
+
private get logoConfig();
|
|
20
106
|
/**
|
|
21
107
|
* 当前缩放比
|
|
22
108
|
*/
|
|
@@ -30,10 +116,34 @@ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
|
|
|
30
116
|
* 绘制
|
|
31
117
|
*/
|
|
32
118
|
autorun(): void;
|
|
119
|
+
/**
|
|
120
|
+
* 计算Logo位置
|
|
121
|
+
*/
|
|
122
|
+
private calculateLogoPosition;
|
|
123
|
+
/**
|
|
124
|
+
* 获取Logo大小
|
|
125
|
+
*/
|
|
126
|
+
private getLogoSize;
|
|
127
|
+
/**
|
|
128
|
+
* 颜色工具函数:将十六进制颜色转换为RGB
|
|
129
|
+
*/
|
|
130
|
+
private hexToRgb;
|
|
131
|
+
/**
|
|
132
|
+
* 颜色工具函数:调整颜色亮度
|
|
133
|
+
*/
|
|
134
|
+
private adjustBrightness;
|
|
135
|
+
/**
|
|
136
|
+
* 生成新拟态阴影滤镜
|
|
137
|
+
*/
|
|
138
|
+
private generateNeumorphismFilter;
|
|
139
|
+
/**
|
|
140
|
+
* 绘制Logo SVG内容
|
|
141
|
+
*/
|
|
142
|
+
private generateLogoSVG;
|
|
33
143
|
/**
|
|
34
144
|
* 绘制网格
|
|
35
145
|
*/
|
|
36
|
-
protected drawGrid(unit: BackgroundScaleUnit): void;
|
|
146
|
+
protected drawGrid(unit: BackgroundScaleUnit, viewBoxWidth: number, viewBoxHeight: number): void;
|
|
37
147
|
protected setSVGStyle(svgElement: HTMLElement | undefined, style: {
|
|
38
148
|
width: number;
|
|
39
149
|
height: number;
|
|
@@ -53,4 +163,4 @@ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
|
|
|
53
163
|
*/
|
|
54
164
|
declare const createBackgroundPlugin: _flowgram_ai_core.PluginCreator<BackgroundLayerOptions>;
|
|
55
165
|
|
|
56
|
-
export { BackgroundLayer, type BackgroundLayerOptions, createBackgroundPlugin };
|
|
166
|
+
export { BackgroundConfig, BackgroundLayer, type BackgroundLayerOptions, createBackgroundPlugin };
|
package/dist/index.d.ts
CHANGED
|
@@ -6,7 +6,65 @@ interface BackgroundScaleUnit {
|
|
|
6
6
|
renderSize: number;
|
|
7
7
|
zoom: number;
|
|
8
8
|
}
|
|
9
|
+
declare const BackgroundConfig: unique symbol;
|
|
9
10
|
interface BackgroundLayerOptions {
|
|
11
|
+
/** 网格间距,默认 20px */
|
|
12
|
+
gridSize?: number;
|
|
13
|
+
/** 点的大小,默认 1px */
|
|
14
|
+
dotSize?: number;
|
|
15
|
+
/** 点的颜色,默认 "#eceeef" */
|
|
16
|
+
dotColor?: string;
|
|
17
|
+
/** 点的透明度,默认 0.5 */
|
|
18
|
+
dotOpacity?: number;
|
|
19
|
+
/** 背景颜色,默认透明 */
|
|
20
|
+
backgroundColor?: string;
|
|
21
|
+
/** 点的填充颜色,默认与stroke颜色相同 */
|
|
22
|
+
dotFillColor?: string;
|
|
23
|
+
/** Logo 配置 */
|
|
24
|
+
logo?: {
|
|
25
|
+
/** Logo 文本内容 */
|
|
26
|
+
text?: string;
|
|
27
|
+
/** Logo 图片 URL */
|
|
28
|
+
imageUrl?: string;
|
|
29
|
+
/** Logo 位置,默认 'center' */
|
|
30
|
+
position?: 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
|
31
|
+
/** Logo 大小,默认 'medium' */
|
|
32
|
+
size?: 'small' | 'medium' | 'large' | number;
|
|
33
|
+
/** Logo 透明度,默认 0.1 */
|
|
34
|
+
opacity?: number;
|
|
35
|
+
/** Logo 颜色(仅文本),默认 "#cccccc" */
|
|
36
|
+
color?: string;
|
|
37
|
+
/** Logo 字体大小(仅文本),默认根据 size 计算 */
|
|
38
|
+
fontSize?: number;
|
|
39
|
+
/** Logo 字体家族(仅文本),默认 'Arial, sans-serif' */
|
|
40
|
+
fontFamily?: string;
|
|
41
|
+
/** Logo 字体粗细(仅文本),默认 'normal' */
|
|
42
|
+
fontWeight?: 'normal' | 'bold' | 'lighter' | number;
|
|
43
|
+
/** 自定义偏移 */
|
|
44
|
+
offset?: {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
};
|
|
48
|
+
/** 新拟态(Neumorphism)效果配置 */
|
|
49
|
+
neumorphism?: {
|
|
50
|
+
/** 是否启用新拟态效果,默认 false */
|
|
51
|
+
enabled?: boolean;
|
|
52
|
+
/** 主要文字颜色,应该与背景色接近,默认自动计算 */
|
|
53
|
+
textColor?: string;
|
|
54
|
+
/** 亮色阴影颜色,默认自动计算(背景色的亮色版本) */
|
|
55
|
+
lightShadowColor?: string;
|
|
56
|
+
/** 暗色阴影颜色,默认自动计算(背景色的暗色版本) */
|
|
57
|
+
darkShadowColor?: string;
|
|
58
|
+
/** 阴影偏移距离,默认 6 */
|
|
59
|
+
shadowOffset?: number;
|
|
60
|
+
/** 阴影模糊半径,默认 12 */
|
|
61
|
+
shadowBlur?: number;
|
|
62
|
+
/** 效果强度(0-1),影响阴影的透明度,默认 0.3 */
|
|
63
|
+
intensity?: number;
|
|
64
|
+
/** 凸起效果(true)还是凹陷效果(false),默认 true */
|
|
65
|
+
raised?: boolean;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
10
68
|
}
|
|
11
69
|
/**
|
|
12
70
|
* dot 网格背景
|
|
@@ -17,6 +75,34 @@ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
|
|
|
17
75
|
private _patternId;
|
|
18
76
|
node: HTMLDivElement;
|
|
19
77
|
grid: HTMLElement;
|
|
78
|
+
/**
|
|
79
|
+
* 获取网格大小配置
|
|
80
|
+
*/
|
|
81
|
+
private get gridSize();
|
|
82
|
+
/**
|
|
83
|
+
* 获取点大小配置
|
|
84
|
+
*/
|
|
85
|
+
private get dotSize();
|
|
86
|
+
/**
|
|
87
|
+
* 获取点颜色配置
|
|
88
|
+
*/
|
|
89
|
+
private get dotColor();
|
|
90
|
+
/**
|
|
91
|
+
* 获取点透明度配置
|
|
92
|
+
*/
|
|
93
|
+
private get dotOpacity();
|
|
94
|
+
/**
|
|
95
|
+
* 获取背景颜色配置
|
|
96
|
+
*/
|
|
97
|
+
private get backgroundColor();
|
|
98
|
+
/**
|
|
99
|
+
* 获取点填充颜色配置
|
|
100
|
+
*/
|
|
101
|
+
private get dotFillColor();
|
|
102
|
+
/**
|
|
103
|
+
* 获取Logo配置
|
|
104
|
+
*/
|
|
105
|
+
private get logoConfig();
|
|
20
106
|
/**
|
|
21
107
|
* 当前缩放比
|
|
22
108
|
*/
|
|
@@ -30,10 +116,34 @@ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
|
|
|
30
116
|
* 绘制
|
|
31
117
|
*/
|
|
32
118
|
autorun(): void;
|
|
119
|
+
/**
|
|
120
|
+
* 计算Logo位置
|
|
121
|
+
*/
|
|
122
|
+
private calculateLogoPosition;
|
|
123
|
+
/**
|
|
124
|
+
* 获取Logo大小
|
|
125
|
+
*/
|
|
126
|
+
private getLogoSize;
|
|
127
|
+
/**
|
|
128
|
+
* 颜色工具函数:将十六进制颜色转换为RGB
|
|
129
|
+
*/
|
|
130
|
+
private hexToRgb;
|
|
131
|
+
/**
|
|
132
|
+
* 颜色工具函数:调整颜色亮度
|
|
133
|
+
*/
|
|
134
|
+
private adjustBrightness;
|
|
135
|
+
/**
|
|
136
|
+
* 生成新拟态阴影滤镜
|
|
137
|
+
*/
|
|
138
|
+
private generateNeumorphismFilter;
|
|
139
|
+
/**
|
|
140
|
+
* 绘制Logo SVG内容
|
|
141
|
+
*/
|
|
142
|
+
private generateLogoSVG;
|
|
33
143
|
/**
|
|
34
144
|
* 绘制网格
|
|
35
145
|
*/
|
|
36
|
-
protected drawGrid(unit: BackgroundScaleUnit): void;
|
|
146
|
+
protected drawGrid(unit: BackgroundScaleUnit, viewBoxWidth: number, viewBoxHeight: number): void;
|
|
37
147
|
protected setSVGStyle(svgElement: HTMLElement | undefined, style: {
|
|
38
148
|
width: number;
|
|
39
149
|
height: number;
|
|
@@ -53,4 +163,4 @@ declare class BackgroundLayer extends Layer<BackgroundLayerOptions> {
|
|
|
53
163
|
*/
|
|
54
164
|
declare const createBackgroundPlugin: _flowgram_ai_core.PluginCreator<BackgroundLayerOptions>;
|
|
55
165
|
|
|
56
|
-
export { BackgroundLayer, type BackgroundLayerOptions, createBackgroundPlugin };
|
|
166
|
+
export { BackgroundConfig, BackgroundLayer, type BackgroundLayerOptions, createBackgroundPlugin };
|
package/dist/index.js
CHANGED
|
@@ -28,18 +28,20 @@ var __decorateClass = (decorators, target, key, kind) => {
|
|
|
28
28
|
// src/index.ts
|
|
29
29
|
var src_exports = {};
|
|
30
30
|
__export(src_exports, {
|
|
31
|
+
BackgroundConfig: () => BackgroundConfig,
|
|
31
32
|
BackgroundLayer: () => BackgroundLayer,
|
|
32
33
|
createBackgroundPlugin: () => createBackgroundPlugin
|
|
33
34
|
});
|
|
34
35
|
module.exports = __toCommonJS(src_exports);
|
|
35
36
|
|
|
36
37
|
// src/background-layer.tsx
|
|
37
|
-
var import_core = require("@flowgram.ai/core");
|
|
38
38
|
var import_utils = require("@flowgram.ai/utils");
|
|
39
|
+
var import_core = require("@flowgram.ai/core");
|
|
39
40
|
var PATTERN_PREFIX = "gedit-background-pattern-";
|
|
40
|
-
var
|
|
41
|
-
var
|
|
41
|
+
var DEFAULT_RENDER_SIZE = 20;
|
|
42
|
+
var DEFAULT_DOT_SIZE = 1;
|
|
42
43
|
var id = 0;
|
|
44
|
+
var BackgroundConfig = Symbol("BackgroundConfig");
|
|
43
45
|
var BackgroundLayer = class extends import_core.Layer {
|
|
44
46
|
constructor() {
|
|
45
47
|
super(...arguments);
|
|
@@ -47,6 +49,48 @@ var BackgroundLayer = class extends import_core.Layer {
|
|
|
47
49
|
this.node = import_utils.domUtils.createDivWithClass("gedit-flow-background-layer");
|
|
48
50
|
this.grid = document.createElement("div");
|
|
49
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
|
+
}
|
|
50
94
|
/**
|
|
51
95
|
* 当前缩放比
|
|
52
96
|
*/
|
|
@@ -64,6 +108,9 @@ var BackgroundLayer = class extends import_core.Layer {
|
|
|
64
108
|
this.grid.style.position = "relative";
|
|
65
109
|
this.node.appendChild(this.grid);
|
|
66
110
|
this.grid.className = "gedit-grid-svg";
|
|
111
|
+
if (this.backgroundColor !== "transparent") {
|
|
112
|
+
this.node.style.backgroundColor = this.backgroundColor;
|
|
113
|
+
}
|
|
67
114
|
}
|
|
68
115
|
/**
|
|
69
116
|
* 最小单元格大小
|
|
@@ -71,9 +118,9 @@ var BackgroundLayer = class extends import_core.Layer {
|
|
|
71
118
|
getScaleUnit() {
|
|
72
119
|
const { zoom } = this;
|
|
73
120
|
return {
|
|
74
|
-
realSize:
|
|
75
|
-
//
|
|
76
|
-
renderSize: Math.round(
|
|
121
|
+
realSize: this.gridSize,
|
|
122
|
+
// 使用配置的网格大小
|
|
123
|
+
renderSize: Math.round(this.gridSize * zoom * 100) / 100,
|
|
77
124
|
// 一个单元格渲染的大小值
|
|
78
125
|
zoom
|
|
79
126
|
// 缩放比
|
|
@@ -96,7 +143,7 @@ var BackgroundLayer = class extends import_core.Layer {
|
|
|
96
143
|
left: scrollX - import_core.SCALE_WIDTH,
|
|
97
144
|
top: scrollY - import_core.SCALE_WIDTH
|
|
98
145
|
});
|
|
99
|
-
this.drawGrid(scaleUnit);
|
|
146
|
+
this.drawGrid(scaleUnit, viewBoxWidth, viewBoxHeight);
|
|
100
147
|
this.setSVGStyle(this.grid, {
|
|
101
148
|
width: viewBoxWidth,
|
|
102
149
|
height: viewBoxHeight,
|
|
@@ -104,29 +151,221 @@ var BackgroundLayer = class extends import_core.Layer {
|
|
|
104
151
|
top: import_core.SCALE_WIDTH - scrollYDelta - mod
|
|
105
152
|
});
|
|
106
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
|
+
}
|
|
107
336
|
/**
|
|
108
337
|
* 绘制网格
|
|
109
338
|
*/
|
|
110
|
-
drawGrid(unit) {
|
|
339
|
+
drawGrid(unit, viewBoxWidth, viewBoxHeight) {
|
|
111
340
|
const minor = unit.renderSize;
|
|
112
341
|
if (!this.grid) {
|
|
113
342
|
return;
|
|
114
343
|
}
|
|
115
|
-
const patternSize =
|
|
116
|
-
|
|
117
|
-
|
|
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 += `
|
|
118
359
|
<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
|
-
/>
|
|
360
|
+
<circle ${circleAttributes} />
|
|
126
361
|
</pattern>
|
|
127
|
-
<rect width="100%" height="100%" fill="url(#${this._patternId})"
|
|
128
|
-
|
|
129
|
-
|
|
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;
|
|
130
369
|
}
|
|
131
370
|
setSVGStyle(svgElement, style) {
|
|
132
371
|
if (!svgElement) {
|
|
@@ -157,12 +396,16 @@ __decorateClass([
|
|
|
157
396
|
// src/create-background-plugin.ts
|
|
158
397
|
var import_core2 = require("@flowgram.ai/core");
|
|
159
398
|
var createBackgroundPlugin = (0, import_core2.definePluginCreator)({
|
|
399
|
+
onBind: (bindConfig, opts) => {
|
|
400
|
+
bindConfig.bind(BackgroundConfig).toConstantValue(opts);
|
|
401
|
+
},
|
|
160
402
|
onInit: (ctx, opts) => {
|
|
161
403
|
ctx.playground.registerLayer(BackgroundLayer, opts);
|
|
162
404
|
}
|
|
163
405
|
});
|
|
164
406
|
// Annotate the CommonJS export names for ESM import in node:
|
|
165
407
|
0 && (module.exports = {
|
|
408
|
+
BackgroundConfig,
|
|
166
409
|
BackgroundLayer,
|
|
167
410
|
createBackgroundPlugin
|
|
168
411
|
});
|
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,kBAA0E;AAC1E,mBAAyB;AAQzB,IAAM,iBAAiB;AACvB,IAAM,cAAc;AACpB,IAAM,WAAW;AACjB,IAAI,KAAK;AAOF,IAAM,kBAAN,cAA8B,kBAA8B;AAAA,EAA5D;AAAA;AAML,SAAQ,aAAa,GAAG,cAAc,GAAG,IAAI;AAE7C,gBAAO,sBAAS,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,0BAAS,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,0BAAc,eAAe;AAAA,MACnC,KAAK,0BAAc,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,MADT,2BAAc,kCAAsB;AAAA,GAH1B,gBAID;;;ACvBZ,IAAAA,eAAoC;AAO7B,IAAM,6BAAyB,kCAA4C;AAAA,EAChF,QAAQ,CAAC,KAAK,SAAS;AACrB,QAAI,WAAW,cAAc,iBAAiB,IAAI;AAAA,EACpD;AACF,CAAC;","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 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","import { 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
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flowgram.ai/background-plugin",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.16",
|
|
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/
|
|
22
|
-
"@flowgram.ai/
|
|
21
|
+
"@flowgram.ai/core": "0.2.16",
|
|
22
|
+
"@flowgram.ai/utils": "0.2.16"
|
|
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.
|
|
33
|
-
"@flowgram.ai/ts-config": "0.2.
|
|
32
|
+
"@flowgram.ai/eslint-config": "0.2.16",
|
|
33
|
+
"@flowgram.ai/ts-config": "0.2.16"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
36
|
"react": ">=16.8",
|