mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-21 18:37:43 +08:00
导出d的图片支持background-size/position/repeat属性效果
This commit is contained in:
parent
9914eef5b9
commit
74a52ea386
@ -1,6 +1,7 @@
|
||||
import { imgToDataUrl, downloadFile } from './utils'
|
||||
import JsPDF from 'jspdf'
|
||||
import { SVG } from '@svgdotjs/svg.js'
|
||||
import drawBackgroundImageToCanvas from './utils/simulateCSSBackgroundInCanvas'
|
||||
const URL = window.URL || window.webkitURL || window
|
||||
|
||||
// 导出类
|
||||
@ -85,7 +86,9 @@ class Export {
|
||||
let {
|
||||
backgroundColor = '#fff',
|
||||
backgroundImage,
|
||||
backgroundRepeat = 'repeat'
|
||||
backgroundRepeat = 'no-repeat',
|
||||
backgroundPosition = 'center center',
|
||||
backgroundSize = 'cover',
|
||||
} = this.mindMap.themeConfig
|
||||
// 背景颜色
|
||||
ctx.save()
|
||||
@ -96,19 +99,18 @@ class Export {
|
||||
// 背景图片
|
||||
if (backgroundImage && backgroundImage !== 'none') {
|
||||
ctx.save()
|
||||
let img = new Image()
|
||||
img.src = backgroundImage
|
||||
img.onload = () => {
|
||||
let pat = ctx.createPattern(img, backgroundRepeat)
|
||||
ctx.rect(0, 0, width, height)
|
||||
ctx.fillStyle = pat
|
||||
ctx.fill()
|
||||
drawBackgroundImageToCanvas(ctx, width, height, backgroundImage, {
|
||||
backgroundRepeat,
|
||||
backgroundPosition,
|
||||
backgroundSize
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
reject(err)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
ctx.restore()
|
||||
resolve()
|
||||
}
|
||||
img.onerror = e => {
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
|
||||
354
simple-mind-map/src/utils/simulateCSSBackgroundInCanvas.js
Normal file
354
simple-mind-map/src/utils/simulateCSSBackgroundInCanvas.js
Normal file
@ -0,0 +1,354 @@
|
||||
// 将以空格分隔的字符串值转换成成数字/单位/值数组
|
||||
const getNumberValueFromStr = value => {
|
||||
let arr = String(value).split(/\s+/)
|
||||
return arr.map(item => {
|
||||
if (/^[\d.]+/.test(item)) {
|
||||
// 数字+单位
|
||||
let res = /^([\d.]+)(.*)$/.exec(item)
|
||||
return [Number(res[1]), res[2]]
|
||||
} else {
|
||||
// 单个值
|
||||
return item
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 缩放宽度
|
||||
const zoomWidth = (ratio, height) => {
|
||||
// w / height = ratio
|
||||
return ratio * height
|
||||
}
|
||||
|
||||
// 缩放高度
|
||||
const zoomHeight = (ratio, width) => {
|
||||
// width / h = ratio
|
||||
return width / ratio
|
||||
}
|
||||
|
||||
// 关键词到百分比值的映射
|
||||
const keyWordToPercentageMap = {
|
||||
left: 0,
|
||||
top: 0,
|
||||
center: 50,
|
||||
bottom: 100,
|
||||
right: 100
|
||||
}
|
||||
|
||||
// 模拟background-size
|
||||
const handleBackgroundSize = ({
|
||||
backgroundSize,
|
||||
drawOpt,
|
||||
imageRatio,
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
canvasRatio
|
||||
}) => {
|
||||
if (backgroundSize) {
|
||||
// 将值转换成数组
|
||||
let backgroundSizeValueArr = getNumberValueFromStr(backgroundSize)
|
||||
// 两个值都为auto,那就相当于不设置
|
||||
if (
|
||||
backgroundSizeValueArr[0] === 'auto' &&
|
||||
backgroundSizeValueArr[1] === 'auto'
|
||||
) {
|
||||
return
|
||||
}
|
||||
// 值为cover
|
||||
if (backgroundSizeValueArr[0] === 'cover') {
|
||||
if (imageRatio > canvasRatio) {
|
||||
// 图片的宽高比大于canvas的宽高比,那么图片高度缩放到和canvas的高度一致,宽度自适应
|
||||
drawOpt.height = canvasHeight
|
||||
drawOpt.width = zoomWidth(imageRatio, canvasHeight)
|
||||
} else {
|
||||
// 否则图片宽度缩放到和canvas的宽度一致,高度自适应
|
||||
drawOpt.width = canvasWidth
|
||||
drawOpt.height = zoomHeight(imageRatio, canvasWidth)
|
||||
}
|
||||
return
|
||||
}
|
||||
// 值为contain
|
||||
if (backgroundSizeValueArr[0] === 'contain') {
|
||||
if (imageRatio > canvasRatio) {
|
||||
// 图片的宽高比大于canvas的宽高比,那么图片宽度缩放到和canvas的宽度一致,高度自适应
|
||||
drawOpt.width = canvasWidth
|
||||
drawOpt.height = zoomHeight(imageRatio, canvasWidth)
|
||||
} else {
|
||||
// 否则图片高度缩放到和canvas的高度一致,宽度自适应
|
||||
drawOpt.height = canvasHeight
|
||||
drawOpt.width = zoomWidth(imageRatio, canvasHeight)
|
||||
}
|
||||
return
|
||||
}
|
||||
// 图片宽度
|
||||
let newNumberWidth = -1
|
||||
if (backgroundSizeValueArr[0]) {
|
||||
if (Array.isArray(backgroundSizeValueArr[0])) {
|
||||
// 数字+单位类型
|
||||
if (backgroundSizeValueArr[0][1] === '%') {
|
||||
// %单位
|
||||
drawOpt.width = (backgroundSizeValueArr[0][0] / 100) * canvasWidth
|
||||
newNumberWidth = drawOpt.width
|
||||
} else {
|
||||
// 其他都认为是px单位
|
||||
drawOpt.width = backgroundSizeValueArr[0][0]
|
||||
newNumberWidth = backgroundSizeValueArr[0][0]
|
||||
}
|
||||
} else if (backgroundSizeValueArr[0] === 'auto') {
|
||||
// auto类型,那么根据设置的新高度以图片原宽高比进行自适应
|
||||
if (backgroundSizeValueArr[1]) {
|
||||
if (backgroundSizeValueArr[1][1] === '%') {
|
||||
// 高度为%单位
|
||||
drawOpt.width = zoomWidth(
|
||||
imageRatio,
|
||||
(backgroundSizeValueArr[1][0] / 100) * canvasHeight
|
||||
)
|
||||
} else {
|
||||
// 其他都认为是px单位
|
||||
drawOpt.width = zoomWidth(imageRatio, backgroundSizeValueArr[1][0])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// 设置了图片高度
|
||||
if (backgroundSizeValueArr[1] && Array.isArray(backgroundSizeValueArr[1])) {
|
||||
// 数字+单位类型
|
||||
if (backgroundSizeValueArr[1][1] === '%') {
|
||||
// 高度为%单位
|
||||
drawOpt.height = (backgroundSizeValueArr[1][0] / 100) * canvasHeight
|
||||
} else {
|
||||
// 其他都认为是px单位
|
||||
drawOpt.height = backgroundSizeValueArr[1][0]
|
||||
}
|
||||
} else if (newNumberWidth !== -1) {
|
||||
// 没有设置图片高度或者设置为auto,那么根据设置的新宽度以图片原宽高比进行自适应
|
||||
drawOpt.height = zoomHeight(imageRatio, newNumberWidth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟background-position
|
||||
const handleBackgroundPosition = ({
|
||||
backgroundPosition,
|
||||
drawOpt,
|
||||
imgWidth,
|
||||
imgHeight,
|
||||
canvasWidth,
|
||||
canvasHeight
|
||||
}) => {
|
||||
if (backgroundPosition) {
|
||||
// 将值转换成数组
|
||||
let backgroundPositionValueArr = getNumberValueFromStr(backgroundPosition)
|
||||
// 将关键词转为百分比
|
||||
backgroundPositionValueArr = backgroundPositionValueArr.map(item => {
|
||||
if (typeof item === 'string') {
|
||||
return keyWordToPercentageMap[item] !== undefined
|
||||
? [keyWordToPercentageMap[item], '%']
|
||||
: item
|
||||
}
|
||||
return item
|
||||
})
|
||||
if (Array.isArray(backgroundPositionValueArr[0])) {
|
||||
if (backgroundPositionValueArr.length === 1) {
|
||||
// 如果只设置了一个值,第二个默认为50%
|
||||
backgroundPositionValueArr.push([50, '%'])
|
||||
}
|
||||
// 水平位置
|
||||
if (backgroundPositionValueArr[0][1] === '%') {
|
||||
// 单位为%
|
||||
let canvasX = (backgroundPositionValueArr[0][0] / 100) * canvasWidth
|
||||
let imgX = (backgroundPositionValueArr[0][0] / 100) * imgWidth
|
||||
// 计算差值
|
||||
drawOpt.x = canvasX - imgX
|
||||
} else {
|
||||
// 其他单位默认都为px
|
||||
drawOpt.x = backgroundPositionValueArr[0][0]
|
||||
}
|
||||
// 垂直位置
|
||||
if (backgroundPositionValueArr[1][1] === '%') {
|
||||
// 单位为%
|
||||
let canvasY = (backgroundPositionValueArr[1][0] / 100) * canvasHeight
|
||||
let imgY = (backgroundPositionValueArr[1][0] / 100) * imgHeight
|
||||
// 计算差值
|
||||
drawOpt.y = canvasY - imgY
|
||||
} else {
|
||||
// 其他单位默认都为px
|
||||
drawOpt.y = backgroundPositionValueArr[1][0]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 模拟background-repeat
|
||||
const handleBackgroundRepeat = ({
|
||||
ctx,
|
||||
image,
|
||||
backgroundRepeat,
|
||||
drawOpt,
|
||||
imgWidth,
|
||||
imgHeight,
|
||||
canvasWidth,
|
||||
canvasHeight
|
||||
}) => {
|
||||
if (backgroundRepeat) {
|
||||
// 保存在handleBackgroundPosition中计算出来的x、y
|
||||
let ox = drawOpt.x
|
||||
let oy = drawOpt.y
|
||||
// 计算ox和oy能平铺的图片数量
|
||||
let oxRepeatNum = Math.ceil(ox / imgWidth)
|
||||
let oyRepeatNum = Math.ceil(oy / imgHeight)
|
||||
// 计算ox和oy第一张图片的位置
|
||||
let oxRepeatX = ox - oxRepeatNum * imgWidth
|
||||
let oxRepeatY = oy - oyRepeatNum * imgHeight
|
||||
// 将值转换成数组
|
||||
let backgroundRepeatValueArr = getNumberValueFromStr(backgroundRepeat)
|
||||
// 不处理
|
||||
if (
|
||||
backgroundRepeatValueArr[0] === 'no-repeat' ||
|
||||
(imgWidth >= canvasWidth && imgHeight >= canvasHeight)
|
||||
) {
|
||||
return
|
||||
}
|
||||
// 水平平铺
|
||||
if (backgroundRepeatValueArr[0] === 'repeat-x') {
|
||||
if (canvasWidth > imgWidth) {
|
||||
let x = oxRepeatX
|
||||
while (x < canvasWidth) {
|
||||
drawImage(ctx, image, {
|
||||
...drawOpt,
|
||||
x
|
||||
})
|
||||
x += imgWidth
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
// 垂直平铺
|
||||
if (backgroundRepeatValueArr[0] === 'repeat-y') {
|
||||
if (canvasHeight > imgHeight) {
|
||||
let y = oxRepeatY
|
||||
while (y < canvasHeight) {
|
||||
drawImage(ctx, image, {
|
||||
...drawOpt,
|
||||
y
|
||||
})
|
||||
y += imgHeight
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
// 平铺
|
||||
if (backgroundRepeatValueArr[0] === 'repeat') {
|
||||
let x = oxRepeatX
|
||||
while (x < canvasWidth) {
|
||||
if (canvasHeight > imgHeight) {
|
||||
let y = oxRepeatY
|
||||
while (y < canvasHeight) {
|
||||
drawImage(ctx, image, {
|
||||
...drawOpt,
|
||||
x,
|
||||
y
|
||||
})
|
||||
y += imgHeight
|
||||
}
|
||||
}
|
||||
x += imgWidth
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 根据参数绘制图片
|
||||
const drawImage = (ctx, image, drawOpt) => {
|
||||
ctx.drawImage(
|
||||
image,
|
||||
drawOpt.sx,
|
||||
drawOpt.sy,
|
||||
drawOpt.swidth,
|
||||
drawOpt.sheight,
|
||||
drawOpt.x,
|
||||
drawOpt.y,
|
||||
drawOpt.width,
|
||||
drawOpt.height
|
||||
)
|
||||
}
|
||||
|
||||
const drawBackgroundImageToCanvas = (
|
||||
ctx,
|
||||
width,
|
||||
height,
|
||||
img,
|
||||
{ backgroundSize, backgroundPosition, backgroundRepeat },
|
||||
callback = () => {}
|
||||
) => {
|
||||
// 画布的长宽比
|
||||
let canvasRatio = width / height
|
||||
// 加载图片
|
||||
let image = new Image()
|
||||
image.src = img
|
||||
image.onload = () => {
|
||||
// 图片的宽度及长宽比
|
||||
let imgWidth = image.width
|
||||
let imgHeight = image.height
|
||||
let imageRatio = imgWidth / imgHeight
|
||||
// 绘制图片
|
||||
// drawImage方法的参数值
|
||||
let drawOpt = {
|
||||
sx: 0,
|
||||
sy: 0,
|
||||
swidth: imgWidth,
|
||||
sheight: imgHeight,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: imgWidth,
|
||||
height: imgHeight
|
||||
}
|
||||
// 模拟background-size
|
||||
handleBackgroundSize({
|
||||
backgroundSize,
|
||||
drawOpt,
|
||||
imageRatio,
|
||||
canvasWidth: width,
|
||||
canvasHeight: height,
|
||||
canvasRatio
|
||||
})
|
||||
|
||||
// 模拟background-position
|
||||
handleBackgroundPosition({
|
||||
backgroundPosition,
|
||||
drawOpt,
|
||||
imgWidth: drawOpt.width,
|
||||
imgHeight: drawOpt.height,
|
||||
imageRatio,
|
||||
canvasWidth: width,
|
||||
canvasHeight: height,
|
||||
canvasRatio
|
||||
})
|
||||
|
||||
// 模拟background-repeat
|
||||
let notNeedDraw = handleBackgroundRepeat({
|
||||
ctx,
|
||||
image,
|
||||
backgroundRepeat,
|
||||
drawOpt,
|
||||
imgWidth: drawOpt.width,
|
||||
imgHeight: drawOpt.height,
|
||||
imageRatio,
|
||||
canvasWidth: width,
|
||||
canvasHeight: height,
|
||||
canvasRatio
|
||||
})
|
||||
|
||||
// 绘制图片
|
||||
if (!notNeedDraw) {
|
||||
drawImage(ctx, image, drawOpt)
|
||||
}
|
||||
|
||||
callback()
|
||||
}
|
||||
image.onerror = e => {
|
||||
callback(e)
|
||||
}
|
||||
}
|
||||
|
||||
export default drawBackgroundImageToCanvas
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
Fix: 1.The problem that deleting the background image does not take effect; 2.The problem that the connector runs above the root node when the node is dragged to the root node.
|
||||
|
||||
New: Add position and size settings for background image display.
|
||||
New: Add position and size settings for background image display. This setting is also supported for exported pictures.
|
||||
|
||||
## 0.3.0
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.3.1</h2>
|
||||
<p>Fix: 1.The problem that deleting the background image does not take effect; 2.The problem that the connector runs above the root node when the node is dragged to the root node.</p>
|
||||
<p>New: Add position and size settings for background image display.</p>
|
||||
<p>New: Add position and size settings for background image display. This setting is also supported for exported pictures.</p>
|
||||
<h2>0.3.0</h2>
|
||||
<p>Upgrade to plugin architecture, pull out some non-core functions as plugins, register as needed, and reduce the overall volume.</p>
|
||||
<h2>0.2.24</h2>
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
# Utility Methods
|
||||
|
||||
## Base utility Methods
|
||||
|
||||
Reference:
|
||||
|
||||
```js
|
||||
import {walk, ...} from 'simple-mind-map/src/utils'
|
||||
```
|
||||
|
||||
## Methods
|
||||
### Methods
|
||||
|
||||
### walk(root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0)
|
||||
#### walk(root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0)
|
||||
|
||||
Depth-first traversal of a tree
|
||||
|
||||
@ -34,11 +36,11 @@ Example:
|
||||
walk(tree, null, () => {}, () => {}, false, 0, 0);
|
||||
```
|
||||
|
||||
### bfsWalk(root, callback)
|
||||
#### bfsWalk(root, callback)
|
||||
|
||||
Breadth-first traversal of a tree
|
||||
|
||||
### resizeImgSize(width, height, maxWidth, maxHeight)
|
||||
#### resizeImgSize(width, height, maxWidth, maxHeight)
|
||||
|
||||
Resize image size
|
||||
|
||||
@ -52,17 +54,17 @@ Resize image size
|
||||
|
||||
`maxWidth` and `maxHeight` can both be passed, or only one of them can be passed
|
||||
|
||||
### resizeImg(imgUrl, maxWidth, maxHeight)
|
||||
#### resizeImg(imgUrl, maxWidth, maxHeight)
|
||||
|
||||
Resize image, internally loads the image first, then calls the `resizeImgSize`
|
||||
method, and returns a `promise`
|
||||
|
||||
### simpleDeepClone(data)
|
||||
#### simpleDeepClone(data)
|
||||
|
||||
Extremely simple deep copy method, can only be used for objects that are all
|
||||
basic data, otherwise it will throw an error
|
||||
|
||||
### copyRenderTree(tree, root)
|
||||
#### copyRenderTree(tree, root)
|
||||
|
||||
Copy render tree data, example:
|
||||
|
||||
@ -70,7 +72,7 @@ Copy render tree data, example:
|
||||
copyRenderTree({}, this.mindMap.renderer.renderTree);
|
||||
```
|
||||
|
||||
### copyNodeTree(tree, root)
|
||||
#### copyNodeTree(tree, root)
|
||||
|
||||
Copy node tree data, mainly eliminating the reference `node` instance `_node`
|
||||
and copying the `data` of the data object, example:
|
||||
@ -79,30 +81,60 @@ and copying the `data` of the data object, example:
|
||||
copyNodeTree({}, node);
|
||||
```
|
||||
|
||||
### imgToDataUrl(src)
|
||||
#### imgToDataUrl(src)
|
||||
|
||||
Convert image to dataURL
|
||||
|
||||
### downloadFile(file, fileName)
|
||||
#### downloadFile(file, fileName)
|
||||
|
||||
Download file
|
||||
|
||||
### throttle(fn, time = 300, ctx)
|
||||
#### throttle(fn, time = 300, ctx)
|
||||
|
||||
Throttle function
|
||||
|
||||
### asyncRun(taskList, callback = () => {})
|
||||
#### asyncRun(taskList, callback = () => {})
|
||||
|
||||
Run tasks in task list asynchronously, tasks are run synchronously without order
|
||||
|
||||
### degToRad(deg)
|
||||
#### degToRad(deg)
|
||||
|
||||
> v0.2.24+
|
||||
|
||||
Angle to radian
|
||||
|
||||
### camelCaseToHyphen(str)
|
||||
#### camelCaseToHyphen(str)
|
||||
|
||||
> v0.2.24+
|
||||
|
||||
CamelCase to hyphen
|
||||
CamelCase to hyphen
|
||||
|
||||
## Simulate CSS background in Canvas
|
||||
|
||||
Import:
|
||||
|
||||
```js
|
||||
import drawBackgroundImageToCanvas from 'simple-mind-map/src/utils/simulateCSSBackgroundInCanvas'
|
||||
```
|
||||
|
||||
Usage:
|
||||
|
||||
```js
|
||||
let width = 500
|
||||
let height = 500
|
||||
let img = '/1.jpg'
|
||||
let canvas = document.createElement('canvas')
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
drawBackgroundImageToCanvas(ctx, width, height, img, {
|
||||
backgroundRepeat: 'repeat-y',
|
||||
backgroundSize: '60%',
|
||||
backgroundPosition: 'center center'
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
// fail
|
||||
} else {
|
||||
// success
|
||||
}
|
||||
})
|
||||
```
|
||||
@ -1,11 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>Utility Methods</h1>
|
||||
<h2>Base utility Methods</h2>
|
||||
<p>Reference:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> {walk, ...} <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/utils'</span>
|
||||
</code></pre>
|
||||
<h2>Methods</h2>
|
||||
<h3>walk(root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0)</h3>
|
||||
<h3>Methods</h3>
|
||||
<h4>walk(root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0)</h4>
|
||||
<p>Depth-first traversal of a tree</p>
|
||||
<p><code>root</code>: the root node of the tree to be traversed</p>
|
||||
<p><code>parent</code>: parent node</p>
|
||||
@ -19,48 +20,71 @@ root, parent, isRoot, layerIndex, index</p>
|
||||
<p>Example:</p>
|
||||
<pre class="hljs"><code>walk(tree, <span class="hljs-literal">null</span>, <span class="hljs-function">() =></span> {}, <span class="hljs-function">() =></span> {}, <span class="hljs-literal">false</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>);
|
||||
</code></pre>
|
||||
<h3>bfsWalk(root, callback)</h3>
|
||||
<h4>bfsWalk(root, callback)</h4>
|
||||
<p>Breadth-first traversal of a tree</p>
|
||||
<h3>resizeImgSize(width, height, maxWidth, maxHeight)</h3>
|
||||
<h4>resizeImgSize(width, height, maxWidth, maxHeight)</h4>
|
||||
<p>Resize image size</p>
|
||||
<p><code>width</code>: original width of the image</p>
|
||||
<p><code>height</code>: original height of the image</p>
|
||||
<p><code>maxWidth</code>: the width to resize to</p>
|
||||
<p><code>maxHeight</code>: the height to resize to</p>
|
||||
<p><code>maxWidth</code> and <code>maxHeight</code> can both be passed, or only one of them can be passed</p>
|
||||
<h3>resizeImg(imgUrl, maxWidth, maxHeight)</h3>
|
||||
<h4>resizeImg(imgUrl, maxWidth, maxHeight)</h4>
|
||||
<p>Resize image, internally loads the image first, then calls the <code>resizeImgSize</code>
|
||||
method, and returns a <code>promise</code></p>
|
||||
<h3>simpleDeepClone(data)</h3>
|
||||
<h4>simpleDeepClone(data)</h4>
|
||||
<p>Extremely simple deep copy method, can only be used for objects that are all
|
||||
basic data, otherwise it will throw an error</p>
|
||||
<h3>copyRenderTree(tree, root)</h3>
|
||||
<h4>copyRenderTree(tree, root)</h4>
|
||||
<p>Copy render tree data, example:</p>
|
||||
<pre class="hljs"><code>copyRenderTree({}, <span class="hljs-built_in">this</span>.mindMap.renderer.renderTree);
|
||||
</code></pre>
|
||||
<h3>copyNodeTree(tree, root)</h3>
|
||||
<h4>copyNodeTree(tree, root)</h4>
|
||||
<p>Copy node tree data, mainly eliminating the reference <code>node</code> instance <code>_node</code>
|
||||
and copying the <code>data</code> of the data object, example:</p>
|
||||
<pre class="hljs"><code>copyNodeTree({}, node);
|
||||
</code></pre>
|
||||
<h3>imgToDataUrl(src)</h3>
|
||||
<h4>imgToDataUrl(src)</h4>
|
||||
<p>Convert image to dataURL</p>
|
||||
<h3>downloadFile(file, fileName)</h3>
|
||||
<h4>downloadFile(file, fileName)</h4>
|
||||
<p>Download file</p>
|
||||
<h3>throttle(fn, time = 300, ctx)</h3>
|
||||
<h4>throttle(fn, time = 300, ctx)</h4>
|
||||
<p>Throttle function</p>
|
||||
<h3>asyncRun(taskList, callback = () => {})</h3>
|
||||
<h4>asyncRun(taskList, callback = () => {})</h4>
|
||||
<p>Run tasks in task list asynchronously, tasks are run synchronously without order</p>
|
||||
<h3>degToRad(deg)</h3>
|
||||
<h4>degToRad(deg)</h4>
|
||||
<blockquote>
|
||||
<p>v0.2.24+</p>
|
||||
</blockquote>
|
||||
<p>Angle to radian</p>
|
||||
<h3>camelCaseToHyphen(str)</h3>
|
||||
<h4>camelCaseToHyphen(str)</h4>
|
||||
<blockquote>
|
||||
<p>v0.2.24+</p>
|
||||
</blockquote>
|
||||
<p>CamelCase to hyphen</p>
|
||||
<h2>Simulate CSS background in Canvas</h2>
|
||||
<p>Import:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> drawBackgroundImageToCanvas <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/utils/simulateCSSBackgroundInCanvas'</span>
|
||||
</code></pre>
|
||||
<p>Usage:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">let</span> width = <span class="hljs-number">500</span>
|
||||
<span class="hljs-keyword">let</span> height = <span class="hljs-number">500</span>
|
||||
<span class="hljs-keyword">let</span> img = <span class="hljs-string">'/1.jpg'</span>
|
||||
<span class="hljs-keyword">let</span> canvas = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'canvas'</span>)
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
drawBackgroundImageToCanvas(ctx, width, height, img, {
|
||||
<span class="hljs-attr">backgroundRepeat</span>: <span class="hljs-string">'repeat-y'</span>,
|
||||
<span class="hljs-attr">backgroundSize</span>: <span class="hljs-string">'60%'</span>,
|
||||
<span class="hljs-attr">backgroundPosition</span>: <span class="hljs-string">'center center'</span>
|
||||
}, <span class="hljs-function">(<span class="hljs-params">err</span>) =></span> {
|
||||
<span class="hljs-keyword">if</span> (err) {
|
||||
<span class="hljs-comment">// fail</span>
|
||||
} <span class="hljs-keyword">else</span> {
|
||||
<span class="hljs-comment">// success</span>
|
||||
}
|
||||
})
|
||||
</code></pre>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
|
||||
修复:1.删除背景图片不生效的问题;2.节点拖拽到根节点时连接线跑到根节点上方的问题。
|
||||
|
||||
新增:背景图片展示增加位置和大小设置。
|
||||
新增:背景图片展示增加位置和大小设置。导出的图片也同步支持该设置。
|
||||
|
||||
## 0.3.0
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<h1>Changelog</h1>
|
||||
<h2>0.3.1</h2>
|
||||
<p>修复:1.删除背景图片不生效的问题;2.节点拖拽到根节点时连接线跑到根节点上方的问题。</p>
|
||||
<p>新增:背景图片展示增加位置和大小设置。</p>
|
||||
<p>新增:背景图片展示增加位置和大小设置。导出的图片也同步支持该设置。</p>
|
||||
<h2>0.3.0</h2>
|
||||
<p>升级为插件化架构,将一些非核心功能抽离出来作为插件,按需注册,减小整体体积。</p>
|
||||
<h2>0.2.24</h2>
|
||||
|
||||
@ -1,14 +1,16 @@
|
||||
# 内置工具方法
|
||||
|
||||
## 基础工具方法
|
||||
|
||||
引用:
|
||||
|
||||
```js
|
||||
import {walk, ...} from 'simple-mind-map/src/utils'
|
||||
```
|
||||
|
||||
## 方法
|
||||
### 方法
|
||||
|
||||
### walk(root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0)
|
||||
#### walk(root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0)
|
||||
|
||||
深度优先遍历树
|
||||
|
||||
@ -32,11 +34,11 @@ import {walk, ...} from 'simple-mind-map/src/utils'
|
||||
walk(tree, null, () => {}, () => {}, false, 0, 0)
|
||||
```
|
||||
|
||||
### bfsWalk(root, callback)
|
||||
#### bfsWalk(root, callback)
|
||||
|
||||
广度优先遍历树
|
||||
|
||||
### resizeImgSize(width, height, maxWidth, maxHeight)
|
||||
#### resizeImgSize(width, height, maxWidth, maxHeight)
|
||||
|
||||
缩放图片的尺寸
|
||||
|
||||
@ -50,15 +52,15 @@ walk(tree, null, () => {}, () => {}, false, 0, 0)
|
||||
|
||||
`maxWidth`和`maxHeight`可以同时都传,也可以只传一个
|
||||
|
||||
### resizeImg(imgUrl, maxWidth, maxHeight)
|
||||
#### resizeImg(imgUrl, maxWidth, maxHeight)
|
||||
|
||||
缩放图片,内部先加载图片,然后调用`resizeImgSize`方法,返回一个`promise`
|
||||
|
||||
### simpleDeepClone(data)
|
||||
#### simpleDeepClone(data)
|
||||
|
||||
极简的深拷贝方法,只能针对全是基本数据的对象,否则会报错
|
||||
|
||||
### copyRenderTree(tree, root)
|
||||
#### copyRenderTree(tree, root)
|
||||
|
||||
复制渲染树数据,示例:
|
||||
|
||||
@ -66,7 +68,7 @@ walk(tree, null, () => {}, () => {}, false, 0, 0)
|
||||
copyRenderTree({}, this.mindMap.renderer.renderTree)
|
||||
```
|
||||
|
||||
### copyNodeTree(tree, root)
|
||||
#### copyNodeTree(tree, root)
|
||||
|
||||
复制节点树数据,主要是剔除其中的引用`node`实例的`_node`,然后复制`data`对象的数据,示例:
|
||||
|
||||
@ -74,30 +76,60 @@ copyRenderTree({}, this.mindMap.renderer.renderTree)
|
||||
copyNodeTree({}, node)
|
||||
```
|
||||
|
||||
### imgToDataUrl(src)
|
||||
#### imgToDataUrl(src)
|
||||
|
||||
图片转成dataURL
|
||||
|
||||
### downloadFile(file, fileName)
|
||||
#### downloadFile(file, fileName)
|
||||
|
||||
下载文件
|
||||
|
||||
### throttle(fn, time = 300, ctx)
|
||||
#### throttle(fn, time = 300, ctx)
|
||||
|
||||
节流函数
|
||||
|
||||
### asyncRun(taskList, callback = () => {})
|
||||
#### asyncRun(taskList, callback = () => {})
|
||||
|
||||
异步执行任务队列,多个任务是同步执行的,没有先后顺序
|
||||
|
||||
### degToRad(deg)
|
||||
#### degToRad(deg)
|
||||
|
||||
> v0.2.24+
|
||||
|
||||
角度转弧度
|
||||
|
||||
### camelCaseToHyphen(str)
|
||||
#### camelCaseToHyphen(str)
|
||||
|
||||
> v0.2.24+
|
||||
|
||||
驼峰转连字符
|
||||
驼峰转连字符
|
||||
|
||||
## 在canvas中模拟css的背景属性
|
||||
|
||||
引入:
|
||||
|
||||
```js
|
||||
import drawBackgroundImageToCanvas from 'simple-mind-map/src/utils/simulateCSSBackgroundInCanvas'
|
||||
```
|
||||
|
||||
使用:
|
||||
|
||||
```js
|
||||
let width = 500
|
||||
let height = 500
|
||||
let img = '/1.jpg'
|
||||
let canvas = document.createElement('canvas')
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
drawBackgroundImageToCanvas(ctx, width, height, img, {
|
||||
backgroundRepeat: 'repeat-y',
|
||||
backgroundSize: '60%',
|
||||
backgroundPosition: 'center center'
|
||||
}, (err) => {
|
||||
if (err) {
|
||||
// 失败
|
||||
} else {
|
||||
// 成功
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
<h1>内置工具方法</h1>
|
||||
<h2>基础工具方法</h2>
|
||||
<p>引用:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> {walk, ...} <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/utils'</span>
|
||||
</code></pre>
|
||||
<h2>方法</h2>
|
||||
<h3>walk(root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0)</h3>
|
||||
<h3>方法</h3>
|
||||
<h4>walk(root, parent, beforeCallback, afterCallback, isRoot, layerIndex = 0, index = 0)</h4>
|
||||
<p>深度优先遍历树</p>
|
||||
<p><code>root</code>:要遍历的树的根节点</p>
|
||||
<p><code>parent</code>:父节点</p>
|
||||
@ -17,45 +18,68 @@
|
||||
<p>示例:</p>
|
||||
<pre class="hljs"><code>walk(tree, <span class="hljs-literal">null</span>, <span class="hljs-function">() =></span> {}, <span class="hljs-function">() =></span> {}, <span class="hljs-literal">false</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>)
|
||||
</code></pre>
|
||||
<h3>bfsWalk(root, callback)</h3>
|
||||
<h4>bfsWalk(root, callback)</h4>
|
||||
<p>广度优先遍历树</p>
|
||||
<h3>resizeImgSize(width, height, maxWidth, maxHeight)</h3>
|
||||
<h4>resizeImgSize(width, height, maxWidth, maxHeight)</h4>
|
||||
<p>缩放图片的尺寸</p>
|
||||
<p><code>width</code>:图片原本的宽</p>
|
||||
<p><code>height</code>:图片原本的高</p>
|
||||
<p><code>maxWidth</code>:要缩放到的宽</p>
|
||||
<p><code>maxHeight</code>:要缩放到的高</p>
|
||||
<p><code>maxWidth</code>和<code>maxHeight</code>可以同时都传,也可以只传一个</p>
|
||||
<h3>resizeImg(imgUrl, maxWidth, maxHeight)</h3>
|
||||
<h4>resizeImg(imgUrl, maxWidth, maxHeight)</h4>
|
||||
<p>缩放图片,内部先加载图片,然后调用<code>resizeImgSize</code>方法,返回一个<code>promise</code></p>
|
||||
<h3>simpleDeepClone(data)</h3>
|
||||
<h4>simpleDeepClone(data)</h4>
|
||||
<p>极简的深拷贝方法,只能针对全是基本数据的对象,否则会报错</p>
|
||||
<h3>copyRenderTree(tree, root)</h3>
|
||||
<h4>copyRenderTree(tree, root)</h4>
|
||||
<p>复制渲染树数据,示例:</p>
|
||||
<pre class="hljs"><code>copyRenderTree({}, <span class="hljs-built_in">this</span>.mindMap.renderer.renderTree)
|
||||
</code></pre>
|
||||
<h3>copyNodeTree(tree, root)</h3>
|
||||
<h4>copyNodeTree(tree, root)</h4>
|
||||
<p>复制节点树数据,主要是剔除其中的引用<code>node</code>实例的<code>_node</code>,然后复制<code>data</code>对象的数据,示例:</p>
|
||||
<pre class="hljs"><code>copyNodeTree({}, node)
|
||||
</code></pre>
|
||||
<h3>imgToDataUrl(src)</h3>
|
||||
<h4>imgToDataUrl(src)</h4>
|
||||
<p>图片转成dataURL</p>
|
||||
<h3>downloadFile(file, fileName)</h3>
|
||||
<h4>downloadFile(file, fileName)</h4>
|
||||
<p>下载文件</p>
|
||||
<h3>throttle(fn, time = 300, ctx)</h3>
|
||||
<h4>throttle(fn, time = 300, ctx)</h4>
|
||||
<p>节流函数</p>
|
||||
<h3>asyncRun(taskList, callback = () => {})</h3>
|
||||
<h4>asyncRun(taskList, callback = () => {})</h4>
|
||||
<p>异步执行任务队列,多个任务是同步执行的,没有先后顺序</p>
|
||||
<h3>degToRad(deg)</h3>
|
||||
<h4>degToRad(deg)</h4>
|
||||
<blockquote>
|
||||
<p>v0.2.24+</p>
|
||||
</blockquote>
|
||||
<p>角度转弧度</p>
|
||||
<h3>camelCaseToHyphen(str)</h3>
|
||||
<h4>camelCaseToHyphen(str)</h4>
|
||||
<blockquote>
|
||||
<p>v0.2.24+</p>
|
||||
</blockquote>
|
||||
<p>驼峰转连字符</p>
|
||||
<h2>在canvas中模拟css的背景属性</h2>
|
||||
<p>引入:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">import</span> drawBackgroundImageToCanvas <span class="hljs-keyword">from</span> <span class="hljs-string">'simple-mind-map/src/utils/simulateCSSBackgroundInCanvas'</span>
|
||||
</code></pre>
|
||||
<p>使用:</p>
|
||||
<pre class="hljs"><code><span class="hljs-keyword">let</span> width = <span class="hljs-number">500</span>
|
||||
<span class="hljs-keyword">let</span> height = <span class="hljs-number">500</span>
|
||||
<span class="hljs-keyword">let</span> img = <span class="hljs-string">'/1.jpg'</span>
|
||||
<span class="hljs-keyword">let</span> canvas = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">'canvas'</span>)
|
||||
canvas.width = width
|
||||
canvas.height = height
|
||||
drawBackgroundImageToCanvas(ctx, width, height, img, {
|
||||
<span class="hljs-attr">backgroundRepeat</span>: <span class="hljs-string">'repeat-y'</span>,
|
||||
<span class="hljs-attr">backgroundSize</span>: <span class="hljs-string">'60%'</span>,
|
||||
<span class="hljs-attr">backgroundPosition</span>: <span class="hljs-string">'center center'</span>
|
||||
}, <span class="hljs-function">(<span class="hljs-params">err</span>) =></span> {
|
||||
<span class="hljs-keyword">if</span> (err) {
|
||||
<span class="hljs-comment">// 失败</span>
|
||||
} <span class="hljs-keyword">else</span> {
|
||||
<span class="hljs-comment">// 成功</span>
|
||||
}
|
||||
})
|
||||
</code></pre>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user