From 2a85a03889471210f3d41ce9dde4b0a7724c8e9a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Thu, 28 Dec 2023 09:27:34 +0800
Subject: [PATCH 01/21] =?UTF-8?q?Feat=EF=BC=9A=E5=AF=BC=E5=87=BApdf?=
=?UTF-8?q?=E4=BB=8Ejspdf=E5=BA=93=E6=94=B9=E4=B8=BApdf-lib=E5=BA=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/package-lock.json | 426 ++++-------------------
simple-mind-map/package.json | 2 +-
simple-mind-map/src/plugins/Export.js | 8 +-
simple-mind-map/src/plugins/ExportPDF.js | 59 +++-
4 files changed, 118 insertions(+), 377 deletions(-)
diff --git a/simple-mind-map/package-lock.json b/simple-mind-map/package-lock.json
index 975f6cd3..e3949191 100644
--- a/simple-mind-map/package-lock.json
+++ b/simple-mind-map/package-lock.json
@@ -1,20 +1,20 @@
{
"name": "simple-mind-map",
- "version": "0.9.1",
+ "version": "0.9.2",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
- "version": "0.9.1",
+ "version": "0.9.2",
"license": "MIT",
"dependencies": {
"@svgdotjs/svg.js": "^3.0.16",
"deepmerge": "^1.5.2",
"eventemitter3": "^4.0.7",
- "jspdf": "^2.5.1",
"jszip": "^3.10.1",
"katex": "^0.16.8",
"mdast-util-from-markdown": "^1.3.0",
+ "pdf-lib": "^1.17.1",
"quill": "^1.3.6",
"tern": "^0.24.3",
"uuid": "^9.0.0",
@@ -27,17 +27,6 @@
"prettier": "^2.7.1"
}
},
- "node_modules/@babel/runtime": {
- "version": "7.23.2",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
- "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
- "dependencies": {
- "regenerator-runtime": "^0.14.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@eslint/eslintrc": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
@@ -129,6 +118,22 @@
"node": ">= 8"
}
},
+ "node_modules/@pdf-lib/standard-fonts": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz",
+ "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==",
+ "dependencies": {
+ "pako": "^1.0.6"
+ }
+ },
+ "node_modules/@pdf-lib/upng": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz",
+ "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==",
+ "dependencies": {
+ "pako": "^1.0.10"
+ }
+ },
"node_modules/@svgdotjs/svg.js": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.1.2.tgz",
@@ -159,12 +164,6 @@
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
"integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
},
- "node_modules/@types/raf": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz",
- "integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==",
- "optional": true
- },
"node_modules/@types/unist": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
@@ -267,31 +266,11 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
- "node_modules/atob": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
- "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
- "bin": {
- "atob": "bin/atob.js"
- },
- "engines": {
- "node": ">= 4.5.0"
- }
- },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
- "node_modules/base64-arraybuffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
- "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
- "optional": true,
- "engines": {
- "node": ">= 0.6.0"
- }
- },
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -320,17 +299,6 @@
"concat-map": "0.0.1"
}
},
- "node_modules/btoa": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz",
- "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==",
- "bin": {
- "btoa": "bin/btoa.js"
- },
- "engines": {
- "node": ">= 0.4.0"
- }
- },
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
@@ -375,31 +343,6 @@
"node": ">=6"
}
},
- "node_modules/canvg": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.10.tgz",
- "integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==",
- "optional": true,
- "dependencies": {
- "@babel/runtime": "^7.12.5",
- "@types/raf": "^3.4.0",
- "core-js": "^3.8.3",
- "raf": "^3.4.1",
- "regenerator-runtime": "^0.13.7",
- "rgbcolor": "^1.0.1",
- "stackblur-canvas": "^2.0.0",
- "svg-pathdata": "^6.0.3"
- },
- "engines": {
- "node": ">=10.0.0"
- }
- },
- "node_modules/canvg/node_modules/regenerator-runtime": {
- "version": "0.13.11",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
- "optional": true
- },
"node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -464,17 +407,6 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
- "node_modules/core-js": {
- "version": "3.33.3",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz",
- "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==",
- "hasInstallScript": true,
- "optional": true,
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/core-js"
- }
- },
"node_modules/core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -494,15 +426,6 @@
"node": ">= 8"
}
},
- "node_modules/css-line-break": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
- "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
- "optional": true,
- "dependencies": {
- "utrie": "^1.0.2"
- }
- },
"node_modules/debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -604,12 +527,6 @@
"node": ">=6.0.0"
}
},
- "node_modules/dompurify": {
- "version": "2.4.7",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz",
- "integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ==",
- "optional": true
- },
"node_modules/enhanced-resolve": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-2.3.0.tgz",
@@ -858,11 +775,6 @@
"reusify": "^1.0.4"
}
},
- "node_modules/fflate": {
- "version": "0.4.8",
- "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
- "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA=="
- },
"node_modules/file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -1059,19 +971,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/html2canvas": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
- "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
- "optional": true,
- "dependencies": {
- "css-line-break": "^2.1.0",
- "text-segmentation": "^1.0.3"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -1272,23 +1171,6 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
- "node_modules/jspdf": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-2.5.1.tgz",
- "integrity": "sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==",
- "dependencies": {
- "@babel/runtime": "^7.14.0",
- "atob": "^2.1.2",
- "btoa": "^1.2.1",
- "fflate": "^0.4.8"
- },
- "optionalDependencies": {
- "canvg": "^3.0.6",
- "core-js": "^3.6.0",
- "dompurify": "^2.2.0",
- "html2canvas": "^1.0.0-rc.5"
- }
- },
"node_modules/jszip": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
@@ -2014,11 +1896,16 @@
"node": ">=8"
}
},
- "node_modules/performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
- "optional": true
+ "node_modules/pdf-lib": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz",
+ "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==",
+ "dependencies": {
+ "@pdf-lib/standard-fonts": "^1.0.0",
+ "@pdf-lib/upng": "^1.0.1",
+ "pako": "^1.0.11",
+ "tslib": "^1.11.1"
+ }
},
"node_modules/prelude-ls": {
"version": "1.2.1",
@@ -2113,15 +2000,6 @@
"resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz",
"integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg=="
},
- "node_modules/raf": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
- "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
- "optional": true,
- "dependencies": {
- "performance-now": "^2.1.0"
- }
- },
"node_modules/randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -2144,11 +2022,6 @@
"util-deprecate": "~1.0.1"
}
},
- "node_modules/regenerator-runtime": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
- "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
- },
"node_modules/regexp.prototype.flags": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
@@ -2196,15 +2069,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/rgbcolor": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
- "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==",
- "optional": true,
- "engines": {
- "node": ">= 0.8.15"
- }
- },
"node_modules/rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -2331,15 +2195,6 @@
"node": ">= 6"
}
},
- "node_modules/stackblur-canvas": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.6.0.tgz",
- "integrity": "sha512-8S1aIA+UoF6erJYnglGPug6MaHYGo1Ot7h5fuXx4fUPvcvQfcdw2o/ppCse63+eZf8PPidSu4v1JnmEVtEDnpg==",
- "optional": true,
- "engines": {
- "node": ">=0.1.14"
- }
- },
"node_modules/string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -2384,15 +2239,6 @@
"node": ">=8"
}
},
- "node_modules/svg-pathdata": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz",
- "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==",
- "optional": true,
- "engines": {
- "node": ">=12.0.0"
- }
- },
"node_modules/tapable": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz",
@@ -2437,21 +2283,17 @@
"node": ">=0.10.0"
}
},
- "node_modules/text-segmentation": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
- "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
- "optional": true,
- "dependencies": {
- "utrie": "^1.0.2"
- }
- },
"node_modules/text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
+ "node_modules/tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -2502,15 +2344,6 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
- "node_modules/utrie": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
- "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
- "optional": true,
- "dependencies": {
- "base64-arraybuffer": "^1.0.2"
- }
- },
"node_modules/uuid": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
@@ -2670,14 +2503,6 @@
}
},
"dependencies": {
- "@babel/runtime": {
- "version": "7.23.2",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.23.2.tgz",
- "integrity": "sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg==",
- "requires": {
- "regenerator-runtime": "^0.14.0"
- }
- },
"@eslint/eslintrc": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.1.tgz",
@@ -2744,6 +2569,22 @@
"fastq": "^1.6.0"
}
},
+ "@pdf-lib/standard-fonts": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@pdf-lib/standard-fonts/-/standard-fonts-1.0.0.tgz",
+ "integrity": "sha512-hU30BK9IUN/su0Mn9VdlVKsWBS6GyhVfqjwl1FjZN4TxP6cCw0jP2w7V3Hf5uX7M0AZJ16vey9yE0ny7Sa59ZA==",
+ "requires": {
+ "pako": "^1.0.6"
+ }
+ },
+ "@pdf-lib/upng": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@pdf-lib/upng/-/upng-1.0.1.tgz",
+ "integrity": "sha512-dQK2FUMQtowVP00mtIksrlZhdFXQZPC+taih1q4CvPZ5vqdxR/LKBaFg0oAfzd1GlHZXXSPdQfzQnt+ViGvEIQ==",
+ "requires": {
+ "pako": "^1.0.10"
+ }
+ },
"@svgdotjs/svg.js": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@svgdotjs/svg.js/-/svg.js-3.1.2.tgz",
@@ -2770,12 +2611,6 @@
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz",
"integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA=="
},
- "@types/raf": {
- "version": "3.4.3",
- "resolved": "https://registry.npmjs.org/@types/raf/-/raf-3.4.3.tgz",
- "integrity": "sha512-c4YAvMedbPZ5tEyxzQdMoOhhJ4RD3rngZIdwC2/qDN3d7JpEhB6fiBRKVY1lg5B7Wk+uPBjn5f39j1/2MY1oOw==",
- "optional": true
- },
"@types/unist": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
@@ -2847,22 +2682,11 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
- "atob": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
- "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="
- },
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
- "base64-arraybuffer": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz",
- "integrity": "sha512-I3yl4r9QB5ZRY3XuJVEPfc2XhZO6YweFPI+UovAzn+8/hb3oJ6lnysaFcjVpkCPfVWFUDvoZ8kmVDP7WyRtYtQ==",
- "optional": true
- },
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
@@ -2877,11 +2701,6 @@
"concat-map": "0.0.1"
}
},
- "btoa": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/btoa/-/btoa-1.2.1.tgz",
- "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g=="
- },
"buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
@@ -2906,30 +2725,6 @@
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"dev": true
},
- "canvg": {
- "version": "3.0.10",
- "resolved": "https://registry.npmjs.org/canvg/-/canvg-3.0.10.tgz",
- "integrity": "sha512-qwR2FRNO9NlzTeKIPIKpnTY6fqwuYSequ8Ru8c0YkYU7U0oW+hLUvWadLvAu1Rl72OMNiFhoLu4f8eUjQ7l/+Q==",
- "optional": true,
- "requires": {
- "@babel/runtime": "^7.12.5",
- "@types/raf": "^3.4.0",
- "core-js": "^3.8.3",
- "raf": "^3.4.1",
- "regenerator-runtime": "^0.13.7",
- "rgbcolor": "^1.0.1",
- "stackblur-canvas": "^2.0.0",
- "svg-pathdata": "^6.0.3"
- },
- "dependencies": {
- "regenerator-runtime": {
- "version": "0.13.11",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
- "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==",
- "optional": true
- }
- }
- },
"chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
@@ -2975,12 +2770,6 @@
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
},
- "core-js": {
- "version": "3.33.3",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.33.3.tgz",
- "integrity": "sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw==",
- "optional": true
- },
"core-util-is": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
@@ -2997,15 +2786,6 @@
"which": "^2.0.1"
}
},
- "css-line-break": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/css-line-break/-/css-line-break-2.1.0.tgz",
- "integrity": "sha512-FHcKFCZcAha3LwfVBhCQbW2nCNbkZXn7KVUJcsT5/P8YmfsVja0FMPJr0B903j/E69HUphKiV9iQArX8SDYA4w==",
- "optional": true,
- "requires": {
- "utrie": "^1.0.2"
- }
- },
"debug": {
"version": "4.3.4",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
@@ -3074,12 +2854,6 @@
"esutils": "^2.0.2"
}
},
- "dompurify": {
- "version": "2.4.7",
- "resolved": "https://registry.npmjs.org/dompurify/-/dompurify-2.4.7.tgz",
- "integrity": "sha512-kxxKlPEDa6Nc5WJi+qRgPbOAbgTpSULL+vI3NUXsZMlkJxTqYI9wg5ZTay2sFrdZRWHPWNi+EdAhcJf81WtoMQ==",
- "optional": true
- },
"enhanced-resolve": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-2.3.0.tgz",
@@ -3273,11 +3047,6 @@
"reusify": "^1.0.4"
}
},
- "fflate": {
- "version": "0.4.8",
- "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.4.8.tgz",
- "integrity": "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA=="
- },
"file-entry-cache": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
@@ -3420,16 +3189,6 @@
"has-symbols": "^1.0.2"
}
},
- "html2canvas": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/html2canvas/-/html2canvas-1.4.1.tgz",
- "integrity": "sha512-fPU6BHNpsyIhr8yyMpTLLxAbkaK8ArIBcmZIRiBLiDhjeqvXolaEmDGmELFuX9I4xDcaKKcJl+TKZLqruBbmWA==",
- "optional": true,
- "requires": {
- "css-line-break": "^2.1.0",
- "text-segmentation": "^1.0.3"
- }
- },
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
@@ -3566,21 +3325,6 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
- "jspdf": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/jspdf/-/jspdf-2.5.1.tgz",
- "integrity": "sha512-hXObxz7ZqoyhxET78+XR34Xu2qFGrJJ2I2bE5w4SM8eFaFEkW2xcGRVUss360fYelwRSid/jT078kbNvmoW0QA==",
- "requires": {
- "@babel/runtime": "^7.14.0",
- "atob": "^2.1.2",
- "btoa": "^1.2.1",
- "canvg": "^3.0.6",
- "core-js": "^3.6.0",
- "dompurify": "^2.2.0",
- "fflate": "^0.4.8",
- "html2canvas": "^1.0.0-rc.5"
- }
- },
"jszip": {
"version": "3.10.1",
"resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
@@ -4013,11 +3757,16 @@
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
"dev": true
},
- "performance-now": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
- "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==",
- "optional": true
+ "pdf-lib": {
+ "version": "1.17.1",
+ "resolved": "https://registry.npmjs.org/pdf-lib/-/pdf-lib-1.17.1.tgz",
+ "integrity": "sha512-V/mpyJAoTsN4cnP31vc0wfNA1+p20evqqnap0KLoRUN0Yk/p3wN52DOEsL4oBFcLdb76hlpKPtzJIgo67j/XLw==",
+ "requires": {
+ "@pdf-lib/standard-fonts": "^1.0.0",
+ "@pdf-lib/upng": "^1.0.1",
+ "pako": "^1.0.11",
+ "tslib": "^1.11.1"
+ }
},
"prelude-ls": {
"version": "1.2.1",
@@ -4082,15 +3831,6 @@
"fast-diff": "1.1.2"
}
},
- "raf": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz",
- "integrity": "sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==",
- "optional": true,
- "requires": {
- "performance-now": "^2.1.0"
- }
- },
"randombytes": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@@ -4113,11 +3853,6 @@
"util-deprecate": "~1.0.1"
}
},
- "regenerator-runtime": {
- "version": "0.14.0",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz",
- "integrity": "sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA=="
- },
"regexp.prototype.flags": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
@@ -4146,12 +3881,6 @@
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
"dev": true
},
- "rgbcolor": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/rgbcolor/-/rgbcolor-1.0.1.tgz",
- "integrity": "sha512-9aZLIrhRaD97sgVhtJOW6ckOEh6/GnvQtdVNfdZ6s67+3/XwLS9lBcQYzEEhYVeUowN7pRzMLsyGhK2i/xvWbw==",
- "optional": true
- },
"rimraf": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
@@ -4234,12 +3963,6 @@
}
}
},
- "stackblur-canvas": {
- "version": "2.6.0",
- "resolved": "https://registry.npmjs.org/stackblur-canvas/-/stackblur-canvas-2.6.0.tgz",
- "integrity": "sha512-8S1aIA+UoF6erJYnglGPug6MaHYGo1Ot7h5fuXx4fUPvcvQfcdw2o/ppCse63+eZf8PPidSu4v1JnmEVtEDnpg==",
- "optional": true
- },
"string_decoder": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
@@ -4272,12 +3995,6 @@
"has-flag": "^4.0.0"
}
},
- "svg-pathdata": {
- "version": "6.0.3",
- "resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz",
- "integrity": "sha512-qsjeeq5YjBZ5eMdFuUa4ZosMLxgr5RZ+F+Y1OrDhuOCEInRMA3x74XdBtggJcj9kOeInz0WE+LgCPDkZFlBYJw==",
- "optional": true
- },
"tapable": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.9.tgz",
@@ -4309,21 +4026,17 @@
}
}
},
- "text-segmentation": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/text-segmentation/-/text-segmentation-1.0.3.tgz",
- "integrity": "sha512-iOiPUo/BGnZ6+54OsWxZidGCsdU8YbE4PSpdPinp7DeMtUJNJBoJ/ouUSTJjHkh1KntHaltHl/gDs2FC4i5+Nw==",
- "optional": true,
- "requires": {
- "utrie": "^1.0.2"
- }
- },
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
"dev": true
},
+ "tslib": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
+ "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
+ },
"type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -4361,15 +4074,6 @@
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
},
- "utrie": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/utrie/-/utrie-1.0.2.tgz",
- "integrity": "sha512-1MLa5ouZiOmQzUbjbu9VmjLzn1QLXBhwpUa7kdLUQK+KQ5KA9I1vk5U4YHe/X2Ch7PYnJfWuWT+VbuxbGwljhw==",
- "optional": true,
- "requires": {
- "base64-arraybuffer": "^1.0.2"
- }
- },
"uuid": {
"version": "9.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz",
diff --git a/simple-mind-map/package.json b/simple-mind-map/package.json
index c57e0575..43711733 100644
--- a/simple-mind-map/package.json
+++ b/simple-mind-map/package.json
@@ -31,10 +31,10 @@
"@svgdotjs/svg.js": "^3.0.16",
"deepmerge": "^1.5.2",
"eventemitter3": "^4.0.7",
- "jspdf": "^2.5.1",
"jszip": "^3.10.1",
"katex": "^0.16.8",
"mdast-util-from-markdown": "^1.3.0",
+ "pdf-lib": "^1.17.1",
"quill": "^1.3.6",
"tern": "^0.24.3",
"uuid": "^9.0.0",
diff --git a/simple-mind-map/src/plugins/Export.js b/simple-mind-map/src/plugins/Export.js
index 79e538c1..225d90f4 100644
--- a/simple-mind-map/src/plugins/Export.js
+++ b/simple-mind-map/src/plugins/Export.js
@@ -22,7 +22,7 @@ class Export {
async export(type, isDownload = true, name = '思维导图', ...args) {
if (this[type]) {
const result = await this[type](name, ...args)
- if (isDownload && type !== 'pdf') {
+ if (isDownload) {
downloadFile(result, name + '.' + type)
}
return result
@@ -229,7 +229,11 @@ class Export {
throw new Error('请注册ExportPDF插件')
}
const img = await this.png(name, transparent)
- await this.mindMap.doExportPDF.pdf(name, img)
+ // 使用jspdf库
+ // await this.mindMap.doExportPDF.pdf(name, img)
+ // 使用pdf-lib库
+ const res = await this.mindMap.doExportPDF.pdf(img)
+ return res
}
// 导出为xmind
diff --git a/simple-mind-map/src/plugins/ExportPDF.js b/simple-mind-map/src/plugins/ExportPDF.js
index 6d231e9a..6cf902c5 100644
--- a/simple-mind-map/src/plugins/ExportPDF.js
+++ b/simple-mind-map/src/plugins/ExportPDF.js
@@ -1,4 +1,6 @@
-import JsPDF from '../utils/jspdf'
+// import JsPDF from '../utils/jspdf'
+import { PDFDocument } from 'pdf-lib'
+import { readBlob } from '../utils/index'
// 导出PDF插件,需要通过Export插件使用
class ExportPDF {
@@ -7,23 +9,29 @@ class ExportPDF {
this.mindMap = opt.mindMap
}
- // 导出为pdf
- async pdf(name, img) {
+ // 使用pdf-lib库导出为pdf
+ async pdf(img) {
return new Promise((resolve, reject) => {
const image = new Image()
- image.onload = () => {
+ image.onload = async () => {
const imageWidth = image.width
const imageHeight = image.height
- const pdf = new JsPDF({
- unit: 'px',
- format: [imageWidth, imageHeight],
- compress: true,
- hotfixes: ['px_scaling'],
- orientation: imageWidth > imageHeight ? 'landscape' : 'portrait'
+ // 创建pdf页面,尺寸设置为图片的大小
+ const pdfDoc = await PDFDocument.create()
+ const page = pdfDoc.addPage()
+ page.setSize(imageWidth, imageHeight)
+ // 添加图片到pdf
+ const pngImage = await pdfDoc.embedPng(img)
+ page.drawImage(pngImage, {
+ x: 0,
+ y: 0,
+ width: imageWidth,
+ height: imageHeight
})
- pdf.addImage(img, 'PNG', 0, 0, imageWidth, imageHeight)
- pdf.save(name)
- resolve()
+ const pdfBytes = await pdfDoc.save()
+ const blob = new Blob([pdfBytes])
+ const res = await readBlob(blob)
+ resolve(res)
}
image.onerror = e => {
reject(e)
@@ -31,6 +39,31 @@ class ExportPDF {
image.src = img
})
}
+
+ // 使用jspdf库导出为pdf
+ // async pdf(name, img) {
+ // return new Promise((resolve, reject) => {
+ // const image = new Image()
+ // image.onload = () => {
+ // const imageWidth = image.width
+ // const imageHeight = image.height
+ // const pdf = new JsPDF({
+ // unit: 'px',
+ // format: [imageWidth, imageHeight],
+ // compress: true,
+ // hotfixes: ['px_scaling'],
+ // orientation: imageWidth > imageHeight ? 'landscape' : 'portrait'
+ // })
+ // pdf.addImage(img, 'PNG', 0, 0, imageWidth, imageHeight)
+ // pdf.save(name)
+ // resolve()
+ // }
+ // image.onerror = e => {
+ // reject(e)
+ // }
+ // image.src = img
+ // })
+ // }
}
ExportPDF.instanceName = 'doExportPDF'
From 7196c37e9a32c7bbbbf7780793f1b0f5c3054c28 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Thu, 28 Dec 2023 09:27:43 +0800
Subject: [PATCH 02/21] Doc: update
---
web/src/pages/Doc/zh/course17/index.md | 2 +-
web/src/pages/Doc/zh/course17/index.vue | 2 +-
web/src/pages/Doc/zh/doExport/index.md | 4 +++-
web/src/pages/Doc/zh/doExport/index.vue | 5 ++++-
4 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/web/src/pages/Doc/zh/course17/index.md b/web/src/pages/Doc/zh/course17/index.md
index 6765cff2..24cf3b83 100644
--- a/web/src/pages/Doc/zh/course17/index.md
+++ b/web/src/pages/Doc/zh/course17/index.md
@@ -16,7 +16,7 @@ mindMap.export(type, isDownload, fileName, ...)
`type`:文件类型
-`isDownload`:传`true`会触发下载,`false`则不会,函数会返回导出文件的数据,`data:url`格式,你可以自行下载,`pdf`不支持该参数,默认会直接下载。
+`isDownload`:传`true`会触发下载,`false`则不会,函数会返回导出文件的数据,`data:url`格式,你可以自行下载,(v0.9.2之前的版本,`pdf`不支持该参数,默认会直接下载)。
`fileName`:下载的文件名称
diff --git a/web/src/pages/Doc/zh/course17/index.vue b/web/src/pages/Doc/zh/course17/index.vue
index 87a8a9bd..8c2a703a 100644
--- a/web/src/pages/Doc/zh/course17/index.vue
+++ b/web/src/pages/Doc/zh/course17/index.vue
@@ -11,7 +11,7 @@
mindMap.export(type, isDownload, fileName, ...)
type:文件类型
-isDownload:传true会触发下载,false则不会,函数会返回导出文件的数据,data:url格式,你可以自行下载,pdf不支持该参数,默认会直接下载。
+isDownload:传true会触发下载,false则不会,函数会返回导出文件的数据,data:url格式,你可以自行下载,(v0.9.2之前的版本,pdf不支持该参数,默认会直接下载)。
fileName:下载的文件名称
导出为smm、json
这两种文件的导出是一样的:
diff --git a/web/src/pages/Doc/zh/doExport/index.md b/web/src/pages/Doc/zh/doExport/index.md
index 5e316b16..6ed31653 100644
--- a/web/src/pages/Doc/zh/doExport/index.md
+++ b/web/src/pages/Doc/zh/doExport/index.md
@@ -88,7 +88,9 @@ svg(
- `transparent`:v0.9.2+,Boolean,默认为false,指定导出图片的背景是否是透明的
-导出为`pdf`,和其他导出方法不一样,这个方法不会返回数据,会直接触发下载。
+导出为`pdf`,
+
+> v0.9.3之前的版本这个方法不会返回数据,会直接触发下载。
> v0.6.0版本以后,需要额外注册一个ExportPDF插件
diff --git a/web/src/pages/Doc/zh/doExport/index.vue b/web/src/pages/Doc/zh/doExport/index.vue
index 70803d94..ba87aa09 100644
--- a/web/src/pages/Doc/zh/doExport/index.vue
+++ b/web/src/pages/Doc/zh/doExport/index.vue
@@ -90,7 +90,10 @@ a.click()
transparent:v0.9.2+,Boolean,默认为false,指定导出图片的背景是否是透明的
-导出为pdf,和其他导出方法不一样,这个方法不会返回数据,会直接触发下载。
+导出为pdf,
+
+v0.9.3之前的版本这个方法不会返回数据,会直接触发下载。
+
v0.6.0版本以后,需要额外注册一个ExportPDF插件
From ee97731e18dacafe8a9d076094221e2a36e2a8c6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Thu, 28 Dec 2023 17:30:58 +0800
Subject: [PATCH 03/21] =?UTF-8?q?Feat=EF=BC=9A=E8=AE=BE=E7=BD=AE=E8=8A=82?=
=?UTF-8?q?=E7=82=B9=E6=96=87=E6=9C=AC=E5=91=BD=E4=BB=A4=E7=9A=84=E7=AC=AC?=
=?UTF-8?q?=E4=BA=8C=E4=B8=AA=E5=8F=82=E6=95=B0=E5=A6=82=E6=9E=9C=E6=B2=A1?=
=?UTF-8?q?=E6=9C=89=E4=BC=A0=E9=80=92=EF=BC=8C=E4=BC=9A=E4=BD=BF=E7=94=A8?=
=?UTF-8?q?=E4=B9=8B=E5=89=8D=E7=9A=84=E5=80=BC?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/core/render/Render.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/simple-mind-map/src/core/render/Render.js b/simple-mind-map/src/core/render/Render.js
index 76ae08cb..25c10d7a 100644
--- a/simple-mind-map/src/core/render/Render.js
+++ b/simple-mind-map/src/core/render/Render.js
@@ -1419,6 +1419,7 @@ class Render {
// 设置节点文本
setNodeText(node, text, richText, resetRichText) {
+ richText = richText === undefined ? node.getData('richText') : richText
this.setNodeDataRender(node, {
text,
richText,
From f087b7102e3afc75a0bb49af2d17707706e0d998 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Thu, 28 Dec 2023 18:49:31 +0800
Subject: [PATCH 04/21] =?UTF-8?q?Fix=EF=BC=9A=E4=BC=98=E5=8C=96=E8=8A=82?=
=?UTF-8?q?=E7=82=B9=E5=AD=98=E5=9C=A8=E8=B6=85=E9=93=BE=E6=8E=A5=E3=80=81?=
=?UTF-8?q?=E5=A4=87=E6=B3=A8=E6=97=B6=E5=9C=A8firefox=E6=B5=8F=E8=A7=88?=
=?UTF-8?q?=E5=99=A8=E4=B8=AD=E5=AF=BC=E5=87=BA=E5=9B=BE=E7=89=87=E7=9A=84?=
=?UTF-8?q?=E5=AE=BD=E9=AB=98=E4=B8=8D=E4=B9=8B=E5=89=8D=E7=9A=84=E9=97=AE?=
=?UTF-8?q?=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/core/render/node/nodeCreateContents.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/simple-mind-map/src/core/render/node/nodeCreateContents.js b/simple-mind-map/src/core/render/node/nodeCreateContents.js
index d6528a5f..206e97fd 100644
--- a/simple-mind-map/src/core/render/node/nodeCreateContents.js
+++ b/simple-mind-map/src/core/render/node/nodeCreateContents.js
@@ -240,7 +240,7 @@ function createHyperlinkNode() {
return
}
let iconSize = this.mindMap.themeConfig.iconSize
- let node = new SVG()
+ let node = new SVG().size(iconSize, iconSize)
// 超链接节点
let a = new A().to(hyperlink).target('_blank')
a.node.addEventListener('click', e => {
@@ -298,7 +298,7 @@ function createNoteNode() {
return null
}
let iconSize = this.mindMap.themeConfig.iconSize
- let node = new SVG().attr('cursor', 'pointer')
+ let node = new SVG().attr('cursor', 'pointer').size(iconSize, iconSize)
// 透明的层,用来作为鼠标区域
node.add(new Rect().size(iconSize, iconSize).fill({ color: 'transparent' }))
// 备注图标
From 794d3e9a53fffb32c912503d046f7cdef79adf98 Mon Sep 17 00:00:00 2001
From: wanglin2 <1013335014@qq.com>
Date: Thu, 28 Dec 2023 21:36:45 +0800
Subject: [PATCH 05/21] =?UTF-8?q?Fix:=E4=BF=AE=E5=A4=8Dsafari=E6=B5=8F?=
=?UTF-8?q?=E8=A7=88=E5=99=A8=E8=8A=82=E7=82=B9=E5=AD=98=E5=9C=A8=E5=9B=BE?=
=?UTF-8?q?=E6=A0=87=E6=97=B6=E6=96=87=E5=AD=97=E4=BD=8D=E7=BD=AE=E9=94=99?=
=?UTF-8?q?=E4=BD=8D=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/core/render/node/Node.js | 3 ++-
simple-mind-map/src/core/render/node/nodeCreateContents.js | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/simple-mind-map/src/core/render/node/Node.js b/simple-mind-map/src/core/render/node/Node.js
index af47745a..c382b087 100644
--- a/simple-mind-map/src/core/render/node/Node.js
+++ b/simple-mind-map/src/core/render/node/Node.js
@@ -360,7 +360,8 @@ class Node {
// 文字
if (this._textData) {
this._textData.node.attr('data-offsetx', textContentOffsetX)
- this._textData.node.x(textContentOffsetX).y(0)
+ // 修复safari浏览器节点存在图标时文字位置不正确的问题
+ ;(this._textData.nodeContent || this._textData.node).x(textContentOffsetX).y(0)
textContentNested.add(this._textData.node)
textContentOffsetX += this._textData.width + textContentItemMargin
}
diff --git a/simple-mind-map/src/core/render/node/nodeCreateContents.js b/simple-mind-map/src/core/render/node/nodeCreateContents.js
index 206e97fd..86c3bc19 100644
--- a/simple-mind-map/src/core/render/node/nodeCreateContents.js
+++ b/simple-mind-map/src/core/render/node/nodeCreateContents.js
@@ -170,6 +170,7 @@ function createRichTextNode() {
g.add(foreignObject)
return {
node: g,
+ nodeContent: foreignObject,
width,
height
}
From eb50b702145ef5b7de58a0edfe00323d01311fa0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Fri, 29 Dec 2023 16:47:30 +0800
Subject: [PATCH 06/21] =?UTF-8?q?Fix=EF=BC=9A=E4=BF=AE=E5=A4=8DChrome?=
=?UTF-8?q?=E4=BD=8E=E7=89=88=E6=9C=AC=E5=85=AC=E5=BC=8F=E6=97=A0=E6=B3=95?=
=?UTF-8?q?=E6=B8=B2=E6=9F=93=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/plugins/Formula.js | 24 +++++++++++++++++++-----
simple-mind-map/src/utils/index.js | 9 +++++++++
2 files changed, 28 insertions(+), 5 deletions(-)
diff --git a/simple-mind-map/src/plugins/Formula.js b/simple-mind-map/src/plugins/Formula.js
index 82783e51..624404d2 100644
--- a/simple-mind-map/src/plugins/Formula.js
+++ b/simple-mind-map/src/plugins/Formula.js
@@ -1,5 +1,7 @@
import katex from 'katex'
import Quill from 'quill'
+import 'katex/dist/katex.min.css'
+import { getChromeVersion } from '../utils/index'
// 数学公式支持插件
// 该插件在富文本模式下可用
@@ -12,19 +14,31 @@ class Formula {
this.extendQuill()
}
+ // 获取katex配置
+ getKatexConfig() {
+ const config = {
+ throwOnError: false,
+ errorColor: '#f00',
+ output: 'mathml' // 默认只输出公式
+ }
+ // Chrome内核100以下,mathml配置公式无法正确渲染
+ const chromeVersion = getChromeVersion()
+ if (chromeVersion && chromeVersion <= 100) {
+ config.output = 'html'
+ }
+ return config
+ }
+
// 修改formula格式工具
extendQuill() {
const QuillFormula = Quill.import('formats/formula')
+ const self = this
class CustomFormulaBlot extends QuillFormula {
static create(value) {
let node = super.create(value)
if (typeof value === 'string') {
- katex.render(value, node, {
- throwOnError: false,
- errorColor: '#f00',
- output: 'mathml' // 增加该配置,默认只输出公式
- })
+ katex.render(value, node, self.getKatexConfig())
node.setAttribute('data-value', value)
}
return node
diff --git a/simple-mind-map/src/utils/index.js b/simple-mind-map/src/utils/index.js
index 824f4386..b0f3ebec 100644
--- a/simple-mind-map/src/utils/index.js
+++ b/simple-mind-map/src/utils/index.js
@@ -1018,3 +1018,12 @@ export const checkNodeListIsEqual = (list1, list2) => {
}
return true
}
+
+// 获取浏览器的chrome内核版本
+export const getChromeVersion = () => {
+ const match = navigator.userAgent.match(/\s+Chrome\/(.*)\s+/)
+ if (match && match[1]) {
+ return Number.parseFloat(match[1])
+ }
+ return ''
+}
From c0fb1e8db8734babfe969911444f9a67dc2e7469 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Fri, 29 Dec 2023 16:48:23 +0800
Subject: [PATCH 07/21] =?UTF-8?q?Demo=EF=BC=9A=E5=85=AC=E5=BC=8Fkatex?=
=?UTF-8?q?=E5=BA=93=E7=9A=84=E9=85=8D=E7=BD=AE=E4=BB=8Esimple-mind-map?=
=?UTF-8?q?=E5=BA=93=E4=B8=AD=E8=8E=B7=E5=8F=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/src/pages/Edit/components/FormulaSidebar.vue | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/web/src/pages/Edit/components/FormulaSidebar.vue b/web/src/pages/Edit/components/FormulaSidebar.vue
index 53fd655f..cc5ca88c 100644
--- a/web/src/pages/Edit/components/FormulaSidebar.vue
+++ b/web/src/pages/Edit/components/FormulaSidebar.vue
@@ -78,10 +78,10 @@ export default {
init() {
this.list = formulaList.map(item => {
return {
- overview: window.katex.renderToString(item, {
- throwOnError: false,
- output: 'mathml'
- }),
+ overview: window.katex.renderToString(
+ item,
+ this.mindMap.formula.getKatexConfig()
+ ),
text: item
}
})
From 1409b07fb3201c235e6f1bd2ddc648b9bbec84b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Fri, 29 Dec 2023 17:46:58 +0800
Subject: [PATCH 08/21] =?UTF-8?q?Feat=EF=BC=9A=E8=8A=82=E7=82=B9=E5=AF=8C?=
=?UTF-8?q?=E6=96=87=E6=9C=AC=E7=BC=96=E8=BE=91=E4=B8=AD=EF=BC=8C=E5=A6=82?=
=?UTF-8?q?=E6=9E=9C=E7=B2=98=E8=B4=B4=E7=9A=84=E6=98=AFsmm=E6=A0=BC?=
=?UTF-8?q?=E5=BC=8F=E7=9A=84=E6=95=B0=E6=8D=AE=EF=BC=8C=E9=82=A3=E4=B9=88?=
=?UTF-8?q?=E5=8F=96=E5=87=BA=E7=AC=AC=E4=B8=80=E4=B8=AA=E8=8A=82=E7=82=B9?=
=?UTF-8?q?=E7=9A=84=E7=BA=AF=E6=96=87=E6=9C=AC=E8=BF=9B=E8=A1=8C=E7=B2=98?=
=?UTF-8?q?=E8=B4=B4?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/core/render/Render.js | 33 ++++++++++-------------
simple-mind-map/src/plugins/RichText.js | 18 ++++++++++---
simple-mind-map/src/utils/index.js | 31 +++++++++++++++++++++
3 files changed, 60 insertions(+), 22 deletions(-)
diff --git a/simple-mind-map/src/core/render/Render.js b/simple-mind-map/src/core/render/Render.js
index 25c10d7a..01266d3f 100644
--- a/simple-mind-map/src/core/render/Render.js
+++ b/simple-mind-map/src/core/render/Render.js
@@ -26,7 +26,9 @@ import {
getDataFromClipboard,
htmlEscape,
parseAddGeneralizationNodeList,
- checkNodeListIsEqual
+ checkNodeListIsEqual,
+ createSmmFormatData,
+ checkSmmFormatData
} from '../../utils'
import { shapeList } from './node/Shape'
import { lineStyleProps } from '../../themes/default'
@@ -876,20 +878,14 @@ class Render {
copy() {
this.beingCopyData = this.copyNode()
if (!this.beingCopyData) return
- setDataToClipboard({
- simpleMindMap: true,
- data: this.beingCopyData
- })
+ setDataToClipboard(createSmmFormatData(this.beingCopyData))
}
// 剪切节点
cut() {
this.mindMap.execCommand('CUT_NODE', copyData => {
this.beingCopyData = copyData
- setDataToClipboard({
- simpleMindMap: true,
- data: copyData
- })
+ setDataToClipboard(createSmmFormatData(copyData))
})
}
@@ -936,10 +932,11 @@ class Render {
const res = await this.mindMap.opt.customHandleClipboardText(text)
if (!isUndef(res)) {
useDefault = false
- if (typeof res === 'object' && res.simpleMindMap) {
- smmData = res.data
+ const checkRes = checkSmmFormatData(res)
+ if (checkRes.isSmm) {
+ smmData = checkRes.data
} else {
- text = String(res)
+ text = checkRes.data
}
}
} catch (error) {
@@ -948,13 +945,11 @@ class Render {
}
// 默认处理
if (useDefault) {
- try {
- const parsedData = JSON.parse(text)
- if (parsedData && parsedData.simpleMindMap) {
- smmData = parsedData.data
- }
- } catch (error) {
- errorHandler(ERROR_TYPES.PARSE_PASTE_DATA_ERROR, error)
+ const checkRes = checkSmmFormatData(text)
+ if (checkRes.isSmm) {
+ smmData = checkRes.data
+ } else {
+ text = checkRes.data
}
}
if (smmData) {
diff --git a/simple-mind-map/src/plugins/RichText.js b/simple-mind-map/src/plugins/RichText.js
index 92dfd723..156f39c5 100644
--- a/simple-mind-map/src/plugins/RichText.js
+++ b/simple-mind-map/src/plugins/RichText.js
@@ -6,7 +6,8 @@ import {
getTextFromHtml,
isWhite,
getVisibleColorFromTheme,
- isUndef
+ isUndef,
+ checkSmmFormatData
} from '../utils'
import { CONSTANTS } from '../constants/constant'
@@ -397,7 +398,7 @@ class RichText {
// 拦截粘贴,只允许粘贴纯文本
this.quill.clipboard.addMatcher(Node.TEXT_NODE, node => {
let style = this.getPasteTextStyle()
- return new Delta().insert(node.data, style)
+ return new Delta().insert(this.formatPasteText(node.data), style)
})
this.quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
let ops = []
@@ -407,7 +408,7 @@ class RichText {
if (op.insert && typeof op.insert === 'string' && op.insert !== '\n') {
ops.push({
attributes: { ...style },
- insert: op.insert
+ insert: this.formatPasteText(op.insert)
})
}
})
@@ -428,6 +429,17 @@ class RichText {
return {}
}
+ // 处理粘贴的文本内容
+ formatPasteText(text) {
+ const { isSmm, data } = checkSmmFormatData(text)
+ if (isSmm && data[0] && data[0].data) {
+ // 只取第一个节点的纯文本
+ return getTextFromHtml(data[0].data.text)
+ } else {
+ return text
+ }
+ }
+
// 正则输入中文
onCompositionStart() {
if (!this.showTextEdit) {
diff --git a/simple-mind-map/src/utils/index.js b/simple-mind-map/src/utils/index.js
index b0f3ebec..6417e79d 100644
--- a/simple-mind-map/src/utils/index.js
+++ b/simple-mind-map/src/utils/index.js
@@ -1027,3 +1027,34 @@ export const getChromeVersion = () => {
}
return ''
}
+
+// 创建smm粘贴的粘贴数据
+export const createSmmFormatData = data => {
+ return {
+ simpleMindMap: true,
+ data
+ }
+}
+
+// 检查是否是smm粘贴格式的数据
+export const checkSmmFormatData = data => {
+ let smmData = null
+ // 如果是字符串,则尝试解析为对象
+ if (typeof data === 'string') {
+ try {
+ const parsedData = JSON.parse(data)
+ // 判断是否是对象,且存在属性标志
+ if (typeof parsedData === 'object' && parsedData.simpleMindMap) {
+ smmData = parsedData.data
+ }
+ } catch (error) {}
+ } else if (typeof data === 'object' && data.simpleMindMap) {
+ // 否则如果是对象,则检查属性标志
+ smmData = data.data
+ }
+ const isSmm = !!smmData
+ return {
+ isSmm,
+ data: isSmm ? smmData : String(data)
+ }
+}
From 0cfa21d4e6a8446213790bc6b46b3c6f3f8c8399 Mon Sep 17 00:00:00 2001
From: wanglin2 <1013335014@qq.com>
Date: Fri, 29 Dec 2023 22:02:15 +0800
Subject: [PATCH 09/21] =?UTF-8?q?Feat:=E5=A2=9E=E5=8A=A0=E5=AF=B9=E8=8A=82?=
=?UTF-8?q?=E7=82=B9=E9=9D=9E=E5=AF=8C=E6=96=87=E6=9C=AC=E7=BC=96=E8=BE=91?=
=?UTF-8?q?=E6=97=B6=E7=9A=84=E7=B2=98=E8=B4=B4=E7=9A=84=E6=8B=A6=E6=88=AA?=
=?UTF-8?q?=E6=93=8D=E4=BD=9C?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/core/render/TextEdit.js | 15 ++++++++++++++-
simple-mind-map/src/utils/index.js | 16 ++++++++++++++++
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/simple-mind-map/src/core/render/TextEdit.js b/simple-mind-map/src/core/render/TextEdit.js
index 620ba85a..6d96b1ea 100644
--- a/simple-mind-map/src/core/render/TextEdit.js
+++ b/simple-mind-map/src/core/render/TextEdit.js
@@ -3,7 +3,10 @@ import {
checkNodeOuter,
focusInput,
selectAllInput,
- htmlEscape
+ htmlEscape,
+ handleInputPasteText,
+ checkSmmFormatData,
+ getTextFromHtml
} from '../../utils'
import { ERROR_TYPES, CONSTANTS } from '../../constants/constant'
@@ -226,6 +229,16 @@ export default class TextEdit {
e.stopPropagation()
}
})
+ this.textEditNode.addEventListener('paste', e => {
+ const text = e.clipboardData.getData('text')
+ const { isSmm, data } = checkSmmFormatData(text)
+ if (isSmm && data[0] && data[0].data) {
+ // 只取第一个节点的纯文本
+ handleInputPasteText(e, getTextFromHtml(data[0].data.text))
+ } else {
+ handleInputPasteText(e)
+ }
+ })
const targetNode =
this.mindMap.opt.customInnerElsAppendTo || document.body
targetNode.appendChild(this.textEditNode)
diff --git a/simple-mind-map/src/utils/index.js b/simple-mind-map/src/utils/index.js
index 6417e79d..6fdf0230 100644
--- a/simple-mind-map/src/utils/index.js
+++ b/simple-mind-map/src/utils/index.js
@@ -1058,3 +1058,19 @@ export const checkSmmFormatData = data => {
data: isSmm ? smmData : String(data)
}
}
+
+// 处理输入框的粘贴事件,会去除文本的html格式、换行
+export const handleInputPasteText = (e, text) => {
+ e.preventDefault()
+ const selection = window.getSelection()
+ if (!selection.rangeCount) return
+ selection.deleteFromDocument()
+ text = text || e.clipboardData.getData('text')
+ // 去除格式
+ text = getTextFromHtml(text)
+ // 去除换行
+ text = text.replaceAll(/\n/g, '')
+ const node = document.createTextNode(text)
+ selection.getRangeAt(0).insertNode(node)
+ selection.collapseToEnd()
+}
From 1bb7e431fb7030de79b373ca54bb702c6885c4d9 Mon Sep 17 00:00:00 2001
From: wanglin2 <1013335014@qq.com>
Date: Fri, 29 Dec 2023 22:04:56 +0800
Subject: [PATCH 10/21] =?UTF-8?q?Demo:=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/src/pages/Doc/zh/course12/index.md | 2 +-
web/src/pages/Doc/zh/course12/index.vue | 2 +-
web/src/pages/Edit/components/Outline.vue | 17 +++--------------
web/src/pages/Edit/components/OutlineEdit.vue | 17 +++--------------
4 files changed, 8 insertions(+), 30 deletions(-)
diff --git a/web/src/pages/Doc/zh/course12/index.md b/web/src/pages/Doc/zh/course12/index.md
index 97a72afd..3842b7d5 100644
--- a/web/src/pages/Doc/zh/course12/index.md
+++ b/web/src/pages/Doc/zh/course12/index.md
@@ -287,7 +287,7 @@ onPaste(e) {
if (!selection.rangeCount) return
selection.deleteFromDocument()// 删除当前选区,也就是如果当前用户在输入框中选择了一些文本,会被删除
// 从剪贴板里取出文本数据
- let text = (e.clipboardData || window.clipboardData).getData('text')
+ let text = e.clipboardData.getData('text')
// 调用库提供的getTextFromHtml方法去除格式
text = getTextFromHtml(text)
// 去除换行
diff --git a/web/src/pages/Doc/zh/course12/index.vue b/web/src/pages/Doc/zh/course12/index.vue
index e8b68667..8ccdbd71 100644
--- a/web/src/pages/Doc/zh/course12/index.vue
+++ b/web/src/pages/Doc/zh/course12/index.vue
@@ -237,7 +237,7 @@ mindMap.execCommand('INSERT_CHILD_NODE'if (!selection.rangeCount) return
selection.deleteFromDocument()
- let text = (e.clipboardData || window.clipboardData).getData('text')
+ let text = e.clipboardData.getData('text')
text = getTextFromHtml(text)
diff --git a/web/src/pages/Edit/components/Outline.vue b/web/src/pages/Edit/components/Outline.vue
index c6ba3b30..0e7d663e 100644
--- a/web/src/pages/Edit/components/Outline.vue
+++ b/web/src/pages/Edit/components/Outline.vue
@@ -41,9 +41,9 @@ import { mapState } from 'vuex'
import {
nodeRichTextToTextWithWrap,
textToNodeRichTextWithWrap,
- getTextFromHtml,
createUid,
- htmlEscape
+ htmlEscape,
+ handleInputPasteText
} from 'simple-mind-map/src/utils'
// 大纲树
@@ -212,18 +212,7 @@ export default {
// 拦截粘贴事件
onPaste(e) {
- e.preventDefault()
- const selection = window.getSelection()
- if (!selection.rangeCount) return
- selection.deleteFromDocument()
- let text = (e.clipboardData || window.clipboardData).getData('text')
- // 去除格式
- text = getTextFromHtml(text)
- // 去除换行
- text = text.replaceAll(/\n/g, '')
- const node = document.createTextNode(text)
- selection.getRangeAt(0).insertNode(node)
- selection.collapseToEnd()
+ handleInputPasteText(e)
},
// 生成唯一的key
diff --git a/web/src/pages/Edit/components/OutlineEdit.vue b/web/src/pages/Edit/components/OutlineEdit.vue
index aea3eea2..1ab514fd 100644
--- a/web/src/pages/Edit/components/OutlineEdit.vue
+++ b/web/src/pages/Edit/components/OutlineEdit.vue
@@ -52,10 +52,10 @@ import { mapState, mapMutations } from 'vuex'
import {
nodeRichTextToTextWithWrap,
textToNodeRichTextWithWrap,
- getTextFromHtml,
createUid,
simpleDeepClone,
- htmlEscape
+ htmlEscape,
+ handleInputPasteText
} from 'simple-mind-map/src/utils'
import { storeData } from '@/api'
@@ -211,18 +211,7 @@ export default {
// 拦截粘贴事件
onPaste(e) {
- e.preventDefault()
- const selection = window.getSelection()
- if (!selection.rangeCount) return
- selection.deleteFromDocument()
- let text = (e.clipboardData || window.clipboardData).getData('text')
- // 去除格式
- text = getTextFromHtml(text)
- // 去除换行
- text = text.replaceAll(/\n/g, '')
- const node = document.createTextNode(text)
- selection.getRangeAt(0).insertNode(node)
- selection.collapseToEnd()
+ handleInputPasteText(e)
},
// 生成唯一的key
From 3a6a2544b228784792841a5f74092b488fe3429b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Wed, 3 Jan 2024 17:29:22 +0800
Subject: [PATCH 11/21] Doc: update
---
README.md | 26 +++++++++++---------
web/src/assets/avatar/欣.jpg | Bin 0 -> 39711 bytes
web/src/pages/Doc/en/introduction/index.md | 4 +++
web/src/pages/Doc/en/introduction/index.vue | 4 +++
web/src/pages/Doc/zh/introduction/index.md | 4 +++
web/src/pages/Doc/zh/introduction/index.vue | 4 +++
6 files changed, 31 insertions(+), 11 deletions(-)
create mode 100644 web/src/assets/avatar/欣.jpg
diff --git a/README.md b/README.md
index ecc47c1a..37eb864a 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
[](https://github.com/wanglin2/mind-map/network/members)

-> 一个简单&强大的Web思维导图
+> 一个简单&强大的 Web 思维导图
本项目包含两部分:
@@ -27,7 +27,7 @@ Github:[releases](https://github.com/wanglin2/mind-map/releases)。
> 客户端版本会落后于在线版本,尝试最新功能请优先使用在线版。
-> 如果访问github比较慢,可以使用:http://lxqnsys.com/simple-mind-map/#/index
+> 如果访问 github 比较慢,可以使用:http://lxqnsys.com/simple-mind-map/#/index
# 特性
@@ -37,7 +37,7 @@ Github:[releases](https://github.com/wanglin2/mind-map/releases)。
- [x] 节点内容支持文本(普通文本、富文本)、图片、图标、超链接、备注、标签、概要、数学公式
- [x] 节点支持拖拽(拖拽移动、自由调整)、多种节点形状,支持使用 DDM 完全自定义节点内容
- [x] 支持画布拖动、缩放
-- [x] 支持鼠标按键拖动选择和Ctrl+左键两种多选节点方式
+- [x] 支持鼠标按键拖动选择和 Ctrl+左键两种多选节点方式
- [x] 支持导出为`json`、`png`、`svg`、`pdf`、`markdown`、`xmind`,支持从`json`、`xmind`、`markdown`导入
- [x] 支持快捷键、前进后退、关联线、搜索替换、小地图、水印、滚动条
- [x] 提供丰富的配置,满足各种场景各种使用习惯
@@ -51,7 +51,7 @@ npm i simple-mind-map
# 使用
-提供一个宽高不为0的容器元素:
+提供一个宽高不为 0 的容器元素:
```html
@@ -72,13 +72,13 @@ npm i simple-mind-map
import MindMap from "simple-mind-map";
const mindMap = new MindMap({
- el: document.getElementById('mindMapContainer'),
+ el: document.getElementById("mindMapContainer"),
data: {
- "data": {
- "text": "根节点"
+ data: {
+ text: "根节点",
},
- "children": []
- }
+ children: [],
+ },
});
```
@@ -88,7 +88,7 @@ const mindMap = new MindMap({
# License
-请尽情享受开源:[MIT](./LICENSE)
+[MIT](./LICENSE)
# 微信交流群
@@ -244,4 +244,8 @@ const mindMap = new MindMap({
继龙
-
\ No newline at end of file
+
+
+ 欣
+
+
diff --git a/web/src/assets/avatar/欣.jpg b/web/src/assets/avatar/欣.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..09dc78bc3f193574a11b36ae8fb974ba1233a187
GIT binary patch
literal 39711
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
XHy}+&cpv#%9ZVlt;S4$degFRehP=jv
literal 0
HcmV?d00001
diff --git a/web/src/pages/Doc/en/introduction/index.md b/web/src/pages/Doc/en/introduction/index.md
index 28c4375f..d62dde94 100644
--- a/web/src/pages/Doc/en/introduction/index.md
+++ b/web/src/pages/Doc/en/introduction/index.md
@@ -269,4 +269,8 @@ Open source is not easy. If this project is helpful to you, you can invite the a
继龙
+
+

+
欣
+
\ No newline at end of file
diff --git a/web/src/pages/Doc/en/introduction/index.vue b/web/src/pages/Doc/en/introduction/index.vue
index 2fc3335e..73cd2453 100644
--- a/web/src/pages/Doc/en/introduction/index.vue
+++ b/web/src/pages/Doc/en/introduction/index.vue
@@ -225,6 +225,10 @@ full screen, support mini map
继龙
+
+

+
欣
+
diff --git a/web/src/pages/Doc/zh/introduction/index.md b/web/src/pages/Doc/zh/introduction/index.md
index 0c733510..aa65f43d 100644
--- a/web/src/pages/Doc/zh/introduction/index.md
+++ b/web/src/pages/Doc/zh/introduction/index.md
@@ -262,4 +262,8 @@
继龙
+
+

+
欣
+
\ No newline at end of file
diff --git a/web/src/pages/Doc/zh/introduction/index.vue b/web/src/pages/Doc/zh/introduction/index.vue
index 83b1e1e1..ad2425b1 100644
--- a/web/src/pages/Doc/zh/introduction/index.vue
+++ b/web/src/pages/Doc/zh/introduction/index.vue
@@ -219,6 +219,10 @@
继龙
+
+

+
欣
+
From a488b436eeabf60b65a0d45f69753ea24b84d76e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Wed, 3 Jan 2024 17:56:35 +0800
Subject: [PATCH 12/21] =?UTF-8?q?=E6=89=93=E5=8C=85=E5=BA=93=E6=97=B6?=
=?UTF-8?q?=E8=87=AA=E5=8A=A8=E6=9B=B4=E6=96=B0=E7=89=88=E6=9C=AC=E5=8F=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/full.js | 1 +
web/package.json | 2 +-
web/scripts/updateVersion.js | 11 +++++++++++
3 files changed, 13 insertions(+), 1 deletion(-)
create mode 100644 web/scripts/updateVersion.js
diff --git a/simple-mind-map/full.js b/simple-mind-map/full.js
index 68f47c64..5c107526 100644
--- a/simple-mind-map/full.js
+++ b/simple-mind-map/full.js
@@ -28,6 +28,7 @@ MindMap.iconList = icons.nodeIconList
MindMap.constants = constants
MindMap.themes = themes
MindMap.defaultTheme = defaultTheme
+MindMap.version = '0.9.2'
MindMap.usePlugin(MiniMap)
.usePlugin(Watermark)
diff --git a/web/package.json b/web/package.json
index 3d017884..e39219f0 100644
--- a/web/package.json
+++ b/web/package.json
@@ -6,7 +6,7 @@
"serve": "vue-cli-service serve",
"build": "vue-cli-service build && node ../copy.js",
"lint": "vue-cli-service lint",
- "buildLibrary": "vue-cli-service build --mode library --target lib --name simpleMindMap ../simple-mind-map/full.js --dest ../simple-mind-map/dist && esbuild ../simple-mind-map/full.js --bundle --external:buffer --format=esm --outfile=../simple-mind-map/dist/simpleMindMap.esm.js && esbuild ../simple-mind-map/full.js --bundle --minify --external:buffer --format=esm --outfile=../simple-mind-map/dist/simpleMindMap.esm.min.js",
+ "buildLibrary": "node ./scripts/updateVersion.js && vue-cli-service build --mode library --target lib --name simpleMindMap ../simple-mind-map/full.js --dest ../simple-mind-map/dist && esbuild ../simple-mind-map/full.js --bundle --external:buffer --format=esm --outfile=../simple-mind-map/dist/simpleMindMap.esm.js && esbuild ../simple-mind-map/full.js --bundle --minify --external:buffer --format=esm --outfile=../simple-mind-map/dist/simpleMindMap.esm.min.js",
"format": "prettier --write src/* src/*/* src/*/*/* src/*/*/*/*",
"buildDoc": "node ./scripts/buildDoc.js",
"autoBuildDoc": "node ./scripts/autoBuildDoc.js",
diff --git a/web/scripts/updateVersion.js b/web/scripts/updateVersion.js
new file mode 100644
index 00000000..c85b0b8a
--- /dev/null
+++ b/web/scripts/updateVersion.js
@@ -0,0 +1,11 @@
+const path = require('path')
+const fs = require('fs')
+const pkg = require('../../simple-mind-map/package.json')
+
+const file = path.resolve('../simple-mind-map/full.js')
+let content = fs.readFileSync(file, 'utf-8')
+content = content.replace(
+ /(MindMap.version\s*=\s*)[^\n]+(\n)/,
+ `$1'${pkg.version}'$2`
+)
+fs.writeFileSync(file, content)
From 1ad1538699d1586dc6d98c13a41cd02e26bac5ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Wed, 3 Jan 2024 18:04:19 +0800
Subject: [PATCH 13/21] =?UTF-8?q?=E5=BA=93=E4=B8=8D=E5=86=8D=E5=AF=BC?=
=?UTF-8?q?=E5=85=A5katex=E7=9A=84css=E6=96=87=E4=BB=B6=EF=BC=8C=E7=94=B1?=
=?UTF-8?q?=E4=BD=BF=E7=94=A8=E6=96=B9=E5=AF=BC=E5=85=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/plugins/Formula.js | 1 -
web/src/pages/Edit/components/FormulaSidebar.vue | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/simple-mind-map/src/plugins/Formula.js b/simple-mind-map/src/plugins/Formula.js
index 624404d2..2e031d55 100644
--- a/simple-mind-map/src/plugins/Formula.js
+++ b/simple-mind-map/src/plugins/Formula.js
@@ -1,6 +1,5 @@
import katex from 'katex'
import Quill from 'quill'
-import 'katex/dist/katex.min.css'
import { getChromeVersion } from '../utils/index'
// 数学公式支持插件
diff --git a/web/src/pages/Edit/components/FormulaSidebar.vue b/web/src/pages/Edit/components/FormulaSidebar.vue
index cc5ca88c..79925695 100644
--- a/web/src/pages/Edit/components/FormulaSidebar.vue
+++ b/web/src/pages/Edit/components/FormulaSidebar.vue
@@ -34,6 +34,7 @@
import Sidebar from './Sidebar'
import { mapState, mapMutations } from 'vuex'
import { formulaList } from '@/config/constant'
+import 'simple-mind-map/node_modules/katex/dist/katex.min.css'
export default {
name: 'FormulaSidebar',
From 541606b2eb891a031231c8ddc0cb926c0878910d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Thu, 4 Jan 2024 09:39:44 +0800
Subject: [PATCH 14/21] =?UTF-8?q?Feat=EF=BC=9A=E6=96=B0=E5=A2=9E=E8=8A=82?=
=?UTF-8?q?=E7=82=B9=E6=95=B0=E6=8D=AE=E6=9B=B4=E6=96=B0=E6=98=8E=E7=BB=86?=
=?UTF-8?q?=E4=BA=8B=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/core/command/Command.js | 74 +++++++++--
.../src/core/command/KeyCommand.js | 1 +
simple-mind-map/src/plugins/Cooperate.js | 120 ++----------------
simple-mind-map/src/utils/index.js | 105 +++++++++++++++
4 files changed, 182 insertions(+), 118 deletions(-)
diff --git a/simple-mind-map/src/core/command/Command.js b/simple-mind-map/src/core/command/Command.js
index d1638dee..0fa38cba 100644
--- a/simple-mind-map/src/core/command/Command.js
+++ b/simple-mind-map/src/core/command/Command.js
@@ -1,4 +1,10 @@
-import { copyRenderTree, simpleDeepClone, throttle } from '../../utils'
+import {
+ copyRenderTree,
+ simpleDeepClone,
+ throttle,
+ isSameObject,
+ transformTreeDataToObject
+} from '../../utils'
// 命令类
class Command {
@@ -84,15 +90,14 @@ class Command {
if (this.mindMap.opt.readonly) {
return
}
- let data = this.getCopyData()
+ const lastData =
+ this.history.length > 0 ? this.history[this.history.length - 1] : null
+ const data = this.getCopyData()
// 此次数据和上次一样则不重复添加
- if (
- this.history.length > 0 &&
- JSON.stringify(this.history[this.history.length - 1]) ===
- JSON.stringify(data)
- ) {
+ if (lastData && JSON.stringify(lastData) === JSON.stringify(data)) {
return
}
+ this.emitDataUpdatesEvent(lastData, data)
// 删除当前历史指针后面的数据
this.history = this.history.slice(0, this.activeHistoryIndex + 1)
this.history.push(simpleDeepClone(data))
@@ -115,13 +120,15 @@ class Command {
return
}
if (this.activeHistoryIndex - step >= 0) {
+ const lastData = this.history[this.activeHistoryIndex]
this.activeHistoryIndex -= step
this.mindMap.emit(
'back_forward',
this.activeHistoryIndex,
this.history.length
)
- let data = simpleDeepClone(this.history[this.activeHistoryIndex])
+ const data = simpleDeepClone(this.history[this.activeHistoryIndex])
+ this.emitDataUpdatesEvent(lastData, data)
this.mindMap.emit('data_change', data)
return data
}
@@ -134,13 +141,15 @@ class Command {
}
let len = this.history.length
if (this.activeHistoryIndex + step <= len - 1) {
+ const lastData = this.history[this.activeHistoryIndex]
this.activeHistoryIndex += step
this.mindMap.emit(
'back_forward',
this.activeHistoryIndex,
this.history.length
)
- let data = simpleDeepClone(this.history[this.activeHistoryIndex])
+ const data = simpleDeepClone(this.history[this.activeHistoryIndex])
+ this.emitDataUpdatesEvent(lastData, data)
this.mindMap.emit('data_change', data)
return data
}
@@ -165,6 +174,53 @@ class Command {
walk(data)
return data
}
+
+ // 派发思维导图更新明细事件
+ emitDataUpdatesEvent(lastData, data) {
+ // 如果data_change_detail没有监听者,那么不进行计算,节省性能
+ const eventName = 'data_change_detail'
+ const count = this.mindMap.event.listenerCount(eventName)
+ if (count > 0 && lastData && data) {
+ const lastDataObj = simpleDeepClone(transformTreeDataToObject(lastData))
+ const dataObj = simpleDeepClone(transformTreeDataToObject(data))
+ const res = []
+ const walkReplace = (root, obj) => {
+ if (root.children && root.children.length > 0) {
+ root.children.forEach((childUid, index) => {
+ root.children[index] = obj[childUid]
+ walkReplace(root.children[index], obj)
+ })
+ }
+ return root
+ }
+ // 找出新增的或修改的
+ Object.keys(dataObj).forEach(uid => {
+ // 新增的或已经存在的,如果数据发生了改变
+ if (!lastDataObj[uid]) {
+ res.push({
+ action: 'create',
+ data: walkReplace(dataObj[uid], dataObj)
+ })
+ } else if (!isSameObject(lastDataObj[uid], dataObj[uid])) {
+ res.push({
+ action: 'update',
+ oldData: walkReplace(lastDataObj[uid], lastDataObj),
+ data: walkReplace(dataObj[uid], dataObj)
+ })
+ }
+ })
+ // 找出删除的
+ Object.keys(lastDataObj).forEach(uid => {
+ if (!dataObj[uid]) {
+ res.push({
+ action: 'delete',
+ data: walkReplace(lastDataObj[uid], lastDataObj)
+ })
+ }
+ })
+ this.mindMap.emit(eventName, res)
+ }
+ }
}
export default Command
diff --git a/simple-mind-map/src/core/command/KeyCommand.js b/simple-mind-map/src/core/command/KeyCommand.js
index 32ec181a..8474e84b 100644
--- a/simple-mind-map/src/core/command/KeyCommand.js
+++ b/simple-mind-map/src/core/command/KeyCommand.js
@@ -1,4 +1,5 @@
import { keyMap } from './keyMap'
+
// 快捷按键、命令处理类
export default class KeyCommand {
// 构造函数
diff --git a/simple-mind-map/src/plugins/Cooperate.js b/simple-mind-map/src/plugins/Cooperate.js
index ea3eb2f5..09258deb 100644
--- a/simple-mind-map/src/plugins/Cooperate.js
+++ b/simple-mind-map/src/plugins/Cooperate.js
@@ -1,6 +1,13 @@
import * as Y from 'yjs'
import { WebrtcProvider } from 'y-webrtc'
-import { isSameObject, simpleDeepClone, getType, isUndef } from '../utils/index'
+import {
+ isSameObject,
+ simpleDeepClone,
+ getType,
+ isUndef,
+ transformTreeDataToObject,
+ transformObjectToTreeData
+} from '../utils/index'
// 协同插件
class Cooperate {
@@ -39,7 +46,7 @@ class Cooperate {
// 创建共享数据
this.ymap = this.ydoc.getMap()
// 思维导图树结构转平级对象结构
- this.currentData = this.transformTreeDataToObject(data)
+ this.currentData = transformTreeDataToObject(data)
// 将思维导图数据添加到共享数据中
Object.keys(this.currentData).forEach(uid => {
this.ymap.set(uid, this.currentData[uid])
@@ -108,7 +115,7 @@ class Cooperate {
if (isSameObject(data, this.currentData)) return
this.currentData = data
// 平级对象转树结构
- const res = this.transformObjectToTreeData(data)
+ const res = transformObjectToTreeData(data)
if (!res) return
// 更新思维导图画布
this.mindMap.renderer.setData(res)
@@ -118,7 +125,7 @@ class Cooperate {
// 当前思维导图改变后的处理,触发同步
onDataChange(data) {
- const res = this.transformTreeDataToObject(data)
+ const res = transformTreeDataToObject(data)
this.updateChanges(res)
}
@@ -224,111 +231,6 @@ class Cooperate {
})
}
- // 将树结构转平级对象
- /*
- {
- data: {
- uid: 'xxx'
- },
- children: [
- {
- data: {
- uid: 'xxx'
- },
- children: []
- }
- ]
- }
- 转为:
- {
- uid: {
- children: [uid1, uid2],
- data: {}
- }
- }
- */
- transformTreeDataToObject(data) {
- const res = {}
- const walk = (root, parent) => {
- const uid = root.data.uid
- if (parent) {
- parent.children.push(uid)
- }
- res[uid] = {
- isRoot: !parent,
- data: {
- ...root.data
- },
- children: []
- }
- if (root.children && root.children.length > 0) {
- root.children.forEach(item => {
- walk(item, res[uid])
- })
- }
- }
- walk(data, null)
- return res
- }
-
- // 找到父节点的uid
- findParentUid(data, targetUid) {
- const uids = Object.keys(data)
- let res = ''
- uids.forEach(uid => {
- const children = data[uid].children
- const isParent =
- children.findIndex(childUid => {
- return childUid === targetUid
- }) !== -1
- if (isParent) {
- res = uid
- }
- })
- return res
- }
-
- // 将平级对象转树结构
- transformObjectToTreeData(data) {
- const uids = Object.keys(data)
- if (uids.length <= 0) return null
- const rootKey = uids.find(uid => {
- return data[uid].isRoot
- })
- if (!rootKey || !data[rootKey]) return null
- // 根节点
- const res = {
- data: simpleDeepClone(data[rootKey].data),
- children: []
- }
- const map = {}
- map[rootKey] = res
- uids.forEach(uid => {
- const parentUid = this.findParentUid(data, uid)
- const cur = data[uid]
- const node = map[uid] || {
- data: simpleDeepClone(cur.data),
- children: []
- }
- if (!map[uid]) {
- map[uid] = node
- }
- if (parentUid) {
- const index = data[parentUid].children.findIndex(item => {
- return item === uid
- })
- if (!map[parentUid]) {
- map[parentUid] = {
- data: simpleDeepClone(data[parentUid].data),
- children: []
- }
- }
- map[parentUid].children[index] = node
- }
- })
- return res
- }
-
// 插件被移除前做的事情
beforePluginRemove() {
this.unBindEvent()
diff --git a/simple-mind-map/src/utils/index.js b/simple-mind-map/src/utils/index.js
index 6fdf0230..1ff2b672 100644
--- a/simple-mind-map/src/utils/index.js
+++ b/simple-mind-map/src/utils/index.js
@@ -1074,3 +1074,108 @@ export const handleInputPasteText = (e, text) => {
selection.getRangeAt(0).insertNode(node)
selection.collapseToEnd()
}
+
+// 将思维导图树结构转平级对象
+/*
+ {
+ data: {
+ uid: 'xxx'
+ },
+ children: [
+ {
+ data: {
+ uid: 'xxx'
+ },
+ children: []
+ }
+ ]
+ }
+ 转为:
+ {
+ uid: {
+ children: [uid1, uid2],
+ data: {}
+ }
+ }
+ */
+export const transformTreeDataToObject = data => {
+ const res = {}
+ const walk = (root, parent) => {
+ const uid = root.data.uid
+ if (parent) {
+ parent.children.push(uid)
+ }
+ res[uid] = {
+ isRoot: !parent,
+ data: {
+ ...root.data
+ },
+ children: []
+ }
+ if (root.children && root.children.length > 0) {
+ root.children.forEach(item => {
+ walk(item, res[uid])
+ })
+ }
+ }
+ walk(data, null)
+ return res
+}
+
+// 将平级对象转树结构
+// transformTreeDataToObject方法的反向操作
+// 找到父节点的uid
+const _findParentUid = (data, targetUid) => {
+ const uids = Object.keys(data)
+ let res = ''
+ uids.forEach(uid => {
+ const children = data[uid].children
+ const isParent =
+ children.findIndex(childUid => {
+ return childUid === targetUid
+ }) !== -1
+ if (isParent) {
+ res = uid
+ }
+ })
+ return res
+}
+export const transformObjectToTreeData = data => {
+ const uids = Object.keys(data)
+ if (uids.length <= 0) return null
+ const rootKey = uids.find(uid => {
+ return data[uid].isRoot
+ })
+ if (!rootKey || !data[rootKey]) return null
+ // 根节点
+ const res = {
+ data: simpleDeepClone(data[rootKey].data),
+ children: []
+ }
+ const map = {}
+ map[rootKey] = res
+ uids.forEach(uid => {
+ const parentUid = _findParentUid(data, uid)
+ const cur = data[uid]
+ const node = map[uid] || {
+ data: simpleDeepClone(cur.data),
+ children: []
+ }
+ if (!map[uid]) {
+ map[uid] = node
+ }
+ if (parentUid) {
+ const index = data[parentUid].children.findIndex(item => {
+ return item === uid
+ })
+ if (!map[parentUid]) {
+ map[parentUid] = {
+ data: simpleDeepClone(data[parentUid].data),
+ children: []
+ }
+ }
+ map[parentUid].children[index] = node
+ }
+ })
+ return res
+}
From 9af630e5786b5bc83b7f997cb22884dbf2cef039 Mon Sep 17 00:00:00 2001
From: lxr-cel <756422071@qq.com>
Date: Thu, 4 Jan 2024 22:21:53 +0800
Subject: [PATCH 15/21] =?UTF-8?q?=E8=8A=82=E7=82=B9=E8=83=8C=E6=99=AF?=
=?UTF-8?q?=E6=B8=90=E5=8F=98=E8=89=B2=E5=AE=9E=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/core/render/node/Node.js | 12 +++++++--
simple-mind-map/src/core/render/node/Style.js | 25 ++++++++++++++++---
simple-mind-map/src/themes/default.js | 20 ++++++++++++---
3 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/simple-mind-map/src/core/render/node/Node.js b/simple-mind-map/src/core/render/node/Node.js
index bbbf2e57..c7f5db15 100644
--- a/simple-mind-map/src/core/render/node/Node.js
+++ b/simple-mind-map/src/core/render/node/Node.js
@@ -1,6 +1,6 @@
import Style from './Style'
import Shape from './Shape'
-import { G, ForeignObject, Rect } from '@svgdotjs/svg.js'
+import { G, ForeignObject, Rect, Defs } from '@svgdotjs/svg.js'
import nodeGeneralizationMethods from './nodeGeneralization'
import nodeExpandBtnMethods from './nodeExpandBtn'
import nodeCommandWrapsMethods from './nodeCommandWraps'
@@ -63,6 +63,8 @@ class Node {
this.userList = []
// 节点内容的容器
this.group = null
+ this.defsNode = null // 节点静态元素
+ this.gradientNode = null // 节点渐变背景
this.shapeNode = null // 节点形状节点
this.hoverNode = null // 节点hover和激活的节点
// 节点内容对象
@@ -289,11 +291,17 @@ class Node {
let { paddingY } = this.getPaddingVale()
const halfBorderWidth = this.getBorderWidth() / 2
paddingY += this.shapePadding.paddingY + halfBorderWidth
+ // 节点静态元素
+ this.defsNode = new Defs()
+ // 节点渐变背景
+ this.gradientNode = this.style.createGradient()
+ this.defsNode.add(this.gradientNode)
+ this.group.add(this.defsNode)
// 节点形状
this.shapeNode = this.shapeInstance.createShape()
this.shapeNode.addClass('smm-node-shape')
this.shapeNode.translate(halfBorderWidth, halfBorderWidth)
- this.style.shape(this.shapeNode)
+ this.style.shape(this.shapeNode, this.gradientNode.id())
this.group.add(this.shapeNode)
// 渲染一个隐藏的矩形区域,用来触发展开收起按钮的显示
this.renderExpandBtnPlaceholderRect()
diff --git a/simple-mind-map/src/core/render/node/Style.js b/simple-mind-map/src/core/render/node/Style.js
index ecc190f7..b1dbf0bc 100644
--- a/simple-mind-map/src/core/render/node/Style.js
+++ b/simple-mind-map/src/core/render/node/Style.js
@@ -2,6 +2,7 @@ import {
checkIsNodeStyleDataKey,
generateColorByContent
} from '../../../utils/index'
+import { Gradient } from '@svgdotjs/svg.js'
const rootProp = ['paddingX', 'paddingY']
const backgroundStyleProps = [
@@ -86,6 +87,14 @@ class Style {
return this.merge(prop, root)
}
+ createGradient() {
+ let gradient = new Gradient("linear")
+ gradient.id()
+ gradient.stop(0,this.merge('startColor'))
+ gradient.stop(1, this.merge('endColor'))
+ return gradient
+ }
+
// 获取自身自定义样式
getSelfStyle(prop) {
return this.ctx.getData(prop)
@@ -98,10 +107,18 @@ class Style {
}
// 矩形外的其他形状
- shape(node) {
- node.fill({
- color: this.merge('fillColor')
- })
+ shape(node, uid) {
+ if (this.merge('gradientStyle')) {
+ node.fill('url(#' + uid + ')'
+ )
+ } else {
+ node.fill({
+ color: this.merge('fillColor')
+ })
+ }
+ // node.fill({
+ // color: this.merge('fillColor')
+ // })
// 节点使用横线样式,不需要渲染非激活状态的边框样式
// if (
// !this.ctx.isRoot &&
diff --git a/simple-mind-map/src/themes/default.js b/simple-mind-map/src/themes/default.js
index 897a46d7..c4302a70 100644
--- a/simple-mind-map/src/themes/default.js
+++ b/simple-mind-map/src/themes/default.js
@@ -70,7 +70,10 @@ export default {
borderWidth: 0,
borderDasharray: 'none',
borderRadius: 5,
- textDecoration: 'none'
+ textDecoration: 'none',
+ gradientStyle: true,
+ startColor: '#549688',
+ endColor: '#fff',
},
// 二级节点样式
second: {
@@ -88,7 +91,10 @@ export default {
borderWidth: 1,
borderDasharray: 'none',
borderRadius: 5,
- textDecoration: 'none'
+ textDecoration: 'none',
+ gradientStyle: false,
+ startColor: '#549688',
+ endColor: '#fff',
},
// 三级及以下节点样式
node: {
@@ -106,7 +112,10 @@ export default {
borderWidth: 0,
borderRadius: 5,
borderDasharray: 'none',
- textDecoration: 'none'
+ textDecoration: 'none',
+ gradientStyle: false,
+ startColor: '#549688',
+ endColor: '#fff',
},
// 概要节点样式
generalization: {
@@ -124,7 +133,10 @@ export default {
borderWidth: 1,
borderDasharray: 'none',
borderRadius: 5,
- textDecoration: 'none'
+ textDecoration: 'none',
+ gradientStyle: false,
+ startColor: '#549688',
+ endColor: '#fff',
}
}
From c4713097a0dbe588436f2354359d6436460919e6 Mon Sep 17 00:00:00 2001
From: lxr-cel <756422071@qq.com>
Date: Thu, 4 Jan 2024 23:28:19 +0800
Subject: [PATCH 16/21] =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=B8=90=E5=8F=98?=
=?UTF-8?q?=E8=89=B2web=E7=A4=BA=E4=BE=8B=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/src/lang/zh_cn.js | 5 +-
web/src/pages/Edit/components/Style.vue | 76 +++++++++++++++++++++++++
2 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/web/src/lang/zh_cn.js b/web/src/lang/zh_cn.js
index 5482a1e7..1d748513 100644
--- a/web/src/lang/zh_cn.js
+++ b/web/src/lang/zh_cn.js
@@ -200,7 +200,10 @@ export default {
line: '线条',
nodePadding: '节点内边距',
horizontal: '水平',
- vertical: '垂直'
+ vertical: '垂直',
+ gradientStyle: '渐变',
+ startColor: '起始',
+ endColor: '结束'
},
theme: {
title: '主题',
diff --git a/web/src/pages/Edit/components/Style.vue b/web/src/pages/Edit/components/Style.vue
index 197728e4..3106b487 100644
--- a/web/src/pages/Edit/components/Style.vue
+++ b/web/src/pages/Edit/components/Style.vue
@@ -249,6 +249,48 @@
+
+
+
{{ $t('style.gradientStyle') }}
+
+ {{style.gradientStyle ? '渐变' : '单一'}}
+
+
+
+ {{ $t('style.startColor') }}
+
+
+
+
+
+
+ {{ $t('style.endColor') }}
+
+
+
+
+
+
{{ $t('style.shape') }}
@@ -601,6 +643,40 @@ export default {
changeFillColor(color) {
this.style.fillColor = color
this.update('fillColor')
+ },
+
+ /**
+ * @Author: lxr_cel
+ * @Date: 2024-01-02 10:28:17
+ * @Desc: 切换渐变背景
+ */
+ toggleGradientStyle() {
+ if (this.style.gradientStyle === false) {
+ this.style.gradientStyle = true
+ } else {
+ this.style.gradientStyle = false
+ }
+ this.update('gradientStyle')
+ },
+
+ /**
+ * @Author: lxr_cel
+ * @Date: 2024-01-02 11:09:27
+ * @Desc: 切换渐变开始颜色
+ */
+ changeStartColor(color) {
+ this.style.startColor = color;
+ this.update('startColor')
+ },
+
+ /**
+ * @Author: lxr_cel
+ * @Date: 2024-01-02 10:10:34
+ * @Desc: 切换渐变结束颜色
+ */
+ changeEndColor(color) {
+ this.style.endColor = color;
+ this.update('endColor')
}
}
}
From 130acff77c789b9f845027206729bee7f2e8b33e Mon Sep 17 00:00:00 2001
From: lxr-cel <756422071@qq.com>
Date: Thu, 4 Jan 2024 23:36:22 +0800
Subject: [PATCH 17/21] =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=B8=90=E5=8F=98?=
=?UTF-8?q?=E8=89=B2=E5=8A=9F=E8=83=BD=E5=AE=9E=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/themes/default.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/simple-mind-map/src/themes/default.js b/simple-mind-map/src/themes/default.js
index fb3a0ed1..4cf34510 100644
--- a/simple-mind-map/src/themes/default.js
+++ b/simple-mind-map/src/themes/default.js
@@ -73,7 +73,7 @@ export default {
borderDasharray: 'none',
borderRadius: 5,
textDecoration: 'none',
- gradientStyle: true,
+ gradientStyle: false,
startColor: '#549688',
endColor: '#fff',
},
From c62089adb9645a84d5a63b1c62b48e14fcd57126 Mon Sep 17 00:00:00 2001
From: lxr-cel <756422071@qq.com>
Date: Thu, 4 Jan 2024 23:37:27 +0800
Subject: [PATCH 18/21] =?UTF-8?q?=E8=8A=82=E7=82=B9=E6=B8=90=E5=8F=98?=
=?UTF-8?q?=E8=89=B2web=E7=A4=BA=E4=BE=8B=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
web/src/pages/Edit/components/Style.vue | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/web/src/pages/Edit/components/Style.vue b/web/src/pages/Edit/components/Style.vue
index 3106b487..483a2b40 100644
--- a/web/src/pages/Edit/components/Style.vue
+++ b/web/src/pages/Edit/components/Style.vue
@@ -485,7 +485,10 @@ export default {
borderRadius: '',
lineColor: '',
lineDasharray: '',
- lineWidth: ''
+ lineWidth: '',
+ gradientStyle: false,
+ startColor: '',
+ endColor: ''
}
}
},
@@ -560,7 +563,10 @@ export default {
'borderRadius',
'lineColor',
'lineDasharray',
- 'lineWidth'
+ 'lineWidth',
+ 'gradientStyle',
+ 'startColor',
+ 'endColor'
].forEach(item => {
this.style[item] = this.activeNodes[0].getStyle(item, false)
})
From 166f2e0a732d9db53cf00a0b5a041f2f7ae286af Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Fri, 5 Jan 2024 09:14:30 +0800
Subject: [PATCH 19/21] Doc: update
---
README.md | 4 ++++
web/src/pages/Doc/en/introduction/index.md | 4 ++++
web/src/pages/Doc/en/introduction/index.vue | 4 ++++
web/src/pages/Doc/zh/introduction/index.md | 4 ++++
web/src/pages/Doc/zh/introduction/index.vue | 4 ++++
5 files changed, 20 insertions(+)
diff --git a/README.md b/README.md
index 37eb864a..1be119ae 100644
--- a/README.md
+++ b/README.md
@@ -248,4 +248,8 @@ const mindMap = new MindMap({
欣
+
+
+ 易空小易
+
diff --git a/web/src/pages/Doc/en/introduction/index.md b/web/src/pages/Doc/en/introduction/index.md
index d62dde94..2c404434 100644
--- a/web/src/pages/Doc/en/introduction/index.md
+++ b/web/src/pages/Doc/en/introduction/index.md
@@ -273,4 +273,8 @@ Open source is not easy. If this project is helpful to you, you can invite the a
欣
+
+

+
易空小易
+
\ No newline at end of file
diff --git a/web/src/pages/Doc/en/introduction/index.vue b/web/src/pages/Doc/en/introduction/index.vue
index 73cd2453..c5111a1b 100644
--- a/web/src/pages/Doc/en/introduction/index.vue
+++ b/web/src/pages/Doc/en/introduction/index.vue
@@ -229,6 +229,10 @@ full screen, support mini map
欣
+
+

+
易空小易
+
diff --git a/web/src/pages/Doc/zh/introduction/index.md b/web/src/pages/Doc/zh/introduction/index.md
index aa65f43d..10d8a182 100644
--- a/web/src/pages/Doc/zh/introduction/index.md
+++ b/web/src/pages/Doc/zh/introduction/index.md
@@ -266,4 +266,8 @@
欣
+
+

+
易空小易
+
\ No newline at end of file
diff --git a/web/src/pages/Doc/zh/introduction/index.vue b/web/src/pages/Doc/zh/introduction/index.vue
index ad2425b1..d8a1aa5f 100644
--- a/web/src/pages/Doc/zh/introduction/index.vue
+++ b/web/src/pages/Doc/zh/introduction/index.vue
@@ -223,6 +223,10 @@
欣
+
+

+
易空小易
+
From 163ae6caaebfc792e154f1ccbb74ca42bfdc2383 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Fri, 5 Jan 2024 12:19:52 +0800
Subject: [PATCH 20/21] =?UTF-8?q?Feat=EF=BC=9A=E4=BC=98=E5=8C=96=E8=8A=82?=
=?UTF-8?q?=E7=82=B9=E6=B8=90=E5=8F=98=E8=83=8C=E6=99=AF=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/src/core/render/node/Node.js | 17 +++-----
simple-mind-map/src/core/render/node/Style.js | 43 ++++++++++++-------
.../core/render/node/nodeGeneralization.js | 1 +
simple-mind-map/src/themes/default.js | 13 +++---
web/src/lang/en_us.js | 5 ++-
web/src/pages/Edit/components/Style.vue | 38 ++++------------
6 files changed, 55 insertions(+), 62 deletions(-)
diff --git a/simple-mind-map/src/core/render/node/Node.js b/simple-mind-map/src/core/render/node/Node.js
index 7038c21c..236511d8 100644
--- a/simple-mind-map/src/core/render/node/Node.js
+++ b/simple-mind-map/src/core/render/node/Node.js
@@ -1,6 +1,6 @@
import Style from './Style'
import Shape from './Shape'
-import { G, ForeignObject, Rect, Defs } from '@svgdotjs/svg.js'
+import { G, ForeignObject, Rect } from '@svgdotjs/svg.js'
import nodeGeneralizationMethods from './nodeGeneralization'
import nodeExpandBtnMethods from './nodeExpandBtn'
import nodeCommandWrapsMethods from './nodeCommandWraps'
@@ -63,8 +63,6 @@ class Node {
this.userList = []
// 节点内容的容器
this.group = null
- this.defsNode = null // 节点静态元素
- this.gradientNode = null // 节点渐变背景
this.shapeNode = null // 节点形状节点
this.hoverNode = null // 节点hover和激活的节点
// 节点内容对象
@@ -301,17 +299,11 @@ class Node {
let { paddingY } = this.getPaddingVale()
const halfBorderWidth = this.getBorderWidth() / 2
paddingY += this.shapePadding.paddingY + halfBorderWidth
- // 节点静态元素
- this.defsNode = new Defs()
- // 节点渐变背景
- this.gradientNode = this.style.createGradient()
- this.defsNode.add(this.gradientNode)
- this.group.add(this.defsNode)
// 节点形状
this.shapeNode = this.shapeInstance.createShape()
this.shapeNode.addClass('smm-node-shape')
this.shapeNode.translate(halfBorderWidth, halfBorderWidth)
- this.style.shape(this.shapeNode, this.gradientNode.id())
+ this.style.shape(this.shapeNode)
this.group.add(this.shapeNode)
// 渲染一个隐藏的矩形区域,用来触发展开收起按钮的显示
this.renderExpandBtnPlaceholderRect()
@@ -369,7 +361,9 @@ class Node {
if (this._textData) {
this._textData.node.attr('data-offsetx', textContentOffsetX)
// 修复safari浏览器节点存在图标时文字位置不正确的问题
- ;(this._textData.nodeContent || this._textData.node).x(textContentOffsetX).y(0)
+ ;(this._textData.nodeContent || this._textData.node)
+ .x(textContentOffsetX)
+ .y(0)
textContentNested.add(this._textData.node)
textContentOffsetX += this._textData.width + textContentItemMargin
}
@@ -719,6 +713,7 @@ class Node {
if (this.parent) {
this.parent.removeLine()
}
+ this.style.onRemove()
}
// 隐藏节点
diff --git a/simple-mind-map/src/core/render/node/Style.js b/simple-mind-map/src/core/render/node/Style.js
index 2a0daf3a..af1f3a10 100644
--- a/simple-mind-map/src/core/render/node/Style.js
+++ b/simple-mind-map/src/core/render/node/Style.js
@@ -59,6 +59,8 @@ class Style {
// 箭头图标
this._markerPath = null
this._marker = null
+ // 渐变背景
+ this._gradient = null
}
// 合并样式
@@ -90,14 +92,6 @@ class Style {
return this.merge(prop, root)
}
- createGradient() {
- let gradient = new Gradient("linear")
- gradient.id()
- gradient.stop(0,this.merge('startColor'))
- gradient.stop(1, this.merge('endColor'))
- return gradient
- }
-
// 获取自身自定义样式
getSelfStyle(prop) {
return this.ctx.getData(prop)
@@ -109,19 +103,22 @@ class Style {
node.radius(this.merge('borderRadius'))
}
- // 矩形外的其他形状
- shape(node, uid) {
+ // 形状
+ shape(node) {
if (this.merge('gradientStyle')) {
- node.fill('url(#' + uid + ')'
- )
+ if (!this._gradient) {
+ this._gradient = this.ctx.nodeDraw.gradient('linear')
+ }
+ this._gradient.update(add => {
+ add.stop(0, this.merge('startColor'))
+ add.stop(1, this.merge('endColor'))
+ })
+ node.fill(this._gradient)
} else {
node.fill({
color: this.merge('fillColor')
})
}
- // node.fill({
- // color: this.merge('fillColor')
- // })
// 节点使用横线样式,不需要渲染非激活状态的边框样式
// if (
// !this.ctx.isRoot &&
@@ -290,6 +287,22 @@ class Style {
color: hoverRectColor
})
}
+
+ // 所属节点被删除时的操作
+ onRemove() {
+ if (this._marker) {
+ this._marker.remove()
+ this._marker = null
+ }
+ if (this._markerPath) {
+ this._markerPath.remove()
+ this._markerPath = null
+ }
+ if (this._gradient) {
+ this._gradient.remove()
+ this._gradient = null
+ }
+ }
}
Style.cacheStyle = null
diff --git a/simple-mind-map/src/core/render/node/nodeGeneralization.js b/simple-mind-map/src/core/render/node/nodeGeneralization.js
index eb6dbb6e..89fd2ab9 100644
--- a/simple-mind-map/src/core/render/node/nodeGeneralization.js
+++ b/simple-mind-map/src/core/render/node/nodeGeneralization.js
@@ -131,6 +131,7 @@ function updateGeneralizationData() {
function removeGeneralization() {
if (this.isGeneralization) return
this._generalizationList.forEach(item => {
+ item.generalizationNode.style.onRemove()
if (item.generalizationLine) {
item.generalizationLine.remove()
item.generalizationLine = null
diff --git a/simple-mind-map/src/themes/default.js b/simple-mind-map/src/themes/default.js
index 4cf34510..53f5f2f0 100644
--- a/simple-mind-map/src/themes/default.js
+++ b/simple-mind-map/src/themes/default.js
@@ -75,7 +75,7 @@ export default {
textDecoration: 'none',
gradientStyle: false,
startColor: '#549688',
- endColor: '#fff',
+ endColor: '#fff'
},
// 二级节点样式
second: {
@@ -96,7 +96,7 @@ export default {
textDecoration: 'none',
gradientStyle: false,
startColor: '#549688',
- endColor: '#fff',
+ endColor: '#fff'
},
// 三级及以下节点样式
node: {
@@ -117,7 +117,7 @@ export default {
textDecoration: 'none',
gradientStyle: false,
startColor: '#549688',
- endColor: '#fff',
+ endColor: '#fff'
},
// 概要节点样式
generalization: {
@@ -138,7 +138,7 @@ export default {
textDecoration: 'none',
gradientStyle: false,
startColor: '#549688',
- endColor: '#fff',
+ endColor: '#fff'
}
}
@@ -174,7 +174,10 @@ const nodeSizeIndependenceList = [
'backgroundPosition',
'backgroundSize',
'rootLineKeepSameInCurve',
- 'showLineMarker'
+ 'showLineMarker',
+ 'gradientStyle',
+ 'startColor',
+ 'endColor'
]
export const checkIsNodeSizeIndependenceConfig = config => {
let keys = Object.keys(config)
diff --git a/web/src/lang/en_us.js b/web/src/lang/en_us.js
index 31cd12de..5ae70103 100644
--- a/web/src/lang/en_us.js
+++ b/web/src/lang/en_us.js
@@ -202,7 +202,10 @@ export default {
line: 'Line',
nodePadding: 'Node padding',
horizontal: 'Horizontal',
- vertical: 'Vertical'
+ vertical: 'Vertical',
+ gradientStyle: 'Gradient',
+ startColor: 'Start',
+ endColor: 'End'
},
theme: {
title: 'Theme',
diff --git a/web/src/pages/Edit/components/Style.vue b/web/src/pages/Edit/components/Style.vue
index 483a2b40..68af7489 100644
--- a/web/src/pages/Edit/components/Style.vue
+++ b/web/src/pages/Edit/components/Style.vue
@@ -252,15 +252,10 @@
{{ $t('style.gradientStyle') }}
-
- {{style.gradientStyle ? '渐变' : '单一'}}
-
+
{{ $t('style.startColor') }}
@@ -284,10 +279,7 @@
:style="{ backgroundColor: style.endColor }"
>
-
+
@@ -535,7 +527,7 @@ export default {
this.initNodeStyle()
})
},
-
+
/**
* @Author: 王林
* @Date: 2021-05-05 09:48:52
@@ -651,27 +643,13 @@ export default {
this.update('fillColor')
},
- /**
- * @Author: lxr_cel
- * @Date: 2024-01-02 10:28:17
- * @Desc: 切换渐变背景
- */
- toggleGradientStyle() {
- if (this.style.gradientStyle === false) {
- this.style.gradientStyle = true
- } else {
- this.style.gradientStyle = false
- }
- this.update('gradientStyle')
- },
-
/**
* @Author: lxr_cel
* @Date: 2024-01-02 11:09:27
* @Desc: 切换渐变开始颜色
*/
changeStartColor(color) {
- this.style.startColor = color;
+ this.style.startColor = color
this.update('startColor')
},
@@ -681,7 +659,7 @@ export default {
* @Desc: 切换渐变结束颜色
*/
changeEndColor(color) {
- this.style.endColor = color;
+ this.style.endColor = color
this.update('endColor')
}
}
From e3cb7b0a6b23fdfbcea280dad5d2bcc266a63e11 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E8=A1=97=E8=A7=92=E5=B0=8F=E6=9E=97?= <1013335014@qq.com>
Date: Fri, 5 Jan 2024 13:50:05 +0800
Subject: [PATCH 21/21] =?UTF-8?q?Fix=EF=BC=9A=E4=BF=AE=E5=A4=8D=E5=AF=BC?=
=?UTF-8?q?=E5=87=BA=E5=9B=BE=E7=89=87=E6=97=B6=E8=8A=82=E7=82=B9=E8=BF=9E?=
=?UTF-8?q?=E7=BA=BF=E7=9A=84=E7=AE=AD=E5=A4=B4=E3=80=81=E5=85=B3=E8=81=94?=
=?UTF-8?q?=E7=BA=BF=E7=9A=84=E7=AE=AD=E5=A4=B4=E3=80=81=E6=B8=90=E5=8F=98?=
=?UTF-8?q?=E8=83=8C=E6=99=AF=E4=B8=A2=E5=A4=B1=E7=9A=84=E9=97=AE=E9=A2=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
simple-mind-map/index.js | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/simple-mind-map/index.js b/simple-mind-map/index.js
index efa52dbb..2bde23ce 100644
--- a/simple-mind-map/index.js
+++ b/simple-mind-map/index.js
@@ -438,14 +438,22 @@ class MindMap {
}
// 添加必要的样式
clone.add(SVG(``))
- // 修正关联线箭头marker的id
- const markerList = svg.find('marker')
- if (markerList && markerList.length > 0) {
- const id = markerList[0].attr('id')
- clone.find('marker').forEach(item => {
- item.attr('id', id)
- })
- }
+ // 修正defs里定义的元素的id,因为clone时defs里的元素的id会继续递增,导致和内容中引用的id对不上
+ const defs = svg.find('defs')
+ const defs2 = clone.find('defs')
+ defs.forEach((def, defIndex) => {
+ const def2 = defs2[defIndex]
+ if (!def2) return
+ const children = def.children()
+ const children2 = def2.children()
+ for (let i = 0; i < children.length; i++) {
+ const child = children[i]
+ const child2 = children2[i]
+ if (child && child2) {
+ child2.attr('id', child.attr('id'))
+ }
+ }
+ })
// 恢复原先的大小和变换信息
svg.size(origWidth, origHeight)
draw.transform(origTransform)