generated from yandex-praktikum/client-server-template-with-vite
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfullscreenHook.ts
134 lines (111 loc) · 3.54 KB
/
fullscreenHook.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import { useCallback, useRef, useState, useEffect } from 'react'
interface IDocument extends Document {
mozFullScreenElement?: Element
msFullscreenElement?: Element
webkitFullscreenElement?: Element
}
interface IHTMLElement extends HTMLElement {
msRequestFullscreen?: () => Promise<void>
mozRequestFullscreen?: () => Promise<void>
webkitEnterFullscreen?: () => Promise<void>
webkitRequestFullscreen?: () => Promise<void>
}
function getFullscreenElement() {
const _document: IDocument = window.document
const fullscreenElement =
_document.fullscreenElement ||
_document.webkitFullscreenElement ||
_document.mozFullScreenElement ||
_document.msFullscreenElement
return fullscreenElement
}
function exitFullscreen() {
const _document = window.document as any
if (typeof _document.exitFullscreen === 'function')
return _document.exitFullscreen()
if (typeof _document.msExitFullscreen === 'function')
return _document.msExitFullscreen()
if (typeof _document.webkitExitFullscreen === 'function')
return _document.webkitExitFullscreen()
if (typeof _document.mozCancelFullScreen === 'function')
return _document.mozCancelFullScreen()
return null
}
function enterFullScreen(element: HTMLElement) {
const _element = element as IHTMLElement
return (
_element.requestFullscreen?.() ||
_element.msRequestFullscreen?.() ||
_element.webkitEnterFullscreen?.() ||
_element.webkitRequestFullscreen?.() ||
_element.mozRequestFullscreen?.()
)
}
const prefixes = ['', 'webkit', 'moz', 'ms']
function addEvents(
element: HTMLElement,
{
onFullScreen,
onError,
}: { onFullScreen: (event: Event) => void; onError: (event: Event) => void }
) {
prefixes.forEach(prefix => {
element.addEventListener(`${prefix}fullscreenchange`, onFullScreen)
element.addEventListener(`${prefix}fullscreenerror`, onError)
})
return () => {
prefixes.forEach(prefix => {
element.removeEventListener(`${prefix}fullscreenchange`, onFullScreen)
element.removeEventListener(`${prefix}fullscreenerror`, onError)
})
}
}
export function useFullscreen<T extends HTMLElement = HTMLElement>() {
const [isFullscreen, setIsFullscreen] = useState<boolean>(false)
const _ref = useRef<T>()
const handleFullscreenChange = useCallback(
(event: Event) => {
setIsFullscreen(event.target === getFullscreenElement())
},
[setIsFullscreen]
)
const handleFullscreenError = useCallback(
(event: Event) => {
setIsFullscreen(false)
// eslint-disable-next-line no-console
console.error(`Ошибка вывода на полный экран: ${event} (${event.target})`)
},
[setIsFullscreen]
)
const toggleFullscreen = useCallback(() => {
if (!getFullscreenElement()) {
enterFullScreen(_ref.current!)
} else {
exitFullscreen()
}
}, [])
const ref = useCallback((element: T | null) => {
if (element === null) {
_ref.current = window.document.documentElement as T
} else {
_ref.current = element
}
}, [])
useEffect(() => {
if (!_ref.current && window.document) {
_ref.current = window.document.documentElement as T
return addEvents(_ref.current, {
onFullScreen: handleFullscreenChange,
onError: handleFullscreenError,
})
}
if (_ref.current) {
return addEvents(_ref.current, {
onFullScreen: handleFullscreenChange,
onError: handleFullscreenError,
})
}
return undefined
}, [])
return { isFullscreen, toggleFullscreen, ref } as const
}