123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166 |
- <template>
- <div class="air-door-container" @click="toggleDoor">
- <!-- 添加3D变换专用包装器 -->
- <div class="svg-3d-wrapper">
- <svg viewBox="0 0 800 400" width="800" height="400">
- <!-- 定义渐变和图案 -->
- <defs>
- <linearGradient id="tunnelGradient" x1="0%" y1="0%" x2="100%" y2="0%">
- <stop offset="0%" stop-color="#222" />
- <stop offset="50%" stop-color="#444" />
- <stop offset="100%" stop-color="#222" />
- </linearGradient>
- <pattern id="tunnelBottomPattern" width="40" height="40" patternUnits="userSpaceOnUse">
- <!-- <rect width="40" height="40" fill="#333" fill-opacity="0.8" /> -->
- </pattern>
- </defs>
-
- <!-- 巷道顶部 - 只有左上和右上圆角 -->
- <path d="M0,20 A20,20 0 0 1 20,0 H780 A20,20 0 0 1 800,20 V120 H0 Z"
- fill="url(#tunnelGradient)" />
-
- <!-- 巷道底部 -->
- <rect x="0" y="120" width="800" height="300" fill="url(#tunnelBottomPattern)" />
-
- <!-- 门框 -->
- <rect x="8" y="128" width="784" height="272" rx="20" ry="10" fill="none" stroke="#8B4513" stroke-width="8" />
-
- <!-- 左门 -->
- <g
- :class="{ 'left-door-open': isOpen, 'left-door-closed': !isOpen }"
- transform-origin="left center"
- >
- <rect
- x="16"
- y="136"
- width="384"
- height="256"
- fill="#A9A9A9"
- stroke="#696969"
- stroke-width="2"
- />
- <line x1="200" y1="146" x2="200" y2="392" stroke="#696969" stroke-width="1" />
- <line x1="16" y1="264" x2="399" y2="264" stroke="#696969" stroke-width="1" />
- </g>
-
- <!-- 右门 -->
- <g
- :class="{ 'right-door-open': isOpen, 'right-door-closed': !isOpen }"
- transform-origin="right center"
- >
- <rect
- x="400"
- y="136"
- width="384"
- height="256"
- fill="#A9A9A9"
- stroke="#696969"
- stroke-width="2"
- />
- <line x1="584" y1="146" x2="584" y2="392" stroke="#696969" stroke-width="1" />
- <line x1="400" y1="264" x2="783" y2="264" stroke="#696969" stroke-width="1" />
- </g>
- </svg>
- </div>
- <div class="status">
- {{ isOpen ? '风门开启' : '风门关闭' }}
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { ref } from 'vue';
- const isOpen = ref(false);
- const toggleDoor = () => {
- isOpen.value = !isOpen.value;
- };
- </script>
- <style scoped>
- .air-door-container {
- position: relative;
- width: 800px;
- height: 400px;
- margin: 0 auto;
- }
- .svg-3d-wrapper {
- width: 100%;
- height: 100%;
- perspective: 800px; /* 透视距离 */
- transform-style: preserve-3d;
- }
- svg {
- display: block;
- overflow: visible; /* 确保旋转内容不被裁剪 */
- transform-style: preserve-3d;
- }
- /* 门元素3D优化 */
- g {
- transform-box: fill-box;
- backface-visibility: visible;
- will-change: transform; /* 性能优化 */
- }
- /* 左门打开动画 */
- @keyframes leftDoorOpen {
- from { transform: translateZ(1px) rotateY(0deg); }
- to { transform: translateZ(1px) rotateY(-75deg); }
- }
- /* 左门关闭动画 */
- @keyframes leftDoorClose {
- from { transform: translateZ(1px) rotateY(-75deg); }
- to { transform: translateZ(1px) rotateY(0deg); }
- }
- /* 右门打开动画 */
- @keyframes rightDoorOpen {
- from { transform: translateZ(1px) rotateY(0deg); }
- to { transform: translateZ(1px) rotateY(-75deg); }
- }
- /* 右门关闭动画 */
- @keyframes rightDoorClose {
- from { transform: translateZ(1px) rotateY(-75deg); }
- to { transform: translateZ(1px) rotateY(0deg); }
- }
- /* 左门打开状态 */
- .left-door-open {
- animation: leftDoorOpen 2s cubic-bezier(0.22, 1, 0.36, 1) forwards;
- }
- /* 左门关闭状态 */
- .left-door-closed {
- animation: leftDoorClose 2s cubic-bezier(0.22, 1, 0.36, 1) forwards;
- }
- /* 右门打开状态 */
- .right-door-open {
- animation: rightDoorOpen 2s cubic-bezier(0.22, 1, 0.36, 1) forwards;
- }
- /* 右门关闭状态 */
- .right-door-closed {
- animation: rightDoorClose 2s cubic-bezier(0.22, 1, 0.36, 1) forwards;
- }
- .status {
- position: absolute;
- top: 10px;
- left: 0;
- width: 100%;
- text-align: center;
- font-size: 18px;
- font-weight: bold;
- color: #fff;
- text-shadow: 1px 1px 2px rgba(0,0,0,0.5);
- pointer-events: none; /* 防止遮挡点击事件 */
- }
- </style>
|