diff --git a/web/src/pages/Doc/catalogList.js b/web/src/pages/Doc/catalogList.js index 56005a44..dfde1397 100644 --- a/web/src/pages/Doc/catalogList.js +++ b/web/src/pages/Doc/catalogList.js @@ -19,6 +19,7 @@ let APIList = [ 'keyCommand', 'command', 'batchExecution', + 'richText', 'select', 'drag', 'keyboardNavigation', diff --git a/web/src/pages/Doc/en/changelog/index.md b/web/src/pages/Doc/en/changelog/index.md index 43d3568c..af1a345b 100644 --- a/web/src/pages/Doc/en/changelog/index.md +++ b/web/src/pages/Doc/en/changelog/index.md @@ -1,5 +1,9 @@ # Changelog +## 0.4.0 + +New: The node supports rich text editing. + ## 0.3.4 New:Automatic line wrapping function is added to node text. diff --git a/web/src/pages/Doc/en/changelog/index.vue b/web/src/pages/Doc/en/changelog/index.vue index 6aac7087..1abad000 100644 --- a/web/src/pages/Doc/en/changelog/index.vue +++ b/web/src/pages/Doc/en/changelog/index.vue @@ -1,6 +1,8 @@ diff --git a/web/src/pages/Doc/en/doExport/index.md b/web/src/pages/Doc/en/doExport/index.md index a2593306..c7bd5fec 100644 --- a/web/src/pages/Doc/en/doExport/index.md +++ b/web/src/pages/Doc/en/doExport/index.md @@ -20,19 +20,40 @@ After registration and instantiation of `MindMap`, the instance can be obtained Exports as `png`, an async method that returns image data, `data:url` data which can be downloaded or displayed. -### svg() +### svg(name, domToImage = false, plusCssText) + +- `name`:`svg` title + +- `domToImage`:v0.4.0+, When node rich text editing is enabled, you can use this parameter to specify whether to convert the `dom` node in the `svg` into a picture + +- `plusCssText`:v0.4.0+, When node rich text editing is enabled and `domToImage` passes `false`, additional `css` styles can be added. If there is a `dom` node in `svg`, you can set some styles for the node through this parameter, such as: + +```js +svg( + '', + false, + `* { + margin: 0; + padding: 0; + box-sizing: border-box; + }` +) +``` Exports as `svg`, an async method that returns `svg` data, `data:url` data which can be downloaded or displayed. -### getSvgData() +### getSvgData(domToImage) + +- `domToImage`:v0.4.0+, If node rich text is enabled, you can use this parameter to specify whether to convert the `DOM` node embedded in `svg` into a picture. Gets `svg` data, an async method that returns an object: ```js { node; // svg object - str; // svg string + str; // svg string, if rich text editing is enabled and domToImage is set to true, the dom node in the svg character returned by this value will be converted into the form of an image + nodeWithDomToImg// v0.4.0+,The svg object after the DOM node is converted to an image has a value only when rich text editing is enabled and domToImage is set to true, otherwise null } ``` diff --git a/web/src/pages/Doc/en/doExport/index.vue b/web/src/pages/Doc/en/doExport/index.vue index 21e8be1f..708023ea 100644 --- a/web/src/pages/Doc/en/doExport/index.vue +++ b/web/src/pages/Doc/en/doExport/index.vue @@ -13,14 +13,39 @@ MindMap.usePlugin(Export)

png()

Exports as png, an async method that returns image data, data:url data which can be downloaded or displayed.

-

svg()

+

svg(name, domToImage = false, plusCssText)

+ +
svg(
+  '', 
+  false, 
+  `* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+  }`
+)
+

Exports as svg, an async method that returns svg data, data:url data which can be downloaded or displayed.

-

getSvgData()

+

getSvgData(domToImage)

+

Gets svg data, an async method that returns an object:

{
   node; // svg object
-  str; // svg string
+  str; // svg string, if rich text editing is enabled and domToImage is set to true, the dom node in the svg character returned by this value will be converted into the form of an image
+  nodeWithDomToImg// v0.4.0+,The svg object after the DOM node is converted to an image has a value only when rich text editing is enabled and domToImage is set to true, otherwise null
 }
 

pdf(name)

diff --git a/web/src/pages/Doc/en/introduction/index.vue b/web/src/pages/Doc/en/introduction/index.vue index c35350ad..1a760eaf 100644 --- a/web/src/pages/Doc/en/introduction/index.vue +++ b/web/src/pages/Doc/en/introduction/index.vue @@ -4,20 +4,20 @@

simple-mind-map is a simple and powerful web mind map library, not dependent on any specific framework.

Features

Table of Contents

1.simple-mind-map

@@ -27,16 +27,16 @@ frameworks such as Vue and React, or without a framework.

This is an online mind map built using the simple-mind-map library and based on Vue2.x and ElementUI. Features include:

diff --git a/web/src/pages/Doc/en/richText/index.md b/web/src/pages/Doc/en/richText/index.md new file mode 100644 index 00000000..e9a9b43f --- /dev/null +++ b/web/src/pages/Doc/en/richText/index.md @@ -0,0 +1,147 @@ +# RichText plugin + +> v0.4.0+ + +> Note: This is a testing nature and imperfect function + +This plugin provides the ability to edit rich text of nodes, and takes effect after registration. + +By default, node editing can only uniformly apply styles to all text in the node. This plugin can support rich text editing effects. Currently, it supports bold, italic, underline, strikethrough, font, font size, and color. Underline and line height are not supported. + +The principle of this plugin is to use [Quill](https://github.com/quilljs/quill) editor implements rich text editing, and then uses the edited `DOM` node directly as the text data of the node, and embeds the `DOM` node through the `svg` `foreignObject` tag during rendering. + +This also caused a problem, that is, the function of exporting as a picture was affected, The original principle of exporting `svg` as an image is very simple, Get the `svg` string, and then create the `blob` data of the `type=image/svg+xml` type. Then use the `URL.createObjectURL` method to generate the `data:url` data. Then create a `Image` tag, use the `data:url` as the `src` of the image, and finally draw the image on the `canvas` object for export, However, after testing, when the `DOM` node is embedded in the `svg`, this method of export will cause errors, and after trying many ways, the perfect export effect cannot be achieved, The current method is to traverse the `foreignObject` node in `svg`, using [html2canvas](https://github.com/niklasvh/html2canvas) Convert the `DOM` node in the `foreignObject` node into an image and then replace the `foreignObject` node. This method can work, but it is very time-consuming. Because the `html2canvas` conversion takes a long time, it takes about 2 seconds to convert a node. This leads to the more nodes, the slower the conversion time. Therefore, it is recommended not to use this plugin if you cannot tolerate the long time of export. + +If you have a better way, please leave a message. + +## Register + +```js +import MindMap from 'simple-mind-map' +import RichText from 'simple-mind-map/src/RichText.js' + +MindMap.usePlugin(RichText, opt?) +``` + +After registration and instantiation of `MindMap`, the instance can be obtained through `mindMap.richText`. + +### Register options + +The `opt` option can pass the following parameters: + +- `opt.fontFamilyList` + +Replace the built-in font list during rich text editing. The built-in list is: + +```js +[ + '宋体, SimSun, Songti SC', + '微软雅黑, Microsoft YaHei', + '楷体, 楷体_GB2312, SimKai, STKaiti', + '黑体, SimHei, Heiti SC', + '隶书, SimLi', + 'andale mono', + 'arial, helvetica, sans-serif', + 'arial black, avant garde', + 'comic sans ms', + 'impact, chicago', + 'times new roman', + 'sans-serif', + 'serif' +] +``` + +- `opt.fontSizeList` + +Replace the built-in font size list during rich text editing. The built-in list is: + +```js +[1, 2, 3, ...100] +``` + +## Method + +### selectAll() + +Select All. When the node is being edited, you can select all the text in the node through this method. + +### formatText(config = {}) + +- `config`:Object. The key is the style attribute and the value is the style value. The complete configuration is as follows: + +```js +{ + font: '字体', + size: '12px,' // font size + bold: true, // Bold or not, true/false + italic: true, // Italic or not, true/false + underline: true, // Show underline or not, true/false + strike: true, // Whether to display strikethrough, true/false + color: '#333' // color +} +``` + +Formats the currently selected text. + +### formatRangeText(range, config = {}) + +- `range`:The range object of `Quill`, has the following format: + +```js +{ + index, + length +} +``` + +- `config`:Same as `formatText` method + +Formats the text of the specified range. + +### formatAllText(config = {}) + +- `config`:Same as `formatText` method + +Formats all text of the current edit node. + +### normalStyleToRichTextStyle(style) + +Converts a normal node style object to a rich text style object. Because there are differences between node style attributes and rich text style attributes during non-rich text editing, a conversion operation is required. For example: + +```js +{ + fontFamily: 'xxx' +} + +// After conversion + +{ + font: 'xxx' +} +``` + +### richTextStyleToNormalStyle(config) + +Converts rich text style objects to normal node style objects. For example: + +```js +{ + size: '16px' +} + +// After conversion + +{ + fontSize: 16 +} +``` + +### handleSvgDomElements(svg) + +- `svg`: `svg` node + +Convert the `dom` element embedded in the `svg` into a picture and return a `Promise`. + +### transformAllNodesToNormalNode() + +Convert all nodes to non-rich text nodes. \ No newline at end of file diff --git a/web/src/pages/Doc/en/richText/index.vue b/web/src/pages/Doc/en/richText/index.vue new file mode 100644 index 00000000..92415426 --- /dev/null +++ b/web/src/pages/Doc/en/richText/index.vue @@ -0,0 +1,129 @@ + + + + + \ No newline at end of file diff --git a/web/src/pages/Doc/routerList.js b/web/src/pages/Doc/routerList.js index 872bf03b..6ec5c61b 100644 --- a/web/src/pages/Doc/routerList.js +++ b/web/src/pages/Doc/routerList.js @@ -1,3 +1,3 @@ - export default [{"lang":"zh","children":[{"path":"batchExecution","title":"BatchExecution实例"},{"path":"changelog","title":"Changelog"},{"path":"command","title":"Command实例"},{"path":"constructor","title":"构造函数"},{"path":"doExport","title":"Export 插件"},{"path":"drag","title":"Drag插件"},{"path":"introduction","title":"简介"},{"path":"keyboardNavigation","title":"KeyboardNavigation插件"},{"path":"keyCommand","title":"KeyCommand实例"},{"path":"miniMap","title":"MiniMap插件"},{"path":"node","title":"Node实例"},{"path":"render","title":"Render实例"},{"path":"select","title":"Select 插件 "},{"path":"start","title":"开始"},{"path":"translate","title":"参与翻译"},{"path":"utils","title":"内置工具方法"},{"path":"view","title":"View实例"},{"path":"watermark","title":"Watermark插件"},{"path":"xmind","title":"XMind解析"}]},{"lang":"en","children":[{"path":"batchExecution","title":"batchExecution instance"},{"path":"changelog","title":"Changelog"},{"path":"command","title":"command instance"},{"path":"constructor","title":"Constructor"},{"path":"doExport","title":"Export plugin"},{"path":"drag","title":"Drag plugin"},{"path":"introduction","title":"Introduction"},{"path":"keyboardNavigation","title":"KeyboardNavigation plugin"},{"path":"keyCommand","title":"KeyCommand instance"},{"path":"miniMap","title":"MiniMap plugin"},{"path":"node","title":"Node instance"},{"path":"render","title":"Render instance"},{"path":"select","title":"Select plugin"},{"path":"start","title":"Start"},{"path":"translate","title":"Participate in translation"},{"path":"utils","title":"Utility Methods"},{"path":"view","title":"View instance"},{"path":"watermark","title":"Watermark plugin"},{"path":"xmind","title":"XMind parse"}]}] + export default [{"lang":"zh","children":[{"path":"batchExecution","title":"BatchExecution实例"},{"path":"changelog","title":"Changelog"},{"path":"command","title":"Command实例"},{"path":"constructor","title":"构造函数"},{"path":"doExport","title":"Export 插件"},{"path":"drag","title":"Drag插件"},{"path":"introduction","title":"简介"},{"path":"keyboardNavigation","title":"KeyboardNavigation插件"},{"path":"keyCommand","title":"KeyCommand实例"},{"path":"miniMap","title":"MiniMap插件"},{"path":"node","title":"Node实例"},{"path":"render","title":"Render实例"},{"path":"richText","title":"RichText插件"},{"path":"select","title":"Select 插件 "},{"path":"start","title":"开始"},{"path":"translate","title":"参与翻译"},{"path":"utils","title":"内置工具方法"},{"path":"view","title":"View实例"},{"path":"watermark","title":"Watermark插件"},{"path":"xmind","title":"XMind解析"}]},{"lang":"en","children":[{"path":"batchExecution","title":"batchExecution instance"},{"path":"changelog","title":"Changelog"},{"path":"command","title":"command instance"},{"path":"constructor","title":"Constructor"},{"path":"doExport","title":"Export plugin"},{"path":"drag","title":"Drag plugin"},{"path":"introduction","title":"Introduction"},{"path":"keyboardNavigation","title":"KeyboardNavigation plugin"},{"path":"keyCommand","title":"KeyCommand instance"},{"path":"miniMap","title":"MiniMap plugin"},{"path":"node","title":"Node instance"},{"path":"render","title":"Render instance"},{"path":"richText","title":"RichText plugin"},{"path":"select","title":"Select plugin"},{"path":"start","title":"Start"},{"path":"translate","title":"Participate in translation"},{"path":"utils","title":"Utility Methods"},{"path":"view","title":"View instance"},{"path":"watermark","title":"Watermark plugin"},{"path":"xmind","title":"XMind parse"}]}] \ No newline at end of file diff --git a/web/src/pages/Doc/zh/changelog/index.md b/web/src/pages/Doc/zh/changelog/index.md index fe60f530..988593aa 100644 --- a/web/src/pages/Doc/zh/changelog/index.md +++ b/web/src/pages/Doc/zh/changelog/index.md @@ -1,10 +1,14 @@ # Changelog +## 0.4.0 + +新增:节点支持富文本编辑。 + ## 0.3.4 -New:节点文本增加自动换行功能。 +新增:节点文本增加自动换行功能。 -Fix:1.修复批量删除的节点中如果存在根节点会出现删除异常的问题。2.修复底边风格的情况下,节点高度过高会和其他节点重叠的问题。 +修复:1.修复批量删除的节点中如果存在根节点会出现删除异常的问题。2.修复底边风格的情况下,节点高度过高会和其他节点重叠的问题。 ## 0.3.3 diff --git a/web/src/pages/Doc/zh/changelog/index.vue b/web/src/pages/Doc/zh/changelog/index.vue index 403e0e79..f284147f 100644 --- a/web/src/pages/Doc/zh/changelog/index.vue +++ b/web/src/pages/Doc/zh/changelog/index.vue @@ -1,9 +1,11 @@ diff --git a/web/src/pages/Doc/zh/doExport/index.md b/web/src/pages/Doc/zh/doExport/index.md index d24cad7e..5d176de6 100644 --- a/web/src/pages/Doc/zh/doExport/index.md +++ b/web/src/pages/Doc/zh/doExport/index.md @@ -19,18 +19,39 @@ MindMap.usePlugin(Export) 导出为`png`,异步方法,返回图片数据,`data:url`数据,可以自行下载或显示 -### svg() +### svg(name, domToImage = false, plusCssText) + +- `name`:`svg`标题 + +- `domToImage`:v0.4.0+,当开启了节点富文本编辑,可以通过该参数指定是否将`svg`中的`dom`节点转换成图片的形式 + +- `plusCssText`:v0.4.0+,当开启了节点富文本编辑,且`domToImage`传了`false`时,可以添加附加的`css`样式,如果`svg`中存在`dom`节点,想要设置一些针对节点的样式可以通过这个参数传入,比如: + +```js +svg( + '', + false, + `* { + margin: 0; + padding: 0; + box-sizing: border-box; + }` +) +``` 导出为`svg`,异步方法,返回`svg`数据,`data:url`数据,可以自行下载或显示 -### getSvgData() +### getSvgData(domToImage) + +- `domToImage`:v0.4.0+,如果开启了节点富文本,则可以通过该参数指定是否要将`svg`中嵌入的`DOM`节点转换为图片。 获取`svg`数据,异步方法,返回一个对象: ```js { node// svg对象 - str// svg字符串 + str// svg字符串,如果开启了富文本编辑且domToImage设为true,那么该值返回的svg字符内的dom节点会被转换成图片的形式 + nodeWithDomToImg// v0.4.0+,DOM节点转换为图片后的svg对象,只有当开启了富文本编辑且domToImage设为true才有值,否则为null } ``` diff --git a/web/src/pages/Doc/zh/doExport/index.vue b/web/src/pages/Doc/zh/doExport/index.vue index c29730dc..1efab1e2 100644 --- a/web/src/pages/Doc/zh/doExport/index.vue +++ b/web/src/pages/Doc/zh/doExport/index.vue @@ -12,13 +12,38 @@ MindMap.usePlugin(Export)

方法

png()

导出为png,异步方法,返回图片数据,data:url数据,可以自行下载或显示

-

svg()

+

svg(name, domToImage = false, plusCssText)

+ +
svg(
+  '', 
+  false, 
+  `* {
+    margin: 0;
+    padding: 0;
+    box-sizing: border-box;
+  }`
+)
+

导出为svg,异步方法,返回svg数据,data:url数据,可以自行下载或显示

-

getSvgData()

+

getSvgData(domToImage)

+

获取svg数据,异步方法,返回一个对象:

{
   node// svg对象
-  str// svg字符串
+  str// svg字符串,如果开启了富文本编辑且domToImage设为true,那么该值返回的svg字符内的dom节点会被转换成图片的形式
+  nodeWithDomToImg// v0.4.0+,DOM节点转换为图片后的svg对象,只有当开启了富文本编辑且domToImage设为true才有值,否则为null
 }
 

pdf(name)

diff --git a/web/src/pages/Doc/zh/richText/index.md b/web/src/pages/Doc/zh/richText/index.md new file mode 100644 index 00000000..e9c10791 --- /dev/null +++ b/web/src/pages/Doc/zh/richText/index.md @@ -0,0 +1,147 @@ +# RichText插件 + +> v0.4.0+ + +> 注意:这是一个测试性质和不完善的功能 + +该插件提供节点富文本编辑的能力,注册了即可生效。 + +默认节点编辑只能对节点内所有文本统一应用样式,通过该插件可以支持富文本编辑的效果,目前支持:加粗、斜体、下划线、删除线、字体、字号、颜色。不支持上划线、行高。 + +该插件的原理是使用[Quill](https://github.com/quilljs/quill)编辑器实现富文本编辑,然后把编辑后生成的`DOM`节点直接作为节点的文本数据,并且在渲染的时候通过`svg`的`foreignObject`标签嵌入`DOM`节点。 + +这样也造成了一个问题,就是导出为图片的功能受到了影响,原本将`svg`导出为图片的原理很简单,获取到`svg`字符串,然后创建为`type=image/svg+xml`类型的`blob`数据,再使用`URL.createObjectURL`方法生成`data:url`数据,再创建一个`Image`标签,将`data:url`作为该图片的`src`,最后再将这个图片绘制到`canvas`对象上进行导出,但是经过测试,当`svg`中嵌入了`DOM`节点,这种方式导出会出错,并且尝试了多种方式后都无法实现完美的导出效果,目前的方式是遍历`svg`中的`foreignObject`节点,使用[html2canvas](https://github.com/niklasvh/html2canvas)将`foreignObject`节点内的`DOM`节点转换为图片再替换掉`foreignObject`节点,这种方式可以工作,但是非常耗时,因为`html2canvas`转换一次的时间很长,导致转换一个节点都需要耗时差不多2秒,这样导致节点越多,转换时间越慢,所以如果无法忍受长时间的导出的话推荐不要使用该插件。 + +如果你有更好的方式也欢迎留言。 + +## 注册 + +```js +import MindMap from 'simple-mind-map' +import RichText from 'simple-mind-map/src/RichText.js' + +MindMap.usePlugin(RichText, opt?) +``` + +注册完且实例化`MindMap`后可通过`mindMap.richText`获取到该实例。 + +### 注册选项 + +`opt`选项可以传递以下参数: + +- `opt.fontFamilyList` + +替换富文本编辑时内置字体列表。内置的列表为: + +```js +[ + '宋体, SimSun, Songti SC', + '微软雅黑, Microsoft YaHei', + '楷体, 楷体_GB2312, SimKai, STKaiti', + '黑体, SimHei, Heiti SC', + '隶书, SimLi', + 'andale mono', + 'arial, helvetica, sans-serif', + 'arial black, avant garde', + 'comic sans ms', + 'impact, chicago', + 'times new roman', + 'sans-serif', + 'serif' +] +``` + +- `opt.fontSizeList` + +替换富文本编辑时内置字号列表。内置的列表为: + +```js +[1, 2, 3, ...100] +``` + +## 方法 + +### selectAll() + +选中全部。当节点正在编辑中可以通过该方法选中节点内的所有文本。 + +### formatText(config = {}) + +- `config`:对象,键为样式属性,值为样式值,完整的配置如下: + +```js +{ + font: '字体', + size: '12px,' // 字号 + bold: true, // 是否加粗,true/false + italic: true, // 是否斜体,true/false + underline: true, // 是否显示下划线,true/false + strike: true, // 是否显示删除线,true/false + color: '#333' // 颜色 +} +``` + +格式化当前选中的文本。 + +### formatRangeText(range, config = {}) + +- `range`:`Quill`的范围对象,格式如下: + +```js +{ + index, + length +} +``` + +- `config`:同`formatText`方法 + +格式化指定范围的文本。 + +### formatAllText(config = {}) + +- `config`:同`formatText`方法 + +格式化当前编辑节点的所有文本。 + +### normalStyleToRichTextStyle(style) + +将普通节点样式对象转换成富文本样式对象。因为非富文本编辑时的节点样式属性和富文本样式属性是存在差异的,所以需要一个转换操作。比如: + +```js +{ + fontFamily: 'xxx' +} + +// 转换后 + +{ + font: 'xxx' +} +``` + +### richTextStyleToNormalStyle(config) + +将富文本样式对象转换成普通节点样式对象。比如: + +```js +{ + size: '16px' +} + +// 转换后 + +{ + fontSize: 16 +} +``` + +### handleSvgDomElements(svg) + +- `svg`: `svg`节点 + +将`svg`中嵌入的`dom`元素转换成图片,返回一个`Promise`。 + +### transformAllNodesToNormalNode() + +将所有节点转换成非富文本节点。 \ No newline at end of file diff --git a/web/src/pages/Doc/zh/richText/index.vue b/web/src/pages/Doc/zh/richText/index.vue new file mode 100644 index 00000000..64130444 --- /dev/null +++ b/web/src/pages/Doc/zh/richText/index.vue @@ -0,0 +1,129 @@ + + + + + \ No newline at end of file