useFullScreen.ts 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import { Ref, ref, unref } from 'vue';
  2. type RFSMethodName =
  3. | 'webkitRequestFullScreen'
  4. | 'requestFullscreen'
  5. | 'msRequestFullscreen'
  6. | 'mozRequestFullScreen';
  7. type EFSMethodName =
  8. | 'webkitExitFullscreen'
  9. | 'msExitFullscreen'
  10. | 'mozCancelFullScreen'
  11. | 'exitFullscreen';
  12. type FSEPropName =
  13. | 'webkitFullscreenElement'
  14. | 'msFullscreenElement'
  15. | 'mozFullScreenElement'
  16. | 'fullscreenElement';
  17. type ONFSCPropName = 'onfullscreenchange' | 'onwebkitfullscreenchange' | 'MSFullscreenChange';
  18. export function useFullscreen(
  19. target: Ref<Nullable<HTMLElement>> = ref(document.documentElement),
  20. options?: FullscreenOptions
  21. ) {
  22. const isFullscreenRef = ref(false);
  23. const DOC_EL = document.documentElement;
  24. let RFC_METHOD_NAME: RFSMethodName = 'requestFullscreen';
  25. let EFS_METHOD_NAME: EFSMethodName = 'exitFullscreen';
  26. let FSE_PROP_NAME: FSEPropName = 'fullscreenElement';
  27. let ON_FSC_PROP_NAME: ONFSCPropName = 'onfullscreenchange';
  28. if ('webkitRequestFullScreen' in DOC_EL) {
  29. RFC_METHOD_NAME = 'webkitRequestFullScreen';
  30. EFS_METHOD_NAME = 'webkitExitFullscreen';
  31. FSE_PROP_NAME = 'webkitFullscreenElement';
  32. ON_FSC_PROP_NAME = 'onwebkitfullscreenchange';
  33. } else if ('msRequestFullscreen' in DOC_EL) {
  34. RFC_METHOD_NAME = 'msRequestFullscreen';
  35. EFS_METHOD_NAME = 'msExitFullscreen';
  36. FSE_PROP_NAME = 'msFullscreenElement';
  37. ON_FSC_PROP_NAME = 'MSFullscreenChange';
  38. } else if ('mozRequestFullScreen' in DOC_EL) {
  39. RFC_METHOD_NAME = 'mozRequestFullScreen';
  40. EFS_METHOD_NAME = 'mozCancelFullScreen';
  41. FSE_PROP_NAME = 'mozFullScreenElement';
  42. // ON_FSC_PROP_NAME = 'onmozfullscreenchange';
  43. } else if (!('requestFullscreen' in DOC_EL)) {
  44. throw new Error('当前浏览器不支持Fullscreen API !');
  45. }
  46. function enterFullscreen(): Promise<void> {
  47. isFullscreenRef.value = true;
  48. return (target.value as any)[RFC_METHOD_NAME](options);
  49. }
  50. function exitFullscreen(): Promise<void> {
  51. isFullscreenRef.value = false;
  52. return (document as any)[EFS_METHOD_NAME]();
  53. }
  54. function isFullscreen(): boolean {
  55. return unref(target) === (document as any)[FSE_PROP_NAME];
  56. }
  57. function toggleFullscreen(): Promise<void> {
  58. if (isFullscreen()) {
  59. return exitFullscreen();
  60. } else {
  61. return enterFullscreen();
  62. }
  63. }
  64. /**
  65. * 当全屏/退出时触发
  66. */
  67. function watchFullscreen(callback: (isFull: boolean) => void) {
  68. const cancel = () => {
  69. const t = unref(target);
  70. t && (t.onfullscreenchange = null);
  71. };
  72. const handler = () => {
  73. callback(isFullscreen());
  74. };
  75. if (target.value) {
  76. (target.value as any)[ON_FSC_PROP_NAME] = handler;
  77. }
  78. return {
  79. cancel,
  80. };
  81. }
  82. watchFullscreen((isFull: boolean) => {
  83. isFullscreenRef.value = isFull;
  84. });
  85. return {
  86. watchFullscreen,
  87. toggleFullscreen,
  88. exitFullscreen,
  89. isFullscreen,
  90. enterFullscreen,
  91. isFullscreenRef,
  92. };
  93. }