window-area.uvue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. <template>
  2. <view style="flex:1;">
  3. <view id="statusBar" class="statusBar" v-if="statusBarArea.width > 0 && statusBarArea.height > 0"
  4. :style="{'width': statusBarArea.width,'height': statusBarArea.height}">
  5. </view>
  6. <view id="cutoutArea" class="cutoutArea" v-if="cutoutArea.length > 0" v-for="(item, _) in cutoutArea"
  7. :style="{'top': item.top,'left': item.left,'width': item.width,'height': item.height}"></view>
  8. <view id="safeArea" class="safeArea"
  9. :style="{'top': safeArea.top,'left': safeArea.left,'width': safeArea.width,'height': safeArea.height}"></view>
  10. <view id="bottomNavigationIndicator" class="bottomNavigationIndicator"
  11. v-if="bottomNavigationIndicatorArea.width > 0 && bottomNavigationIndicatorArea.height > 0"
  12. :style="{'width': bottomNavigationIndicatorArea.width,'height': bottomNavigationIndicatorArea.height}"></view>
  13. <view style="flex: 1;justify-content: center;align-items: center;">
  14. <view v-if="statusBarArea.width > 0 && statusBarArea.height > 0" style="margin: 5px 0;">
  15. <text style="color: red;">系统状态栏区域</text>
  16. </view>
  17. <view v-if="cutoutArea.length > 0" style="margin: 5px 0;">
  18. <text style="color: orange;">摄像头区域</text>
  19. </view>
  20. <view style="margin: 5px 0;">
  21. <text style="color: green;">安全区域</text>
  22. </view>
  23. <view v-if="bottomNavigationIndicatorArea.width > 0 && bottomNavigationIndicatorArea.height > 0"
  24. style="margin: 5px 0;">
  25. <text style="color: blue;">系统导航栏区域</text>
  26. </view>
  27. <!-- <view style="flex-direction: row;align-items: center;margin: 5px 0">
  28. <text>显示系统状态栏</text>
  29. <switch :checked="isStatusBarShow" @change="statusBarChange"></switch>
  30. </view>
  31. <view style="flex-direction: row;align-items: center;margin: 5px 0">
  32. <text>显示系统导航栏</text>
  33. <switch :checked="isBottomNavigationIndicatorShow" @change="bottomNavigationIndicatorChange"></switch>
  34. </view> -->
  35. </view>
  36. </view>
  37. </template>
  38. <script setup>
  39. type StatusBarArea = {
  40. width : number,
  41. height : number
  42. }
  43. type CutoutArea = {
  44. top : number,
  45. left : number,
  46. width : number,
  47. height : number
  48. }
  49. type SafeArea = {
  50. top : number,
  51. left : number,
  52. width : number,
  53. height : number
  54. }
  55. type BottomNavigationIndicatorArea = {
  56. width : number,
  57. height : number
  58. }
  59. const statusBarArea = ref({ width: 0, height: 0 } as StatusBarArea);
  60. const cutoutArea = ref([] as CutoutArea[]);
  61. const safeArea = ref({ top: 0, left: 0, width: 0, height: 0 } as SafeArea);
  62. const bottomNavigationIndicatorArea = ref({ width: 0, height: 0 } as BottomNavigationIndicatorArea);
  63. const isStatusBarShow = ref(false);
  64. const isBottomNavigationIndicatorShow = ref(false);
  65. const getWindowInfo = () => {
  66. const info = uni.getWindowInfo();
  67. statusBarArea.value.width = info.windowWidth;
  68. statusBarArea.value.height = info.safeAreaInsets.top;
  69. cutoutArea.value.length = 0;
  70. (info.cutoutArea ?? []).forEach((item) => {
  71. cutoutArea.value.push({
  72. top: item.top,
  73. left: item.left,
  74. width: item.right - item.left,
  75. height: item.bottom - item.top
  76. } as CutoutArea);
  77. })
  78. safeArea.value.top = info.safeArea.top;
  79. safeArea.value.left = info.safeArea.left;
  80. safeArea.value.width = info.safeArea.width;
  81. safeArea.value.height = info.safeArea.height;
  82. bottomNavigationIndicatorArea.value.width = info.windowWidth;
  83. bottomNavigationIndicatorArea.value.height = info.safeAreaInsets.bottom;
  84. };
  85. const statusBarChange = (e : UniSwitchChangeEvent) => {
  86. const pages = getCurrentPages();
  87. pages[pages.length - 1].setPageStyle({
  88. 'hideStatusBar': !e.detail.value,
  89. });
  90. };
  91. const bottomNavigationIndicatorChange = (e : UniSwitchChangeEvent) => {
  92. const pages = getCurrentPages();
  93. pages[pages.length - 1].setPageStyle({
  94. 'hideBottomNavigationIndicator': !e.detail.value,
  95. });
  96. };
  97. onReady(() => {
  98. const pages = getCurrentPages();
  99. // #ifndef MP
  100. isStatusBarShow.value = !(pages[pages.length - 1].getPageStyle()['hideStatusBar'] as boolean);
  101. isBottomNavigationIndicatorShow.value = !(pages[pages.length - 1].getPageStyle()['hideBottomNavigationIndicator'] as boolean);
  102. // #endif
  103. getWindowInfo();
  104. });
  105. onResize((_ : OnResizeOptions) => {
  106. getWindowInfo();
  107. });
  108. </script>
  109. <style>
  110. .statusBar {
  111. position: absolute;
  112. border-style: solid;
  113. border-color: red;
  114. border-width: 4px;
  115. }
  116. .cutoutArea {
  117. position: absolute;
  118. border-style: solid;
  119. border-color: orange;
  120. border-width: 4px;
  121. }
  122. .safeArea {
  123. position: absolute;
  124. border-style: solid;
  125. border-color: green;
  126. border-width: 4px;
  127. }
  128. .bottomNavigationIndicator {
  129. position: absolute;
  130. bottom: 0;
  131. border-style: solid;
  132. border-color: blue;
  133. border-width: 4px;
  134. }
  135. </style>