Skip to content

Commit 485e3fa

Browse files
YunaiVgitee-org
authored andcommitted
!489 [代码优化]AI: 思维导图代码优化
Merge pull request !489 from hhhero/dev
2 parents ed36d2b + 8d4c9e9 commit 485e3fa

File tree

4 files changed

+46
-42
lines changed

4 files changed

+46
-42
lines changed

src/utils/download.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,31 @@ const download = {
3434
download0(data, fileName, 'text/markdown')
3535
},
3636
// 下载图片(允许跨域)
37-
image: (url: string) => {
37+
image: ({
38+
url,
39+
canvasWidth,
40+
canvasHeight,
41+
drawWithImageSize = true
42+
}: {
43+
url: string
44+
canvasWidth?: number // 指定画布宽度
45+
canvasHeight?: number // 指定画布高度
46+
drawWithImageSize?: boolean // 将图片绘制在画布上时带上图片的宽高值, 默认是要带上的
47+
}) => {
3848
const image = new Image()
39-
image.setAttribute('crossOrigin', 'anonymous')
49+
// image.setAttribute('crossOrigin', 'anonymous')
4050
image.src = url
4151
image.onload = () => {
4252
const canvas = document.createElement('canvas')
43-
canvas.width = image.width
44-
canvas.height = image.height
45-
const ctx = canvas.getContext('2d') as CanvasDrawImage
46-
ctx.drawImage(image, 0, 0, image.width, image.height)
53+
canvas.width = canvasWidth || image.width
54+
canvas.height = canvasHeight || image.height
55+
const ctx = canvas.getContext('2d') as CanvasRenderingContext2D
56+
ctx?.clearRect(0, 0, canvas.width, canvas.height)
57+
if (drawWithImageSize) {
58+
ctx.drawImage(image, 0, 0, image.width, image.height)
59+
} else {
60+
ctx.drawImage(image, 0, 0)
61+
}
4762
const url = canvas.toDataURL('image/png')
4863
const a = document.createElement('a')
4964
a.href = url

src/views/ai/image/index/components/ImageList.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ const handleImageButtonClick = async (type: string, imageDetail: ImageVO) => {
150150
}
151151
// 下载
152152
if (type === 'download') {
153-
await download.image(imageDetail.picUrl)
153+
await download.image({ url: imageDetail.picUrl })
154154
return
155155
}
156156
// 重新生成

src/views/ai/mindmap/index/components/Right.vue

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<div class="flex flex-col items-center justify-center" v-html="html"></div>
2020
</div>
2121

22-
<div ref="mindmapRef" class="wh-full">
22+
<div ref="mindMapRef" class="wh-full">
2323
<svg ref="svgRef" class="w-full" :style="{ height: `${contentAreaHeight}px` }" />
2424
<div ref="toolBarRef" class="absolute bottom-[10px] right-5"></div>
2525
</div>
@@ -32,20 +32,20 @@ import { Markmap } from 'markmap-view'
3232
import { Transformer } from 'markmap-lib'
3333
import { Toolbar } from 'markmap-toolbar'
3434
import markdownit from 'markdown-it'
35+
import download from '@/utils/download'
3536
3637
const md = markdownit()
3738
const message = useMessage() // 消息弹窗
3839
39-
// TODO @hhero:mindmap 改成 mindMap 更精准哈
4040
const props = defineProps<{
41-
mindmapResult: string // 生成结果 TODO @hhero 改成 generatedContent 会不会好点
41+
generatedContent: string // 生成结果
4242
isEnd: boolean // 是否结束
4343
isGenerating: boolean // 是否正在生成
4444
isStart: boolean // 开始状态,开始时需要清除 html
4545
}>()
4646
const contentRef = ref<HTMLDivElement>() // 右侧出来header以下的区域
4747
const mdContainerRef = ref<HTMLDivElement>() // markdown 的容器,用来滚动到底下的
48-
const mindmapRef = ref<HTMLDivElement>() // 思维导图的容器
48+
const mindMapRef = ref<HTMLDivElement>() // 思维导图的容器
4949
const svgRef = ref<SVGElement>() // 思维导图的渲染 svg
5050
const toolBarRef = ref<HTMLDivElement>() // 思维导图右下角的工具栏,缩放等
5151
const html = ref('') // 生成过程中的文本
@@ -66,15 +66,16 @@ onMounted(() => {
6666
}
6767
})
6868
69-
watch(props, ({ mindmapResult, isGenerating, isEnd, isStart }) => {
69+
watch(props, ({ generatedContent, isGenerating, isEnd, isStart }) => {
7070
// 开始生成的时候清空一下 markdown 的内容
7171
if (isStart) {
7272
html.value = ''
7373
}
7474
// 生成内容的时候使用 markdown 来渲染
7575
if (isGenerating) {
76-
html.value = md.render(mindmapResult)
76+
html.value = md.render(generatedContent)
7777
}
78+
// 生成结束时更新思维导图
7879
if (isEnd) {
7980
update()
8081
}
@@ -83,7 +84,7 @@ watch(props, ({ mindmapResult, isGenerating, isEnd, isStart }) => {
8384
/** 更新思维导图的展示 */
8485
const update = () => {
8586
try {
86-
const { root } = transformer.transform(processContent(props.mindmapResult))
87+
const { root } = transformer.transform(processContent(props.generatedContent))
8788
markMap?.setData(root)
8889
markMap?.fit()
8990
} catch (e) {
@@ -106,31 +107,19 @@ const processContent = (text: string) => {
106107
}
107108
108109
/** 下载图片 */
109-
// TODO @hhhero:可以抽到 download 这个里面,src/utils/download.ts 么?复用 image 方法?
110110
// download SVG to png file
111111
const downloadImage = () => {
112-
const svgElement = mindmapRef.value
112+
const svgElement = mindMapRef.value
113113
// 将 SVG 渲染到图片对象
114114
const serializer = new XMLSerializer()
115-
const source =
116-
'<?xml version="1.0" standalone="no"?>\r\n' + serializer.serializeToString(svgRef.value!)
117-
const image = new Image()
118-
image.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(source)
119-
120-
// 将图片对象渲染
121-
const canvas = document.createElement('canvas')
122-
canvas.width = svgElement?.offsetWidth || 0
123-
canvas.height = svgElement?.offsetHeight || 0
124-
let context = canvas.getContext('2d')
125-
context?.clearRect(0, 0, canvas.width, canvas.height)
126-
127-
image.onload = function () {
128-
context?.drawImage(image, 0, 0)
129-
const a = document.createElement('a')
130-
a.download = 'mindmap.png'
131-
a.href = canvas.toDataURL(`image/png`)
132-
a.click()
133-
}
115+
const source = `<?xml version="1.0" standalone="no"?>\r\n${serializer.serializeToString(svgRef.value!)}`
116+
const base64Url = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(source)}`
117+
download.image({
118+
url: base64Url,
119+
canvasWidth: svgElement?.offsetWidth,
120+
canvasHeight: svgElement?.offsetHeight,
121+
drawWithImageSize: false
122+
})
134123
}
135124
136125
defineExpose({

src/views/ai/mindmap/index/index.vue

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<!--右边生成思维导图区域-->
1111
<Right
1212
ref="rightRef"
13-
:mindmapResult="mindmapResult"
13+
:generatedContent="generatedContent"
1414
:isEnd="isEnd"
1515
:isGenerating="isGenerating"
1616
:isStart="isStart"
@@ -33,15 +33,15 @@ const isStart = ref(false) // 开始生成,用来清空思维导图
3333
const isEnd = ref(true) // 用来判断结束的时候渲染思维导图
3434
const message = useMessage() // 消息提示
3535
36-
const mindmapResult = ref('') // 生成思维导图结果
36+
const generatedContent = ref('') // 生成思维导图结果
3737
3838
const leftRef = ref<InstanceType<typeof Left>>() // 左边组件
3939
const rightRef = ref<InstanceType<typeof Right>>() // 右边组件
4040
4141
/** 使用已有内容直接生成 **/
4242
const directGenerate = (existPrompt: string) => {
4343
isEnd.value = false // 先设置为false再设置为true,让子组建的watch能够监听到
44-
mindmapResult.value = existPrompt
44+
generatedContent.value = existPrompt
4545
isEnd.value = true
4646
}
4747
@@ -58,7 +58,7 @@ const submit = (data: AiMindMapGenerateReqVO) => {
5858
isStart.value = true
5959
isEnd.value = false
6060
ctrl.value = new AbortController() // 请求控制赋值
61-
mindmapResult.value = '' // 清空生成数据
61+
generatedContent.value = '' // 清空生成数据
6262
AiMindMapApi.generateMindMap({
6363
data,
6464
onMessage: async (res) => {
@@ -68,13 +68,13 @@ const submit = (data: AiMindMapGenerateReqVO) => {
6868
stopStream()
6969
return
7070
}
71-
mindmapResult.value = mindmapResult.value + data
71+
generatedContent.value = generatedContent.value + data
7272
await nextTick()
7373
rightRef.value?.scrollBottom()
7474
},
7575
onClose() {
7676
isEnd.value = true
77-
leftRef.value?.setGeneratedContent(mindmapResult.value)
77+
leftRef.value?.setGeneratedContent(generatedContent.value)
7878
stopStream()
7979
},
8080
onError(err) {
@@ -87,6 +87,6 @@ const submit = (data: AiMindMapGenerateReqVO) => {
8787
8888
/** 初始化 */
8989
onMounted(() => {
90-
mindmapResult.value = MindMapContentExample
90+
generatedContent.value = MindMapContentExample
9191
})
9292
</script>

0 commit comments

Comments
 (0)