index.vue 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. <template>
  2. <div class="player-page" :style="bodyStyle">
  3. <div class="page-wrapper" :style="pageWapperStyle">
  4. <RenderComponent v-for="element in getElements" :key="element.key" :element="element"/>
  5. <Result
  6. v-if="!currentPage"
  7. status="warning"
  8. title="很抱歉!当前项目未知错误."
  9. subTitle="请联系管理员"
  10. >
  11. <template #extra>
  12. <Button key="console" type="primary" @click="$router.replace('/')">返回首页</Button>
  13. </template>
  14. </Result>
  15. </div>
  16. </div>
  17. </template>
  18. <script setup lang="ts">
  19. import type { CustomElement, ProjectInfo } from '#/project';
  20. import { ref, onMounted, onBeforeUnmount, StyleValue, computed } from "vue";
  21. import { Result, Button } from "ant-design-vue";
  22. import RenderComponent from "./component/RenderComponent.vue";
  23. import { ScreenFillEnum } from "@/enum/screenFillEnum";
  24. const projectInfo = JSON.parse(localStorage.getItem("currentProject") || "{}") as ProjectInfo;
  25. document.title = `${projectInfo?.name || '沙鲁大屏项目'}--沙鲁低码平台`;
  26. const currentPage = ref(projectInfo.pages?.[0]);
  27. const pageWapperStyle = ref<StyleValue>();
  28. const bodyStyle = ref<StyleValue>();
  29. const getElements = computed(() => {
  30. const list: CustomElement[] = [];
  31. (currentPage.value?.elements || []).forEach((item) => {
  32. if(item.componentType === 'group') {
  33. item.children?.forEach((child) => {
  34. child.container.props.x += item.container.props.x;
  35. child.container.props.y += item.container.props.y;
  36. list.push(child);
  37. });
  38. } else {
  39. list.push(item);
  40. }
  41. });
  42. return list;
  43. });
  44. // 页面样式
  45. const getWapperStyle = () => {
  46. if (!currentPage.value) return;
  47. const { background } = currentPage.value;
  48. const pageBackground =
  49. background.type === "color"
  50. ? { background: background.color }
  51. : {
  52. background: `url(${background.image}) no-repeat center center`,
  53. backgroundSize: background.fillType,
  54. };
  55. const { width = 1280, height = 720 } = projectInfo;
  56. const { clientWidth, clientHeight } = document.documentElement;
  57. let scale: string | number = 1;
  58. switch (projectInfo.fillType) {
  59. case ScreenFillEnum.FILL_HEIGHT:
  60. scale = clientHeight / height;
  61. break;
  62. case ScreenFillEnum.FILL_WIDTH:
  63. scale = clientWidth / width;
  64. break;
  65. case ScreenFillEnum.FILL_BOTH:
  66. const scaleX = clientWidth / width;
  67. const scaleY = clientHeight / height;
  68. scale = `${scaleX},${scaleY}`;
  69. break;
  70. default:
  71. scale = Math.min(clientWidth / width, clientHeight / height);
  72. }
  73. bodyStyle.value = {
  74. background: '#000',
  75. } as unknown as StyleValue;
  76. pageWapperStyle.value = {
  77. position: 'absolute',
  78. left: '50%',
  79. top: '50%',
  80. width: `${width}px`,
  81. height: `${height}px`,
  82. overflow: "hidden",
  83. // border: "1px solid #f0f0f0",
  84. boxShadow: "0 0 10px rgba(0, 0, 0, 0.1)",
  85. transform: `scale(${scale}) translate(-50%, -50%)`,
  86. transformOrigin: "0 0",
  87. ...pageBackground,
  88. } as unknown as StyleValue;
  89. };
  90. onMounted(() => {
  91. getWapperStyle();
  92. window.addEventListener("resize", getWapperStyle);
  93. });
  94. onBeforeUnmount(() => {
  95. window.removeEventListener("resize", getWapperStyle);
  96. });
  97. </script>
  98. <style lang="less" scoped>
  99. .player-page {
  100. height: 100%;
  101. width: 100%;
  102. position: fixed;
  103. overflow: hidden;
  104. }
  105. </style>