modelAirDoorCSS.vue 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <template>
  2. <div class="air-door-container" @click="toggleDoor">
  3. <div class="tunnel">
  4. <!-- 巷道顶部 -->
  5. <div class="tunnel-top"></div>
  6. <!-- 巷道底部 -->
  7. <div class="tunnel-bottom"></div>
  8. <!-- 门框 -->
  9. <div class="door-frame"></div>
  10. <!-- 左右两扇门 -->
  11. <div class="doors-container">
  12. <!-- 左门 (向内开) -->
  13. <div
  14. class="door left-door"
  15. :class="{ 'open': isOpen }"
  16. ></div>
  17. <!-- 右门 (向外开) -->
  18. <div
  19. class="door right-door"
  20. :class="{ 'open': isOpen }"
  21. ></div>
  22. </div>
  23. </div>
  24. <div class="status">
  25. {{ isOpen ? '风门开启' : '风门关闭' }}
  26. </div>
  27. </div>
  28. </template>
  29. <script lang="ts" setup>
  30. import { ref } from 'vue';
  31. const isOpen = ref(false);
  32. const toggleDoor = () => {
  33. isOpen.value = !isOpen.value;
  34. };
  35. </script>
  36. <style scoped>
  37. .air-door-container {
  38. position: relative;
  39. width: 800px;
  40. height: 400px;
  41. margin: 0 auto;
  42. perspective: 1000px;
  43. }
  44. .tunnel {
  45. position: relative;
  46. width: 100%;
  47. height: 100%;
  48. transform-style: preserve-3d;
  49. }
  50. .tunnel-top {
  51. position: absolute;
  52. top: 0;
  53. left: 0;
  54. width: 100%;
  55. height: 120px;
  56. background: linear-gradient(to right, #222, #444, #222);
  57. border-radius: 400px 400px 0 0 / 60px 60px 0 0;
  58. }
  59. .tunnel-bottom {
  60. position: absolute;
  61. top: 120px;
  62. left: 0;
  63. width: 100%;
  64. height: 300px;
  65. /* background-image: linear-gradient(45deg, #333 25%, #444 25%, #444 50%, #333 50%, #333 75%, #444 75%, #444 100%); */
  66. background-size: 40px 40px;
  67. }
  68. .door-frame {
  69. position: absolute;
  70. top: 120px;
  71. left: 0;
  72. width: 100%;
  73. height: 300px;
  74. border: 8px solid #8B4513;
  75. border-radius: 0 0 20px 20px / 0 0 10px 10px;
  76. box-sizing: border-box;
  77. z-index: 10;
  78. }
  79. .doors-container {
  80. position: absolute;
  81. top: 120px;
  82. left:0;
  83. width: 100%;
  84. height: 300px;
  85. transform-style: preserve-3d;
  86. z-index: 20;
  87. }
  88. .door {
  89. position: absolute;
  90. top: 8px;
  91. width: calc(50% - 8px);
  92. height: calc(100% - 16px);
  93. background-color: #A9A9A9;
  94. border: 2px solid #696969;
  95. box-sizing: border-box;
  96. transition: transform 2s ease;
  97. transform-origin: left center;
  98. transform-style: preserve-3d;
  99. }
  100. .left-door {
  101. left: 8px;
  102. /* border-radius: 0 0 0 10px / 0 0 0 5px; */
  103. }
  104. .right-door {
  105. right: 8px;
  106. /* border-radius: 0 0 10px 0 / 0 0 5px 0; */
  107. transform-origin: right center;
  108. }
  109. .door.open.left-door {
  110. transform: rotateY(-90deg);
  111. }
  112. .door.open.right-door {
  113. transform: rotateY(-90deg);
  114. }
  115. /* 门的纹理 */
  116. .door::before,
  117. .door::after {
  118. content: '';
  119. position: absolute;
  120. background-color: #696969;
  121. }
  122. .left-door::before {
  123. top: 10px;
  124. left: 37px;
  125. width: 1px;
  126. height: 100px;
  127. }
  128. .left-door::after {
  129. top: 40px;
  130. left: 10px;
  131. width: 130px;
  132. height: 1px;
  133. }
  134. .right-door::before {
  135. top: 10px;
  136. right: 37px;
  137. width: 1px;
  138. height: 100px;
  139. }
  140. .right-door::after {
  141. top: 40px;
  142. right: 10px;
  143. width: 130px;
  144. height: 1px;
  145. }
  146. .status {
  147. position: absolute;
  148. top: 10px;
  149. left: 0;
  150. width: 100%;
  151. text-align: center;
  152. font-size: 18px;
  153. font-weight: bold;
  154. color: #fff;
  155. text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
  156. }
  157. </style>