Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 2e7aea7

Browse files
feat: svg画图代码重构
1 parent ca5beda commit 2e7aea7

File tree

3 files changed

+152
-47
lines changed

3 files changed

+152
-47
lines changed

‎src/views/draw/Svg.tsx

Lines changed: 111 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
11
import React, { useEffect, useState } from 'react'
2-
import { Drauu, createDrauu } from 'drauu'
2+
import { Brush,Drauu,DrawingMode, createDrauu } from 'drauu'
33
import SvgTools from './components/SvgTools'
44
import styles from './svg.module.scss'
55
const DrawSvg = () => {
66
const [drauu, setDrauu] = useState<Drauu | null>(null)
7+
const [option, setOption] = useState<Brush>({
8+
mode: 'stylus', // 'line', 'rectangle', 'ellipse'
9+
color: '#000',
10+
size: 5,
11+
dasharray: undefined,
12+
arrowEnd: false
13+
})
714
useEffect(() => {
815
setDrauu(() => {
916
const drauu = createDrauu({
@@ -14,13 +21,115 @@ const DrawSvg = () => {
1421
size: 5
1522
}
1623
})
24+
1725
return drauu
1826
})
1927
}, [])
28+
useEffect(() => {
29+
if (drauu) {
30+
window.addEventListener('keydown', (e) => {
31+
if (drauu) {
32+
if (e.code === 'KeyZ' && (e.ctrlKey || e.metaKey)) {
33+
if (e.shiftKey) onRedo()
34+
else onUndo()
35+
} else if (e.code === 'KeyL') {
36+
onModeChange?.('line', false)
37+
} else if (e.code === 'KeyD') {
38+
onModeChange?.('draw', false)
39+
} else if (e.code === 'KeyS') {
40+
onModeChange?.('stylus', false)
41+
} else if (e.code === 'KeyR') {
42+
onModeChange?.('rectangle', false)
43+
} else if (e.code === 'KeyE') {
44+
onModeChange?.('ellipse', false)
45+
} else if (e.code === 'KeyC') {
46+
onClear?.()
47+
} else if (e.code === 'Equal') {
48+
onSizeChange?.(option.size + 0.5)
49+
} else if (e.code === 'Minus') {
50+
onSizeChange?.(option.size - 0.5)
51+
}
52+
}
53+
})
54+
}
55+
}, [drauu])
56+
57+
function onModeChange(mode: DrawingMode, arrowEnd: boolean) {
58+
drauu!.brush.arrowEnd = arrowEnd
59+
drauu!.mode = mode
60+
setOption({
61+
...option,
62+
mode,
63+
arrowEnd
64+
})
65+
}
66+
function onSizeChange(size: number) {
67+
drauu!.brush.size = size
68+
setOption({
69+
...option,
70+
size
71+
})
72+
}
73+
function onColorChange(color: string) {
74+
drauu!.brush.color = color
75+
setOption({
76+
...option,
77+
color
78+
})
79+
}
80+
function onDashArrayChange(dasharray: string | undefined) {
81+
drauu!.brush.dasharray = dasharray
82+
setOption({
83+
...option,
84+
dasharray
85+
})
86+
}
87+
function onSave() {
88+
drauu!.el!.setAttribute('xmlns', 'http://www.w3.org/2000/svg')
89+
const data = drauu!.el!.outerHTML || ''
90+
const blob = new Blob([data], { type: 'image/svg+xml' })
91+
const elem = window.document.createElement('a')
92+
elem.href = window.URL.createObjectURL(blob)
93+
elem.download = 'drauu.svg'
94+
document.body.appendChild(elem)
95+
elem.click()
96+
document.body.removeChild(elem)
97+
}
98+
function onRedo() {
99+
drauu?.redo()
100+
}
101+
function onUndo() {
102+
drauu?.undo()
103+
}
104+
function onClear() {
105+
drauu?.clear()
106+
}
20107
return (
21108
<div className={'page-container ' + styles.svgPage}>
22-
<SvgTools drauu={drauu}></SvgTools>
109+
<SvgTools
110+
onModeChange={onModeChange}
111+
onSizeChange={onSizeChange}
112+
onColorChange={onColorChange}
113+
onDashArrayChange={onDashArrayChange}
114+
onSave={onSave}
115+
onRedo={onRedo}
116+
onUndo={onUndo}
117+
onClear={onClear}
118+
option={option}
119+
></SvgTools>
23120
<svg className={styles.svgMain} id="svg"></svg>
121+
<pre className={styles.svgTips}>
122+
{`
123+
f / freehand
124+
l / line
125+
r / rectangle
126+
e / ellipse
127+
c / clear
128+
+ / increase size
129+
- / decrease size
130+
ctrl+z / undo
131+
shift+ctrl+z / redo`}
132+
</pre>
24133
</div>
25134
)
26135
}

‎src/views/draw/components/SvgTools.tsx

Lines changed: 32 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Button, Col, ColorPicker, Divider, Row, Slider } from 'antd'
22
import styles from './svgTools.module.scss'
33
import IconFont from '@/components/Iconfont'
4-
import { Drauu, DrawingMode } from 'drauu'
4+
import { Brush,Drauu, DrawingMode } from 'drauu'
55
import { useEffect, useMemo, useState } from 'react'
66

77
interface DrawModeAndIcon {
@@ -78,64 +78,48 @@ const dasharrayList: Dasharray[] = [
7878
]
7979

8080
interface Iprops {
81-
drauu: Drauu | null
8281
className?: string
82+
option: Brush
83+
onModeChange?: (mode: DrawingMode, arrowEnd: boolean) => void
84+
onSizeChange?: (size: number) => void
85+
onDashArrayChange?: (dashArray: string | undefined) => void
86+
onColorChange?: (color: string) => void
87+
onSave?: () => void
88+
onUndo?: () => void
89+
onRedo?: () => void
90+
onClear?: () => void
8391
}
8492
const SvgTools = (props: Iprops) => {
85-
const drauu = useMemo(() => {
86-
return props.drauu
87-
}, [props.drauu])
88-
const [currentMode, setCurrentMode] = useState<string>(
89-
props?.drauu?.mode || 'stylus'
90-
)
91-
const [currentColor, setCurrentColor] = useState<string>(
92-
props?.drauu?.brush.color || '#000'
93-
)
94-
const [currentSize, setCurrentSize] = useState<number>(
95-
props?.drauu?.brush.size || 5
96-
)
97-
const [currentDash, setCurrentDash] = useState<string | undefined>(
98-
props?.drauu?.brush?.dasharray
99-
)
100-
const [colorPickerOpen, setColorPickerOpen] = useState(false)
93+
const option = useMemo(() => {
94+
return props.option
95+
}, [props.option])
96+
10197
function undo() {
102-
drauu?.undo()
98+
props.onUndo?.()
10399
}
104100
function redo() {
105-
drauu?.redo()
101+
props.onRedo?.()
106102
}
107103
function clear() {
108-
drauu?.clear()
104+
props.onClear?.()
109105
}
110106
function drawingModeChange(drawModeAndIcon: DrawModeAndIcon) {
111-
drauu!.brush.arrowEnd = drawModeAndIcon.arrowEnd
112-
drauu!.mode = drawModeAndIcon.mode
113-
setCurrentMode(drawModeAndIcon.key)
107+
// drauu!.brush.arrowEnd = drawModeAndIcon.arrowEnd
108+
// drauu!.mode = drawModeAndIcon.mode
109+
props.onModeChange?.(drawModeAndIcon.mode,drawModeAndIcon.arrowEnd)
114110
}
115111
function dasharrayChange(dashArray: Dasharray) {
116-
drauu!.brush.dasharray = dashArray.value
117-
setCurrentDash(dashArray.value)
112+
props.onDashArrayChange?.(dashArray.value)
118113
}
119114
function colorChange(color: string) {
120-
drauu!.brush.color = color
121-
setCurrentColor(color)
115+
props.onColorChange?.(color)
122116
}
123117
function sizeChange(value: number) {
124-
drauu!.brush.size = value
125-
setCurrentSize(value)
118+
props.onSizeChange?.(value)
126119
}
127120
function save() {
128-
drauu!.el!.setAttribute('xmlns', 'http://www.w3.org/2000/svg')
129-
const data = drauu!.el!.outerHTML || ''
130-
const blob = new Blob([data], { type: 'image/svg+xml' })
131-
const elem = window.document.createElement('a')
132-
elem.href = window.URL.createObjectURL(blob)
133-
elem.download = 'drauu.svg'
134-
document.body.appendChild(elem)
135-
elem.click()
136-
document.body.removeChild(elem)
121+
props.onSave?.()
137122
}
138-
139123
return (
140124
<div className={styles.svgTools}>
141125
<Row align="middle" gutter={4}>
@@ -172,7 +156,10 @@ const SvgTools = (props: Iprops) => {
172156
<Button
173157
title={drawingMode.key}
174158
className={
175-
currentMode == drawingMode.key ? styles.activeItem : ''
159+
option.mode == drawingMode.mode &&
160+
option.arrowEnd == drawingMode.arrowEnd
161+
? styles.activeItem
162+
: ''
176163
}
177164
onClick={() => drawingModeChange(drawingMode)}
178165
type="text"
@@ -194,7 +181,7 @@ const SvgTools = (props: Iprops) => {
194181
onChange={sizeChange}
195182
min={1}
196183
max={40}
197-
defaultValue={currentSize}
184+
defaultValue={option.size}
198185
/>
199186
</Col>
200187
<Col>
@@ -206,7 +193,7 @@ const SvgTools = (props: Iprops) => {
206193
<Button
207194
title={dasharray.key}
208195
className={
209-
currentDash == dasharray.value ? styles.activeItem : ''
196+
option.dasharray == dasharray.value ? styles.activeItem : ''
210197
}
211198
onClick={() => dasharrayChange(dasharray)}
212199
type="text"
@@ -224,11 +211,11 @@ const SvgTools = (props: Iprops) => {
224211
<Col>
225212
<Divider plain type="vertical" />
226213
</Col>
227-
<ColonClick={()=>setColorPickerOpen(true)}>
214+
<Col>
228215
<ColorPicker
229216
// open={colorPickerOpen}
230217
onChange={(color) => colorChange(color.toHexString())}
231-
value={currentColor}
218+
value={option.color}
232219
presets={[
233220
{
234221
label: '快速选择',

‎src/views/draw/svg.module.scss

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,13 @@
88
flex: 1;
99
height: 0;
1010
cursor: crosshair;
11+
}
12+
13+
.svgTips {
14+
position: fixed;
15+
line-height: 1.5;
16+
right: 40px;
17+
bottom: 50px;
18+
opacity: .35;
19+
pointer-events: none;
1120
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /