Skip to content

Commit 718e980

Browse files
committed
feat: svg viewer full screen
1 parent 3d4bfc7 commit 718e980

2 files changed

Lines changed: 107 additions & 2 deletions

File tree

src/components/stateless/SvgPreview/index.jsx

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import React, { useEffect, useRef, useState } from 'react'
22
import { Button, message } from 'antd'
3-
import { ZoomInOutlined, ZoomOutOutlined, SyncOutlined, DownloadOutlined } from '@ant-design/icons'
3+
import {
4+
ZoomInOutlined,
5+
ZoomOutOutlined,
6+
SyncOutlined,
7+
DownloadOutlined,
8+
FullscreenOutlined,
9+
FullscreenExitOutlined,
10+
} from '@ant-design/icons'
411

512
const defaultBg = '#1e1e1e'
613

@@ -249,6 +256,98 @@ function SvgPreview({
249256
}
250257
}
251258

259+
// fullscreen handling
260+
const [isFullscreen, setIsFullscreen] = useState(false)
261+
262+
useEffect(() => {
263+
const onFsChange = () => {
264+
try {
265+
const isFs = !!(document.fullscreenElement || document.webkitFullscreenElement || document.msFullscreenElement)
266+
// temporarily disable transform transitions to avoid layout/paint thrash when entering/exiting fullscreen
267+
try {
268+
const el = innerRef.current
269+
if (el) {
270+
const prev = el.style.transition
271+
el.style.transition = 'none'
272+
requestAnimationFrame(() => {
273+
// restore after frame to allow browser to finish fullscreen layout
274+
el.style.transition = prev || ''
275+
})
276+
}
277+
} catch (e) {
278+
console.log('error', e.message)
279+
}
280+
setIsFullscreen(isFs)
281+
} catch (e) {
282+
console.log('error', e.message)
283+
}
284+
}
285+
document.addEventListener('fullscreenchange', onFsChange)
286+
document.addEventListener('webkitfullscreenchange', onFsChange)
287+
document.addEventListener('mozfullscreenchange', onFsChange)
288+
document.addEventListener('MSFullscreenChange', onFsChange)
289+
return () => {
290+
document.removeEventListener('fullscreenchange', onFsChange)
291+
document.removeEventListener('webkitfullscreenchange', onFsChange)
292+
document.removeEventListener('mozfullscreenchange', onFsChange)
293+
document.removeEventListener('MSFullscreenChange', onFsChange)
294+
}
295+
}, [])
296+
297+
const enterFullscreen = async (el) => {
298+
if (!el) return
299+
const req = el.requestFullscreen || el.webkitRequestFullscreen || el.mozRequestFullScreen || el.msRequestFullscreen
300+
if (req) {
301+
try {
302+
await req.call(el)
303+
} catch (e) {
304+
console.log('error', e.message)
305+
}
306+
}
307+
}
308+
309+
const exitFullscreen = async () => {
310+
const exit =
311+
document.exitFullscreen ||
312+
document.webkitExitFullscreen ||
313+
document.mozCancelFullScreen ||
314+
document.msExitFullscreen
315+
if (exit) {
316+
try {
317+
await exit.call(document)
318+
} catch (e) {
319+
console.log('error', e.message)
320+
}
321+
}
322+
}
323+
324+
const toggleFullscreen = async () => {
325+
try {
326+
const el = innerRef.current
327+
if (el) {
328+
const prev = el.style.transition
329+
el.style.transition = 'none'
330+
if (!isFullscreen) {
331+
await enterFullscreen(containerRef.current || document.documentElement)
332+
} else {
333+
await exitFullscreen()
334+
}
335+
requestAnimationFrame(() => {
336+
el.style.transition = prev || ''
337+
})
338+
return
339+
}
340+
} catch (e) {
341+
console.log('error', e.message)
342+
}
343+
344+
if (!isFullscreen) {
345+
await enterFullscreen(containerRef.current || document.documentElement)
346+
} else {
347+
await exitFullscreen()
348+
}
349+
}
350+
252351
return (
253352
<div style={{ height: '100%', position: 'relative' }}>
254353
<div
@@ -304,6 +403,12 @@ function SvgPreview({
304403
</div>
305404
<Button icon={<ZoomInOutlined />} onClick={handleZoomIn} type="text" style={{ color: '#fff' }} />
306405
<Button icon={<SyncOutlined />} onClick={handleReset} type="text" style={{ color: '#fff' }} />
406+
<Button
407+
icon={isFullscreen ? <FullscreenExitOutlined /> : <FullscreenOutlined />}
408+
onClick={toggleFullscreen}
409+
type="text"
410+
style={{ color: '#fff' }}
411+
/>
307412
<Button icon={<DownloadOutlined />} onClick={handleDownload} type="primary" size="small">
308413
下载
309414
</Button>

src/pages/svgViewer/index.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import FixTabPanel from '@stateless/FixTabPanel'
22
import SvgPreview from '@stateless/SvgPreview'
33
import DiagramSvgRbac from '@assets/svg/architecture-diagram-rbac.svg'
44
import DiagramSvg from '@assets/svg/architecture-diagram.svg'
5-
import { Card, Space, Typography, Row, Col, Divider } from 'antd'
5+
import { Card, Space, Typography, Row, Col } from 'antd'
66

77
const { Title, Paragraph, Text } = Typography
88

0 commit comments

Comments
 (0)