mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-21 10:27:44 +08:00
Demo:右键菜单新增复制到剪贴板功能
This commit is contained in:
parent
1fc5b951a0
commit
b7722987b1
@ -207,7 +207,7 @@ export const copyNodeTree = (
|
||||
}
|
||||
|
||||
// 图片转成dataURL
|
||||
export const imgToDataUrl = src => {
|
||||
export const imgToDataUrl = (src, returnBlob = false) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image()
|
||||
// 跨域图片需要添加这个属性,否则画布被污染了无法导出图片
|
||||
@ -220,7 +220,13 @@ export const imgToDataUrl = src => {
|
||||
let ctx = canvas.getContext('2d')
|
||||
// 图片绘制到canvas里
|
||||
ctx.drawImage(img, 0, 0, img.width, img.height)
|
||||
resolve(canvas.toDataURL())
|
||||
if (returnBlob) {
|
||||
canvas.toBlob(blob => {
|
||||
resolve(blob)
|
||||
})
|
||||
} else {
|
||||
resolve(canvas.toDataURL())
|
||||
}
|
||||
} catch (e) {
|
||||
reject(e)
|
||||
}
|
||||
|
||||
@ -100,7 +100,15 @@ export default {
|
||||
removeNote: 'Remove note',
|
||||
removeCustomStyles: 'Remove custom styles',
|
||||
removeAllNodeCustomStyles: 'Remove all node custom styles',
|
||||
exportNodeToPng: 'Export node to png'
|
||||
exportNodeToPng: 'Export node to png',
|
||||
copyToClipboard: 'Copy to clipboard',
|
||||
copyToSmm: 'SMM',
|
||||
copyToJson: 'JSON',
|
||||
copyToMarkdown: 'Markdown',
|
||||
copyToTxt: 'Txt',
|
||||
copyToPng: 'Png',
|
||||
copySuccess: 'Copy success',
|
||||
copyFail: 'Copy fail'
|
||||
},
|
||||
count: {
|
||||
words: 'Words',
|
||||
|
||||
@ -100,7 +100,15 @@ export default {
|
||||
removeNote: '移除备注',
|
||||
removeCustomStyles: '一键去除自定义样式',
|
||||
removeAllNodeCustomStyles: '一键去除所有节点自定义样式',
|
||||
exportNodeToPng: '导出该节点为图片'
|
||||
exportNodeToPng: '导出该节点为图片',
|
||||
copyToClipboard: '复制到剪贴板',
|
||||
copyToSmm: 'SMM',
|
||||
copyToJson: 'JSON',
|
||||
copyToMarkdown: 'Markdown',
|
||||
copyToTxt: 'Txt',
|
||||
copyToPng: '图片',
|
||||
copySuccess: '复制成功',
|
||||
copyFail: '复制失败'
|
||||
},
|
||||
count: {
|
||||
words: '字数',
|
||||
|
||||
@ -109,6 +109,7 @@
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="name">{{ $t('contextmenu.expandTo') }}</span>
|
||||
<span class="el-icon-arrow-right"></span>
|
||||
<div class="subItems listBox" :class="{ isDark: isDark }">
|
||||
<div
|
||||
class="item"
|
||||
@ -137,13 +138,30 @@
|
||||
$t('contextmenu.removeAllNodeCustomStyles')
|
||||
}}</span>
|
||||
</div>
|
||||
<div class="item">
|
||||
<span class="name">{{ $t('contextmenu.copyToClipboard') }}</span>
|
||||
<span class="el-icon-arrow-right"></span>
|
||||
<div class="subItems listBox" :class="{ isDark: isDark }">
|
||||
<div
|
||||
class="item"
|
||||
v-for="item in copyList"
|
||||
:key="item.value"
|
||||
@click="copyToClipboard(item.value)"
|
||||
>
|
||||
{{ item.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapMutations } from 'vuex'
|
||||
import { getTextFromHtml } from 'simple-mind-map/src/utils'
|
||||
import { getTextFromHtml, imgToDataUrl } from 'simple-mind-map/src/utils'
|
||||
import { transformToMarkdown } from 'simple-mind-map/src/parse/toMarkdown'
|
||||
import { transformToTxt } from 'simple-mind-map/src/parse/toTxt'
|
||||
import { setDataToClipboard, setImgToClipboard, copy } from '@/utils'
|
||||
|
||||
/**
|
||||
* @Author: 王林
|
||||
@ -166,7 +184,8 @@ export default {
|
||||
type: '',
|
||||
isMousedown: false,
|
||||
mosuedownX: 0,
|
||||
mosuedownY: 0
|
||||
mosuedownY: 0,
|
||||
enableCopyToClipboardApi: navigator.clipboard
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -184,6 +203,33 @@ export default {
|
||||
this.$t('contextmenu.level6')
|
||||
]
|
||||
},
|
||||
copyList() {
|
||||
const list = [
|
||||
{
|
||||
name: this.$t('contextmenu.copyToSmm'),
|
||||
value: 'smm'
|
||||
},
|
||||
{
|
||||
name: this.$t('contextmenu.copyToJson'),
|
||||
value: 'json'
|
||||
},
|
||||
{
|
||||
name: this.$t('contextmenu.copyToMarkdown'),
|
||||
value: 'md'
|
||||
},
|
||||
{
|
||||
name: this.$t('contextmenu.copyToTxt'),
|
||||
value: 'txt'
|
||||
}
|
||||
]
|
||||
if (this.enableCopyToClipboardApi) {
|
||||
list.push({
|
||||
name: this.$t('contextmenu.copyToPng'),
|
||||
value: 'png'
|
||||
})
|
||||
}
|
||||
return list
|
||||
},
|
||||
insertNodeBtnDisabled() {
|
||||
return !this.node || this.node.isRoot || this.node.isGeneralization
|
||||
},
|
||||
@ -355,6 +401,48 @@ export default {
|
||||
break
|
||||
}
|
||||
this.hide()
|
||||
},
|
||||
|
||||
// 复制到剪贴板
|
||||
async copyToClipboard(type) {
|
||||
try {
|
||||
this.hide()
|
||||
let data
|
||||
let str
|
||||
switch (type) {
|
||||
case 'smm':
|
||||
case 'json':
|
||||
data = this.mindMap.getData(true)
|
||||
str = JSON.stringify(data)
|
||||
break
|
||||
case 'md':
|
||||
data = this.mindMap.getData()
|
||||
str = transformToMarkdown(data)
|
||||
break
|
||||
case 'txt':
|
||||
data = this.mindMap.getData()
|
||||
str = transformToTxt(data)
|
||||
break
|
||||
case 'png':
|
||||
const png = await this.mindMap.export('png', false)
|
||||
const blob = await imgToDataUrl(png, true)
|
||||
setImgToClipboard(blob)
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
if (str) {
|
||||
if (this.enableCopyToClipboardApi) {
|
||||
setDataToClipboard(str)
|
||||
} else {
|
||||
copy(str)
|
||||
}
|
||||
}
|
||||
this.$message.success(this.$t('contextmenu.copySuccess'))
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
this.$message.error(this.$t('contextmenu.copyFail'))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -393,11 +481,11 @@ export default {
|
||||
.item {
|
||||
position: relative;
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
padding: 0 16px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
&.danger {
|
||||
color: #f56c6c;
|
||||
@ -439,6 +527,7 @@ export default {
|
||||
left: 100%;
|
||||
top: 0;
|
||||
visibility: hidden;
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -49,11 +49,28 @@ export const fileToBuffer = file => {
|
||||
}
|
||||
|
||||
// 复制文本到剪贴板
|
||||
export const copy = (text) => {
|
||||
const input = document.createElement('input')
|
||||
input.setAttribute('value', text)
|
||||
export const copy = text => {
|
||||
// 使用textarea可以保留换行
|
||||
const input = document.createElement('textarea')
|
||||
// input.setAttribute('value', text)
|
||||
input.innerHTML = text
|
||||
document.body.appendChild(input)
|
||||
input.select()
|
||||
document.execCommand('copy')
|
||||
document.body.removeChild(input)
|
||||
}
|
||||
|
||||
// 复制文本到剪贴板
|
||||
export const setDataToClipboard = data => {
|
||||
if (navigator.clipboard) {
|
||||
navigator.clipboard.writeText(data)
|
||||
}
|
||||
}
|
||||
|
||||
// 复制图片到剪贴板
|
||||
export const setImgToClipboard = img => {
|
||||
if (navigator.clipboard) {
|
||||
const data = [new ClipboardItem({ ['image/png']: img })]
|
||||
navigator.clipboard.write(data)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user