@lingxiteam/ebe-utils 0.0.4 → 0.0.6
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/es/index.d.ts
CHANGED
|
@@ -24,6 +24,9 @@ interface CodeServices {
|
|
|
24
24
|
findApplication: (params: {
|
|
25
25
|
appId: string;
|
|
26
26
|
}) => Promise<any>;
|
|
27
|
+
getWaterMarkByAppId: (params: {
|
|
28
|
+
appId: string;
|
|
29
|
+
}) => Promise<any>;
|
|
27
30
|
}
|
|
28
31
|
interface CodeOptions {
|
|
29
32
|
appId: string;
|
|
@@ -52,6 +55,7 @@ export declare const fetchData: ({ appId, services, platform, baseUrl, onProgres
|
|
|
52
55
|
themeCss: any;
|
|
53
56
|
models: Record<string, any>;
|
|
54
57
|
appInfo: Record<string, any>;
|
|
58
|
+
waterMark: any;
|
|
55
59
|
};
|
|
56
60
|
cleanedTree: any;
|
|
57
61
|
}>;
|
package/es/index.js
CHANGED
|
@@ -266,7 +266,7 @@ export var init = /*#__PURE__*/function () {
|
|
|
266
266
|
}();
|
|
267
267
|
export var fetchData = /*#__PURE__*/function () {
|
|
268
268
|
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(_ref4) {
|
|
269
|
-
var appId, services, platform, baseUrl, onProgress, appInfo, attrSpecPage, resultObject, frontendHookList, themeCss, temCompAssetList, compAssetList, globalDataInfo, dataSourceList, globalDataMap, pageIdMapping, appPageList, lastPageId, data, pages, itemHash, itemLists, busiData, busiCompMapping, busiPages, pageDSLS, options, cleanedTree;
|
|
269
|
+
var appId, services, platform, baseUrl, onProgress, appInfo, attrSpecPage, resultObject, frontendHookList, themeCss, temCompAssetList, compAssetList, globalDataInfo, dataSourceList, globalDataMap, pageIdMapping, appPageList, lastPageId, data, pages, itemHash, itemLists, busiData, busiCompMapping, busiPages, pageDSLS, waterMark, options, cleanedTree;
|
|
270
270
|
return _regeneratorRuntime().wrap(function _callee2$(_context2) {
|
|
271
271
|
while (1) switch (_context2.prev = _context2.next) {
|
|
272
272
|
case 0:
|
|
@@ -321,7 +321,7 @@ export var fetchData = /*#__PURE__*/function () {
|
|
|
321
321
|
}), new Promise(function (resolve, reject) {
|
|
322
322
|
setTimeout(function () {
|
|
323
323
|
resolve('');
|
|
324
|
-
},
|
|
324
|
+
}, 20000);
|
|
325
325
|
})]);
|
|
326
326
|
case 19:
|
|
327
327
|
themeCss = _context2.sent;
|
|
@@ -427,6 +427,17 @@ export var fetchData = /*#__PURE__*/function () {
|
|
|
427
427
|
return busiData;
|
|
428
428
|
}); // 合并页面,生成器那边支持页面类型和业务组件类型
|
|
429
429
|
pageDSLS = [].concat(_toConsumableArray(pages), _toConsumableArray(busiPages));
|
|
430
|
+
onProgress({
|
|
431
|
+
log: '查询水印配置信息',
|
|
432
|
+
progress: 7
|
|
433
|
+
});
|
|
434
|
+
// 获取水印
|
|
435
|
+
_context2.next = 60;
|
|
436
|
+
return services.getWaterMarkByAppId({
|
|
437
|
+
appId: appId
|
|
438
|
+
});
|
|
439
|
+
case 60:
|
|
440
|
+
waterMark = _context2.sent;
|
|
430
441
|
options = {
|
|
431
442
|
platform: platform,
|
|
432
443
|
appId: appId,
|
|
@@ -442,11 +453,12 @@ export var fetchData = /*#__PURE__*/function () {
|
|
|
442
453
|
}),
|
|
443
454
|
themeCss: themeCss,
|
|
444
455
|
models: globalDataMap,
|
|
445
|
-
appInfo: clearAppInfo(appInfo)
|
|
456
|
+
appInfo: clearAppInfo(appInfo),
|
|
457
|
+
waterMark: waterMark
|
|
446
458
|
};
|
|
447
459
|
onProgress({
|
|
448
460
|
log: '清理无用数据',
|
|
449
|
-
progress:
|
|
461
|
+
progress: 8
|
|
450
462
|
});
|
|
451
463
|
cleanedTree = cleanTree(pageDSLS, ['path']); // 清理字段'b'和字段'e'
|
|
452
464
|
cleanedTree = clearLXPagesDSL(cleanedTree);
|
|
@@ -454,7 +466,7 @@ export var fetchData = /*#__PURE__*/function () {
|
|
|
454
466
|
options: options,
|
|
455
467
|
cleanedTree: cleanedTree
|
|
456
468
|
});
|
|
457
|
-
case
|
|
469
|
+
case 66:
|
|
458
470
|
case "end":
|
|
459
471
|
return _context2.stop();
|
|
460
472
|
}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 将角度转成弧度
|
|
3
|
+
* @param degrees 角度
|
|
4
|
+
* @returns 弧度
|
|
5
|
+
*/
|
|
6
|
+
const degreesToRadians = (degrees: number) => {
|
|
7
|
+
return (degrees * Math.PI) / 180;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 计算原始矩形旋转后占用的面积
|
|
12
|
+
* @param sourceWidth 原始宽度
|
|
13
|
+
* @param sourceHeight 原始高度
|
|
14
|
+
* @param degrees 旋转角度逆时针 0 - 360°
|
|
15
|
+
*/
|
|
16
|
+
const calculateRotateSize = (
|
|
17
|
+
_sourceWidth: number,
|
|
18
|
+
_sourceHeight: number,
|
|
19
|
+
_degrees: number,
|
|
20
|
+
): {
|
|
21
|
+
width: number;
|
|
22
|
+
height: number;
|
|
23
|
+
} => {
|
|
24
|
+
switch (_degrees) {
|
|
25
|
+
case 0:
|
|
26
|
+
case 180:
|
|
27
|
+
case 360:
|
|
28
|
+
return { width: _sourceWidth, height: _sourceHeight };
|
|
29
|
+
case 90:
|
|
30
|
+
case 270:
|
|
31
|
+
return { width: _sourceHeight, height: _sourceWidth };
|
|
32
|
+
default:
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
let sourceWidth = _sourceWidth;
|
|
37
|
+
let sourceHeight = _sourceHeight;
|
|
38
|
+
let degrees = _degrees;
|
|
39
|
+
|
|
40
|
+
if (degrees > 90 && degrees < 180) {
|
|
41
|
+
degrees = 180 - degrees;
|
|
42
|
+
sourceWidth = _sourceHeight;
|
|
43
|
+
sourceHeight = _sourceWidth;
|
|
44
|
+
} else if (degrees > 180 && degrees < 270) {
|
|
45
|
+
degrees = 270 - degrees;
|
|
46
|
+
// sourceWidth = _sourceHeight;
|
|
47
|
+
// sourceHeight = _sourceWidth;
|
|
48
|
+
} else if (degrees > 270 && degrees < 360) {
|
|
49
|
+
degrees = 360 - degrees;
|
|
50
|
+
sourceWidth = _sourceHeight;
|
|
51
|
+
sourceHeight = _sourceWidth;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// 旋转弧度
|
|
55
|
+
const radians = degreesToRadians(degrees);
|
|
56
|
+
|
|
57
|
+
const widthA = sourceWidth * Math.cos(radians);
|
|
58
|
+
|
|
59
|
+
const heightA = sourceWidth * Math.sin(radians);
|
|
60
|
+
|
|
61
|
+
const widthB = sourceHeight * Math.sin(radians);
|
|
62
|
+
|
|
63
|
+
const heightB = sourceHeight * Math.cos(radians);
|
|
64
|
+
|
|
65
|
+
const res = {
|
|
66
|
+
width: Math.ceil(widthA + widthB),
|
|
67
|
+
height: Math.ceil(heightA + heightB),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return res;
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const laodImage = (baseData: string): Promise<HTMLImageElement> =>
|
|
74
|
+
new Promise((resolve) => {
|
|
75
|
+
const img = new Image();
|
|
76
|
+
img.src = baseData;
|
|
77
|
+
img.onload = () => {
|
|
78
|
+
resolve(img);
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* 生成水印图片
|
|
84
|
+
* @param content 水印内容
|
|
85
|
+
* @param width 宽度
|
|
86
|
+
* @param height 高度
|
|
87
|
+
* @param fontSize 字号大小
|
|
88
|
+
* @param fontColor 字体颜色
|
|
89
|
+
* @param alpha 透明度
|
|
90
|
+
* @param angle 旋转角度
|
|
91
|
+
*/
|
|
92
|
+
const generatorImage = async (
|
|
93
|
+
content: string,
|
|
94
|
+
width: number,
|
|
95
|
+
height: number,
|
|
96
|
+
fontSize: number,
|
|
97
|
+
fontColor: string,
|
|
98
|
+
alpha: number,
|
|
99
|
+
angle: number,
|
|
100
|
+
): Promise<string | null> => {
|
|
101
|
+
// 文字行高
|
|
102
|
+
const lineHeight = fontSize + 2;
|
|
103
|
+
|
|
104
|
+
const sourceCanvas = document.createElement('canvas');
|
|
105
|
+
const sourceCtx = sourceCanvas.getContext('2d') as CanvasRenderingContext2D;
|
|
106
|
+
|
|
107
|
+
sourceCanvas.width = width;
|
|
108
|
+
sourceCanvas.height = height;
|
|
109
|
+
sourceCtx.font = `300 ${fontSize}px Microsoft YaHei`;
|
|
110
|
+
sourceCtx.globalAlpha = alpha;
|
|
111
|
+
sourceCtx.fillStyle = fontColor;
|
|
112
|
+
|
|
113
|
+
const strList = [];
|
|
114
|
+
|
|
115
|
+
const measureTextWidth = (str: string) => {
|
|
116
|
+
return sourceCtx.measureText(str).width;
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
// 回车替换成空格 多个空格合并成一个
|
|
120
|
+
const nextStr = content.replace(/\n/g, ' ').replace(/\s{2,}/, ' ');
|
|
121
|
+
let length = 0;
|
|
122
|
+
let currentLine = '';
|
|
123
|
+
while (length < nextStr.length) {
|
|
124
|
+
const char = nextStr[length];
|
|
125
|
+
const newLine = currentLine + char;
|
|
126
|
+
if (measureTextWidth(newLine) < 300) {
|
|
127
|
+
currentLine = newLine;
|
|
128
|
+
} else {
|
|
129
|
+
currentLine = '';
|
|
130
|
+
strList.push({
|
|
131
|
+
x: 0,
|
|
132
|
+
content: newLine,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
length += 1;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 最后一行文字没有填充满 计算居中偏移量
|
|
139
|
+
if (currentLine) {
|
|
140
|
+
strList.push({
|
|
141
|
+
x: (width - measureTextWidth(currentLine)) / 2,
|
|
142
|
+
content: currentLine,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// 根据行数计算起始位置
|
|
147
|
+
const contentHeight = strList.length * 26;
|
|
148
|
+
let offsetY = (height - contentHeight) / 2;
|
|
149
|
+
offsetY = offsetY < 0 ? 0 : offsetY;
|
|
150
|
+
|
|
151
|
+
// 逐行添加文字
|
|
152
|
+
for (let i = 0; i < strList.length; i += 1) {
|
|
153
|
+
const { x, content } = strList[i];
|
|
154
|
+
const y = (i + 1) * lineHeight + offsetY;
|
|
155
|
+
sourceCtx.fillText(content, x, y);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// 图片base64
|
|
159
|
+
let imgBase64 = sourceCanvas.toDataURL('image/png');
|
|
160
|
+
|
|
161
|
+
// 存在角度旋转
|
|
162
|
+
if (angle > 0) {
|
|
163
|
+
const nextCanvas = document.createElement('canvas');
|
|
164
|
+
const nextCtx = nextCanvas.getContext('2d') as CanvasRenderingContext2D;
|
|
165
|
+
const { width: nextWidth, height: nextHeight } = calculateRotateSize(
|
|
166
|
+
width,
|
|
167
|
+
height,
|
|
168
|
+
angle,
|
|
169
|
+
);
|
|
170
|
+
nextCanvas.width = nextWidth;
|
|
171
|
+
nextCanvas.height = nextHeight;
|
|
172
|
+
const img = await laodImage(imgBase64);
|
|
173
|
+
const _offsetX = -img.width / 2;
|
|
174
|
+
const _offsetY = -img.height / 2;
|
|
175
|
+
nextCtx.translate(nextWidth / 2, nextHeight / 2);
|
|
176
|
+
nextCtx.rotate(-degreesToRadians(angle));
|
|
177
|
+
nextCtx.drawImage(img, _offsetX, _offsetY, img.width, img.height);
|
|
178
|
+
imgBase64 = nextCanvas.toDataURL('image/png');
|
|
179
|
+
}
|
|
180
|
+
return imgBase64;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
export default generatorImage;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { FC, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import generatorImage from './generatorImage';
|
|
3
|
+
import './index.less';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* 水印配置
|
|
7
|
+
*/
|
|
8
|
+
interface AppWaterMarkCfgType {
|
|
9
|
+
fontColor: string;
|
|
10
|
+
fontSize: string;
|
|
11
|
+
tiltAngle?: string;
|
|
12
|
+
waterMarkInfoResultValue: string;
|
|
13
|
+
isEnable: string;
|
|
14
|
+
fontTransparency: number;
|
|
15
|
+
blockWidth?: number;
|
|
16
|
+
blockHeight?: number;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface WatermarkProps {
|
|
20
|
+
config: AppWaterMarkCfgType;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const Watermark: FC<WatermarkProps> = (props) => {
|
|
24
|
+
const watermarkInfo = props.config || {};
|
|
25
|
+
const [previewURL, setPreviewURL] = useState<string>();
|
|
26
|
+
const watermarkRef = useRef<HTMLDivElement>(null);
|
|
27
|
+
const getWaterMark = () => {
|
|
28
|
+
// 如果存在水印就不需要展示,不然弹窗等会叠加水印
|
|
29
|
+
generatorImage(
|
|
30
|
+
watermarkInfo.waterMarkInfoResultValue,
|
|
31
|
+
watermarkInfo.blockWidth || 200,
|
|
32
|
+
watermarkInfo.blockHeight || 200,
|
|
33
|
+
Number(watermarkInfo.fontSize || 16),
|
|
34
|
+
watermarkInfo.fontColor || '#000',
|
|
35
|
+
(watermarkInfo.fontTransparency || 50) / 100,
|
|
36
|
+
Number(watermarkInfo.tiltAngle) || 0,
|
|
37
|
+
).then((res) => {
|
|
38
|
+
if (res) {
|
|
39
|
+
setPreviewURL(res);
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
};
|
|
43
|
+
useEffect(() => {
|
|
44
|
+
getWaterMark();
|
|
45
|
+
}, [watermarkInfo]);
|
|
46
|
+
|
|
47
|
+
return previewURL ? (
|
|
48
|
+
<div
|
|
49
|
+
ref={watermarkRef}
|
|
50
|
+
className="engine-watermark"
|
|
51
|
+
style={{ background: previewURL ? `url(${previewURL})` : '#FFFFFF' }}
|
|
52
|
+
/>
|
|
53
|
+
) : (
|
|
54
|
+
<></>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export default Watermark;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingxiteam/ebe-utils",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [],
|
|
6
6
|
"author": "",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"@babel/parser": "^7.12.12",
|
|
18
18
|
"@babel/traverse": "^7.12.12",
|
|
19
19
|
"@babel/types": "^7.12.12",
|
|
20
|
-
"@lingxiteam/ebe": "0.0.
|
|
20
|
+
"@lingxiteam/ebe": "0.0.6",
|
|
21
21
|
"cac": "^6.7.14",
|
|
22
22
|
"fs-extra": "9.x"
|
|
23
23
|
},
|