Skip to content

Commit 10cbce9

Browse files
authored
Merge pull request #3 from nowscott/development
优化下载体验
2 parents 59102bf + c85046e commit 10cbce9

File tree

3 files changed

+92
-67
lines changed

3 files changed

+92
-67
lines changed

src/components/Header/index.tsx

+51-37
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import React from 'react';
2-
import { Layout, Typography } from 'antd';
3-
import { StepBackwardFilled, StepForwardFilled } from '@ant-design/icons';
2+
import { Layout, Typography, Button } from 'antd';
3+
import { StepBackwardFilled, StepForwardFilled, ShareAltOutlined } from '@ant-design/icons';
44
import Input from '../Input';
5+
import { downloadPreviewImage } from '../../utils/download';
56

67
const { Header: AntHeader } = Layout;
78
const { Title } = Typography;
@@ -33,26 +34,24 @@ const Header: React.FC<HeaderProps> = ({ isDarkMode, onSubmit, leftSiderCollapse
3334
borderBottom: `1px solid ${isDarkMode ? '#303030' : '#f0f0f0'}`
3435
}}
3536
>
36-
<div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
37-
{leftSiderCollapsed ? (
38-
<StepForwardFilled
39-
style={{
40-
fontSize: '18px',
41-
color: isDarkMode ? '#ffffff' : '#000000',
42-
cursor: 'pointer'
43-
}}
44-
onClick={onLeftSiderCollapse}
45-
/>
46-
) : (
47-
<StepBackwardFilled
48-
style={{
49-
fontSize: '18px',
50-
color: isDarkMode ? '#ffffff' : '#000000',
51-
cursor: 'pointer'
52-
}}
53-
onClick={onLeftSiderCollapse}
54-
/>
55-
)}
37+
<div style={{ display: 'flex', alignItems: 'center', gap: '16px' }}>
38+
<Button
39+
type="default"
40+
icon={leftSiderCollapsed ? (
41+
<StepForwardFilled style={{ color: '#fa8c16' }} />
42+
) : (
43+
<StepBackwardFilled style={{ color: isDarkMode ? '#ffffff' : '#000000' }} />
44+
)}
45+
onClick={onLeftSiderCollapse}
46+
style={{
47+
padding: 0,
48+
width: '32px',
49+
height: '32px',
50+
display: 'flex',
51+
alignItems: 'center',
52+
justifyContent: 'center'
53+
}}
54+
/>
5655
<Title
5756
level={4}
5857
style={{
@@ -76,27 +75,42 @@ const Header: React.FC<HeaderProps> = ({ isDarkMode, onSubmit, leftSiderCollapse
7675
</a>
7776
</Title>
7877
</div>
79-
<div style={{ marginLeft: 'auto', flex: '0 1 420px', display: 'flex', alignItems: 'center', gap: '16px' }}>
80-
<Input onSubmit={onSubmit} />
81-
{rightSiderCollapsed ? (
82-
<StepBackwardFilled
78+
<div style={{ flex: '1 1 auto', display: 'flex', alignItems: 'center', position: 'relative' }}>
79+
<div style={{ position: 'absolute', left: '50%', transform: 'translateX(-50%)', width: '420px' }}>
80+
<Input onSubmit={onSubmit} />
81+
</div>
82+
<div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: '16px' }}>
83+
<Button
84+
type="default"
85+
icon={<ShareAltOutlined style={{ color: isDarkMode ? '#ffffff' : '#000000' }} />}
86+
onClick={() => downloadPreviewImage()}
8387
style={{
84-
fontSize: '18px',
85-
color: isDarkMode ? '#ffffff' : '#000000',
86-
cursor: 'pointer'
88+
padding: 0,
89+
width: '32px',
90+
height: '32px',
91+
display: 'flex',
92+
alignItems: 'center',
93+
justifyContent: 'center'
8794
}}
88-
onClick={onRightSiderCollapse}
8995
/>
90-
) : (
91-
<StepForwardFilled
96+
<Button
97+
type="default"
98+
icon={rightSiderCollapsed ? (
99+
<StepBackwardFilled style={{ color: '#fa8c16' }} />
100+
) : (
101+
<StepForwardFilled style={{ color: isDarkMode ? '#ffffff' : '#000000' }} />
102+
)}
103+
onClick={onRightSiderCollapse}
92104
style={{
93-
fontSize: '18px',
94-
color: isDarkMode ? '#ffffff' : '#000000',
95-
cursor: 'pointer'
105+
padding: 0,
106+
width: '32px',
107+
height: '32px',
108+
display: 'flex',
109+
alignItems: 'center',
110+
justifyContent: 'center'
96111
}}
97-
onClick={onRightSiderCollapse}
98112
/>
99-
)}
113+
</div>
100114
</div>
101115
</AntHeader>
102116
);

src/components/Input/index.tsx

+1-30
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import React, { useState } from 'react';
22
import { Input as AntInput, Button, Space } from 'antd';
3-
import { EyeOutlined, DownloadOutlined } from '@ant-design/icons';
4-
import domtoimage from 'dom-to-image';
3+
import { EyeOutlined } from '@ant-design/icons';
54

65
interface InputProps {
76
onSubmit: (url: string) => void;
@@ -16,31 +15,6 @@ const Input: React.FC<InputProps> = ({ onSubmit }) => {
1615
}
1716
};
1817

19-
const handleDownload = async () => {
20-
const previewElement = document.querySelector('.app-content > div') as HTMLElement;
21-
if (!previewElement) return;
22-
23-
try {
24-
const dataUrl = await domtoimage.toPng(previewElement, {
25-
height: previewElement.offsetHeight * 8,
26-
width: previewElement.offsetWidth * 8,
27-
style: {
28-
transform: 'scale(8)',
29-
transformOrigin: 'top left',
30-
width: `${previewElement.offsetWidth}px`,
31-
height: `${previewElement.offsetHeight}px`
32-
},
33-
});
34-
const link = document.createElement('a');
35-
const repoName = document.querySelector('.app-content')?.querySelector('h1')?.textContent || 'repo';
36-
link.download = `${repoName}.png`;
37-
link.href = dataUrl;
38-
link.click();
39-
} catch (error) {
40-
console.error('下载图片时出错:', error);
41-
}
42-
};
43-
4418
return (
4519
<Space style={{ width: '100%' }}>
4620
<AntInput
@@ -52,9 +26,6 @@ const Input: React.FC<InputProps> = ({ onSubmit }) => {
5226
<Button type="primary" icon={<EyeOutlined />} onClick={handleSubmit}>
5327
生成预览
5428
</Button>
55-
<Button icon={<DownloadOutlined />} onClick={handleDownload}>
56-
下载图片
57-
</Button>
5829
</Space>
5930
);
6031
};

src/utils/download.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
import domtoimage from 'dom-to-image';
3+
import { message } from 'antd';
4+
5+
interface DownloadOptions {
6+
scale?: number;
7+
quality?: number;
8+
}
9+
10+
export const downloadPreviewImage = async (options: DownloadOptions = {}) => {
11+
const previewElement = document.querySelector('.app-content > div') as HTMLElement;
12+
if (!previewElement) return;
13+
14+
const { scale = 8, quality = 1 } = options;
15+
16+
try {
17+
const dataUrl = await domtoimage.toPng(previewElement, {
18+
height: previewElement.offsetHeight * scale,
19+
width: previewElement.offsetWidth * scale,
20+
style: {
21+
transform: `scale(${scale})`,
22+
transformOrigin: 'top left',
23+
width: `${previewElement.offsetWidth}px`,
24+
height: `${previewElement.offsetHeight}px`
25+
},
26+
quality
27+
});
28+
29+
const link = document.createElement('a');
30+
const repoName = document.querySelector('.app-content')?.querySelector('h1')?.textContent || 'repo';
31+
link.download = `${repoName}.png`;
32+
link.href = dataUrl;
33+
link.click();
34+
message.success('图片已成功保存!');
35+
} catch (error) {
36+
console.error('下载图片时出错:', error);
37+
message.error('保存图片失败,请稍后重试');
38+
throw error;
39+
}
40+
};

0 commit comments

Comments
 (0)