diff --git a/simple-mind-map/index.js b/simple-mind-map/index.js index b749aa2e..b29b234b 100644 --- a/simple-mind-map/index.js +++ b/simple-mind-map/index.js @@ -11,6 +11,7 @@ import Export from './src/Export' import Select from './src/Select' import Drag from './src/Drag' import MiniMap from './src/MiniMap' +import Watermark from './src/Watermark' import { layoutValueList } from './src/utils/constant' import { SVG } from '@svgdotjs/svg.js' import xmind from './src/parse/xmind' @@ -53,7 +54,19 @@ const defaultOpt = { } */ // 是否开启节点自由拖拽 - enableFreeDrag: false + enableFreeDrag: false, + // 水印配置 + watermarkConfig: { + text: '', + lineSpacing: 100, + textSpacing: 100, + angle: 30, + textStyle: { + color: '#999', + opacity: 0.5, + fontSize: 14 + } + } } // 思维导图 @@ -132,6 +145,11 @@ class MindMap { mindMap: this }) + // 水印类 + this.watermark = new Watermark({ + mindMap: this + }) + // 批量执行类 this.batchExecution = new BatchExecution() diff --git a/simple-mind-map/scripts/changeComments.js b/simple-mind-map/scripts/walkJsFiles.js similarity index 60% rename from simple-mind-map/scripts/changeComments.js rename to simple-mind-map/scripts/walkJsFiles.js index db084baa..96124251 100644 --- a/simple-mind-map/scripts/changeComments.js +++ b/simple-mind-map/scripts/walkJsFiles.js @@ -1,4 +1,4 @@ -// 将/** */类型的注释转换为//类型 +// 遍历所有js文件 const path = require('path') const fs = require('fs') @@ -11,13 +11,26 @@ const transform = dir => { if (fs.statSync(file).isDirectory()) { transform(file) } else if (/\.js$/.test(file)) { - rewriteComments(file) + transformFile(file) } }) } -const rewriteComments = file => { +const transformFile = file => { + console.log(file); let content = fs.readFileSync(file, 'utf-8') + countCodeLines(content) + // transformComments(file, content) +} + +// 统计代码行数 +let totalLines = 0 +const countCodeLines = (content) => { + totalLines += content.split(/\n/).length +} + +// 转换注释类型 +const transformComments = (file, content) => { console.log('当前转换文件:', file) content = content.replace(/\/\*\*[^/]+\*\//g, str => { let res = /@Desc:([^\n]+)\n/g.exec(str) @@ -29,4 +42,5 @@ const rewriteComments = file => { } transform(entryPath) -rewriteComments(path.join(__dirname, '../index.js')) +transformFile(path.join(__dirname, '../index.js')) +console.log(totalLines); \ No newline at end of file diff --git a/simple-mind-map/src/Watermark.js b/simple-mind-map/src/Watermark.js new file mode 100644 index 00000000..2d740fb2 --- /dev/null +++ b/simple-mind-map/src/Watermark.js @@ -0,0 +1,111 @@ +import { Text, G } from '@svgdotjs/svg.js' +import { degToRad, camelCaseToHyphen } from './utils' +import merge from 'deepmerge' + +// 水印类 +export default class Watermark { + constructor(opt = {}) { + this.mindMap = opt.mindMap + this.lineSpacing = 0 // 水印行间距 + this.textSpacing = 0 // 行内水印间距 + this.angle = 0 // 旋转角度 + this.text = '' // 水印文字 + this.textStyle = {} // 水印文字样式 + this.watermarkDraw = this.mindMap.svg + .group() + .css({ 'pointer-events': 'none', 'user-select': 'none' }) + this.maxLong = Math.sqrt( + Math.pow(this.mindMap.width, 2) + Math.pow(this.mindMap.height, 2) + ) + this.updateWatermark(this.mindMap.opt.watermarkConfig || {}) + } + + // 处理水印配置 + handleConfig({ text, lineSpacing, textSpacing, angle, textStyle }) { + this.text = text === undefined ? '' : String(text).trim() + this.lineSpacing = + typeof lineSpacing === 'number' && lineSpacing > 0 ? lineSpacing : 100 + this.textSpacing = + typeof textSpacing === 'number' && textSpacing > 0 ? textSpacing : 100 + this.angle = + typeof angle === 'number' && angle >= 0 && angle <= 90 ? angle : 30 + this.textStyle = Object.assign(this.textStyle, textStyle || {}) + } + + // 绘制水印 + // 非精确绘制,会绘制一些超出可视区域的水印 + draw() { + this.watermarkDraw.clear() + if (!this.text.trim()) { + return + } + let x = 0 + while (x < this.mindMap.width) { + this.drawText(x) + x += this.lineSpacing / Math.sin(degToRad(this.angle)) + } + + let yOffset = + this.lineSpacing / Math.cos(degToRad(this.angle)) || this.lineSpacing + let y = yOffset + while (y < this.mindMap.height) { + this.drawText(0, y) + y += yOffset + } + } + + // 绘制文字 + drawText(x, y) { + let long = Math.min( + this.maxLong, + (this.mindMap.width - x) / Math.cos(degToRad(this.angle)) + ) + let g = new G() + let bbox = null + let bboxWidth = 0 + let textHeight = -1 + while (bboxWidth < long) { + let text = new Text().text(this.text) + g.add(text) + text.transform({ + translateX: bboxWidth + }) + this.setTextStyle(text) + bbox = g.bbox() + if (textHeight === -1) { + textHeight = bbox.height + } + bboxWidth = bbox.width + this.textSpacing + } + let params = { + rotate: this.angle, + origin: 'top left', + translateX: x, + translateY: textHeight + } + if (y !== undefined) { + params.translateY = y + textHeight + } + g.transform(params) + this.watermarkDraw.add(g) + } + + // 给文字设置样式 + setTextStyle(text) { + Object.keys(this.textStyle).forEach(item => { + let value = this.textStyle[item] + if (item === 'color') { + text.fill(value) + } else { + text.css(camelCaseToHyphen(item), value) + } + }) + } + + // 更新水印 + updateWatermark(config) { + this.mindMap.opt.watermarkConfig = merge(this.mindMap.opt.watermarkConfig, config) + this.handleConfig(config) + this.draw() + } +} diff --git a/simple-mind-map/src/utils/index.js b/simple-mind-map/src/utils/index.js index 819b09a3..f69a8543 100644 --- a/simple-mind-map/src/utils/index.js +++ b/simple-mind-map/src/utils/index.js @@ -224,3 +224,15 @@ export const asyncRun = (taskList, callback = () => {}) => { } loop() } + +// 角度转弧度 +export const degToRad = deg => { + return deg * (Math.PI / 180) +} + +// 驼峰转连字符 +export const camelCaseToHyphen = (str) => { + return str.replace(/([a-z])([A-Z])/g, (...args) => { + return args[1] + '-' + args[2].toLowerCase() + }) +} \ No newline at end of file diff --git a/web/src/lang/en_us.js b/web/src/lang/en_us.js index 91fe4c6c..22bdee95 100644 --- a/web/src/lang/en_us.js +++ b/web/src/lang/en_us.js @@ -22,7 +22,17 @@ export default { nodeBorderType: 'Node border style', nodeUseLineStyle: 'Use only has bottom border style', otherConfig: 'Other config', - enableFreeDrag: 'Enable node free drag' + enableFreeDrag: 'Enable node free drag', + watermark: 'Watermark', + showWatermark: 'Is show watermark', + watermarkDefaultText: 'Watermark text', + watermarkText: 'Watermark text', + watermarkTextColor: 'Text color', + watermarkLineSpacing: 'Line spacing', + watermarkTextSpacing: 'Text spacing', + watermarkAngle: 'Angle', + watermarkTextOpacity: 'Text opacity', + watermarkTextFontSize: 'Font size' }, color: { moreColor: 'More color' diff --git a/web/src/lang/zh_cn.js b/web/src/lang/zh_cn.js index 2b9c5f70..4d2f2739 100644 --- a/web/src/lang/zh_cn.js +++ b/web/src/lang/zh_cn.js @@ -22,7 +22,17 @@ export default { nodeBorderType: '节点边框风格', nodeUseLineStyle: '是否使用只有底边框的风格', otherConfig: '其他配置', - enableFreeDrag: '是否开启节点自由拖拽' + enableFreeDrag: '是否开启节点自由拖拽', + watermark: '水印', + showWatermark: '是否显示水印', + watermarkDefaultText: '水印文字', + watermarkText: '水印文字', + watermarkTextColor: '文字颜色', + watermarkLineSpacing: '水印行间距', + watermarkTextSpacing: '水印文字间距', + watermarkAngle: '旋转角度', + watermarkTextOpacity: '文字透明度', + watermarkTextFontSize: '文字字号' }, color: { moreColor: '更多颜色' diff --git a/web/src/pages/Doc/catalogList.js b/web/src/pages/Doc/catalogList.js index dcbc2f52..0693dcc0 100644 --- a/web/src/pages/Doc/catalogList.js +++ b/web/src/pages/Doc/catalogList.js @@ -18,6 +18,7 @@ let APIList = [ 'view', 'miniMap', 'doExport', + 'watermark', 'keyCommand', 'keyboardNavigation', 'command', diff --git a/web/src/pages/Doc/en/constructor/index.md b/web/src/pages/Doc/en/constructor/index.md index 8f3d103f..13235650 100644 --- a/web/src/pages/Doc/en/constructor/index.md +++ b/web/src/pages/Doc/en/constructor/index.md @@ -83,6 +83,17 @@ package | customNoteContentShow(v0.1.6+) | Object | null | Custom node note content display, object type, structure: {show: (noteContent, left, top) => {// your display node note logic }, hide: () => {// your hide node note logic }} | | | readonly(v0.1.7+) | Boolean | false | Whether it is read-only mode | | | enableFreeDrag(v0.2.4+) | Boolean | false | Enable node free drag | | +| watermarkConfig(v0.2.4+) | Object | | Watermark config, Please refer to the table 【Watermark config】 below for detailed configuration | | + +### Watermark config + +| Field Name | Type | Default Value | Description | +| ----------- | ------ | ------------------------------------------- | ------------------------------------------------------------ | +| text | String | '' | Watermark text. If it is an empty string, the watermark will not be displayed | +| lineSpacing | Number | 100 | Spacing between watermark lines | +| textSpacing | Number | 100 | Spacing between watermarks in the same row | +| angle | Number | 30 | Tilt angle of watermark, range: [0, 90] | +| textStyle | Object | {color: '#999', opacity: 0.5, fontSize: 14} | Watermark text style | ## Static methods diff --git a/web/src/pages/Doc/en/constructor/index.vue b/web/src/pages/Doc/en/constructor/index.vue index ef6d1b9b..efd72b97 100644 --- a/web/src/pages/Doc/en/constructor/index.vue +++ b/web/src/pages/Doc/en/constructor/index.vue @@ -158,6 +158,63 @@ package
| Field Name | +Type | +Default Value | +Description | +
|---|---|---|---|
| text | +String | +'' | +Watermark text. If it is an empty string, the watermark will not be displayed | +
| lineSpacing | +Number | +100 | +Spacing between watermark lines | +
| textSpacing | +Number | +100 | +Spacing between watermarks in the same row | +
| angle | +Number | +30 | +Tilt angle of watermark, range: [0, 90] | +
| textStyle | +Object | +{color: '#999', opacity: 0.5, fontSize: 14} | +Watermark text style | +
Gets the custom theme configuration.
Gets the value of a specific theme configuration property.
+++0.2.24+
+
prop:Get the value of the specified configuration, and return the entire configuration if not passed
Get config, That is, opt of new MindMap (opt)
++0.2.24+
+
opt:Configuration to update
Update config,That is update opt of new MindMap(opt),You can only update some data, such as:
mindMap.updateConfig({
+ enableFreeDrag: true// 开启节点自由拖拽
+})
+
+This method only updates the configuration and has no other side effects, such as triggering canvas re-rendering
Gets the current layout structure.
data of the data object, example:
Throttle function
Run tasks in task list asynchronously, tasks are run synchronously without order
+++v0.2.24+
+
Angle to radian
+++v0.2.24+
+
CamelCase to hyphen
diff --git a/web/src/pages/Doc/en/watermark/index.md b/web/src/pages/Doc/en/watermark/index.md new file mode 100644 index 00000000..9407fcd3 --- /dev/null +++ b/web/src/pages/Doc/en/watermark/index.md @@ -0,0 +1,32 @@ +# Watermark instance + +> 0.2.24+ + +`Watermark` instance is responsible for displaying the watermark, and can be obtained +through `mindMap.watermark`. + +## Methods + +### draw() + +Redraw the watermark. + +Note: For imprecise rendering, some watermarks beyond the visible area will be drawn. If you have extreme performance requirements, it is recommended to develop the watermark function yourself. + +### updateWatermark(config) + +Update watermark config. Example: + +```js +mindMap.watermark.updateWatermark({ + text: 'Watermark text', + lineSpacing: 100, + textSpacing: 100, + angle: 50, + textStyle: { + color: '#000', + opacity: 1, + fontSize: 20 + } +}) +``` \ No newline at end of file diff --git a/web/src/pages/Doc/en/watermark/index.vue b/web/src/pages/Doc/en/watermark/index.vue new file mode 100644 index 00000000..cd341b2a --- /dev/null +++ b/web/src/pages/Doc/en/watermark/index.vue @@ -0,0 +1,39 @@ + +++0.2.24+
+
Watermark instance is responsible for displaying the watermark, and can be obtained
+through mindMap.watermark.
Redraw the watermark.
+Note: For imprecise rendering, some watermarks beyond the visible area will be drawn. If you have extreme performance requirements, it is recommended to develop the watermark function yourself.
+Update watermark config. Example:
+mindMap.watermark.updateWatermark({
+ text: 'Watermark text',
+ lineSpacing: 100,
+ textSpacing: 100,
+ angle: 50,
+ textStyle: {
+ color: '#000',
+ opacity: 1,
+ fontSize: 20
+ }
+})
+
+
+ | 字段名称 | +类型 | +默认值 | +描述 | +
|---|---|---|---|
| text | +String | +'' | +水印文字,如果为空字符串则不显示水印 | +
| lineSpacing | +Number | +100 | +水印每行之间的间距 | +
| textSpacing | +Number | +100 | +同一行水印之间的间距 | +
| angle | +Number | +30 | +水印的倾斜角度,范围:[0, 90] | +
| textStyle | +Object | +{color: '#999', opacity: 0.5, fontSize: 14} | +水印文字样式 | +
获取自定义主题配置
获取某个主题配置属性值
+++0.2.24+
+
prop:获取指定配置的值,不传则返回整个配置
获取配置,即new MindMap(opt)的opt
++0.2.24+
+
opt:要更新的配置
更新配置,即更新new MindMap(opt)的opt,可以只更新部分数据,比如:
mindMap.updateConfig({
+ enableFreeDrag: true// 开启节点自由拖拽
+})
+
+该方法只做更新配置的事情,没有其他副作用,比如触发画布重新渲染之类的
获取当前的布局结构
节流函数
异步执行任务队列,多个任务是同步执行的,没有先后顺序
+++v0.2.24+
+
角度转弧度
+++v0.2.24+
+
驼峰转连字符
diff --git a/web/src/pages/Doc/zh/watermark/index.md b/web/src/pages/Doc/zh/watermark/index.md new file mode 100644 index 00000000..fbd94bd0 --- /dev/null +++ b/web/src/pages/Doc/zh/watermark/index.md @@ -0,0 +1,31 @@ +# Watermark实例 + +> 0.2.24+ + +`Watermark`实例负责显示水印,可通过`mindMap.watermark`获取到该实例。 + +## 方法 + +### draw() + +重新绘制水印。 + +注意:非精确绘制,会绘制一些超出可视区域的水印,如果对性能有极致要求,推荐自行开发水印功能。 + +### updateWatermark(config) + +更新水印配置。示例: + +```js +mindMap.watermark.updateWatermark({ + text: '水印文字', + lineSpacing: 100, + textSpacing: 100, + angle: 50, + textStyle: { + color: '#000', + opacity: 1, + fontSize: 20 + } +}) +``` \ No newline at end of file diff --git a/web/src/pages/Doc/zh/watermark/index.vue b/web/src/pages/Doc/zh/watermark/index.vue new file mode 100644 index 00000000..e78d26ea --- /dev/null +++ b/web/src/pages/Doc/zh/watermark/index.vue @@ -0,0 +1,38 @@ + +++0.2.24+
+
Watermark实例负责显示水印,可通过mindMap.watermark获取到该实例。
重新绘制水印。
+注意:非精确绘制,会绘制一些超出可视区域的水印,如果对性能有极致要求,推荐自行开发水印功能。
+更新水印配置。示例:
+mindMap.watermark.updateWatermark({
+ text: '水印文字',
+ lineSpacing: 100,
+ textSpacing: 100,
+ angle: 50,
+ textStyle: {
+ color: '#000',
+ opacity: 1,
+ fontSize: 20
+ }
+})
+
+
+