|
39 | 39 | </template>
|
40 | 40 |
|
41 | 41 | <script setup lang="ts">
|
42 |
| - import { computed, watch } from 'vue'; |
43 |
| -
|
44 |
| - import { useOpenCV } from './composables/useOpenCV'; |
45 |
| - import { useChessEngine } from './composables/useChessEngine'; |
46 |
| - import { useChessStore } from './stores/chess'; |
47 |
| - import { useImageProcessing } from './composables/useImageProcessing'; |
48 |
| -
|
49 |
| - import ImageUploader from './components/ImageUploader.vue'; |
50 |
| - import BoardResult from './components/BoardResult.vue'; |
51 |
| - import FENDisplay from './components/FENDisplay.vue'; |
52 |
| - import SolutionDisplay from './components/SolutionDisplay.vue'; |
53 |
| - import DepthControl from './components/DepthControl.vue'; |
54 |
| - import WelcomeModal from './components/WelcomeModal.vue'; |
55 |
| - import Spinner from './components/Spinner.vue'; |
56 |
| -
|
57 |
| - const { templates } = useOpenCV(); |
58 |
| - const { fetchBestMove, isEngineReady } = useChessEngine(); |
59 |
| - const isLoading = computed(() => { |
60 |
| - const templatesReady = !!templates.value; |
61 |
| - return !isEngineReady.value || !templatesReady; |
62 |
| - }); |
63 |
| -
|
64 |
| - const chessStore = useChessStore(); |
65 |
| -
|
66 |
| - watch( |
67 |
| - () => [chessStore.fenCode, chessStore.depth], |
68 |
| - () => { |
69 |
| - if (chessStore.fenCode) { |
70 |
| - fetchBestMove(chessStore.fenCode, chessStore.depth); |
71 |
| - } |
| 42 | +import { computed, watch } from 'vue'; |
| 43 | +
|
| 44 | +import { useOpenCV } from './composables/useOpenCV'; |
| 45 | +import { useChessEngine } from './composables/useChessEngine'; |
| 46 | +import { useChessStore } from './stores/chess'; |
| 47 | +import { useImageProcessing } from './composables/useImageProcessing'; |
| 48 | +
|
| 49 | +import ImageUploader from './components/ImageUploader.vue'; |
| 50 | +import BoardResult from './components/BoardResult.vue'; |
| 51 | +import FENDisplay from './components/FENDisplay.vue'; |
| 52 | +import SolutionDisplay from './components/SolutionDisplay.vue'; |
| 53 | +import DepthControl from './components/DepthControl.vue'; |
| 54 | +import WelcomeModal from './components/WelcomeModal.vue'; |
| 55 | +import Spinner from './components/Spinner.vue'; |
| 56 | +
|
| 57 | +const { templates } = useOpenCV(); |
| 58 | +const { fetchBestMove, isEngineReady } = useChessEngine(); |
| 59 | +const isLoading = computed(() => { |
| 60 | + const templatesReady = !!templates.value; |
| 61 | + return !isEngineReady.value || !templatesReady; |
| 62 | +}); |
| 63 | +
|
| 64 | +const chessStore = useChessStore(); |
| 65 | +
|
| 66 | +watch( |
| 67 | + () => [chessStore.fenCode, chessStore.depth], |
| 68 | + () => { |
| 69 | + if (chessStore.fenCode) { |
| 70 | + fetchBestMove(chessStore.fenCode, chessStore.depth); |
72 | 71 | }
|
73 |
| - ); |
| 72 | + } |
| 73 | +); |
74 | 74 |
|
75 |
| - const { processUploadedImage } = useImageProcessing(templates); |
| 75 | +const { processUploadedImage } = useImageProcessing(templates); |
76 | 76 |
|
77 |
| - const handleImageUpload = (img: HTMLImageElement) => { |
78 |
| - chessStore.resetHistory(); |
79 |
| - processUploadedImage(img); |
80 |
| - }; |
| 77 | +const handleImageUpload = (img: HTMLImageElement) => { |
| 78 | + chessStore.resetHistory(); |
| 79 | + processUploadedImage(img); |
| 80 | +}; |
81 | 81 | </script>
|
82 | 82 |
|
83 | 83 | <style scoped>
|
84 |
| - .app-container { |
85 |
| - flex: 1; |
86 |
| - display: flex; |
| 84 | +.app-container { |
| 85 | + flex: 1; |
| 86 | + display: flex; |
| 87 | + flex-direction: column; |
| 88 | + width: 100%; |
| 89 | + margin: 0 auto; |
| 90 | + padding: 0; |
| 91 | + box-sizing: border-box; |
| 92 | +} |
| 93 | +
|
| 94 | +.content-wrapper { |
| 95 | + display: flex; |
| 96 | + flex-wrap: wrap; |
| 97 | + gap: 2rem; |
| 98 | + width: 100%; |
| 99 | + max-width: 1200px; |
| 100 | + margin: 0 auto; |
| 101 | + padding: 0 1rem; |
| 102 | + box-sizing: border-box; |
| 103 | +} |
| 104 | +
|
| 105 | +.left-column, |
| 106 | +.right-column { |
| 107 | + width: 100%; |
| 108 | +} |
| 109 | +
|
| 110 | +.loading-overlay { |
| 111 | + position: fixed; |
| 112 | + top: 0; |
| 113 | + left: 0; |
| 114 | + width: 100%; |
| 115 | + height: 100%; |
| 116 | + background-color: rgba(255, 255, 255, 0.8); |
| 117 | + display: flex; |
| 118 | + flex-direction: column; |
| 119 | + justify-content: center; |
| 120 | + align-items: center; |
| 121 | + z-index: 9999; |
| 122 | +} |
| 123 | +
|
| 124 | +.loading-overlay p { |
| 125 | + margin-top: 20px; |
| 126 | + font-size: 1.2rem; |
| 127 | + color: #333; |
| 128 | +} |
| 129 | +
|
| 130 | +/* 媒体查询 */ |
| 131 | +@media (max-width: 768px) { |
| 132 | + .content-wrapper { |
87 | 133 | flex-direction: column;
|
88 |
| - width: 100%; |
89 |
| - margin: 0 auto; |
90 |
| - padding: 0; |
91 |
| - box-sizing: border-box; |
| 134 | + gap: 0; |
92 | 135 | }
|
93 | 136 |
|
94 |
| - .content-wrapper { |
95 |
| - display: flex; |
96 |
| - flex-wrap: wrap; |
97 |
| - gap: 2rem; |
98 |
| - width: 100%; |
99 |
| - max-width: 1200px; |
100 |
| - margin: 0 auto; |
101 |
| - padding: 0 1rem; |
102 |
| - box-sizing: border-box; |
| 137 | + .solution-section { |
| 138 | + order: 1; |
103 | 139 | }
|
104 |
| -
|
105 |
| - .left-column, |
106 |
| - .right-column { |
107 |
| - width: 100%; |
| 140 | + .upload-section { |
| 141 | + order: 0; |
108 | 142 | }
|
109 |
| -
|
110 |
| - .loading-overlay { |
111 |
| - position: fixed; |
112 |
| - top: 0; |
113 |
| - left: 0; |
114 |
| - width: 100%; |
115 |
| - height: 100%; |
116 |
| - background-color: rgba(255, 255, 255, 0.8); |
117 |
| - display: flex; |
118 |
| - flex-direction: column; |
119 |
| - justify-content: center; |
120 |
| - align-items: center; |
121 |
| - z-index: 9999; |
| 143 | + .board-result-section { |
| 144 | + order: 2; |
122 | 145 | }
|
123 |
| -
|
124 |
| - .loading-overlay p { |
125 |
| - margin-top: 20px; |
126 |
| - font-size: 1.2rem; |
127 |
| - color: #333; |
| 146 | + .fen-section { |
| 147 | + order: 3; |
128 | 148 | }
|
129 |
| -
|
130 |
| - /* 媒体查询 */ |
131 |
| - @media (max-width: 768px) { |
132 |
| - .content-wrapper { |
133 |
| - flex-direction: column; |
134 |
| - gap: 0; |
135 |
| - } |
136 |
| -
|
137 |
| - .solution-section { |
138 |
| - order: 1; |
139 |
| - } |
140 |
| - .upload-section { |
141 |
| - order: 0; |
142 |
| - } |
143 |
| - .board-result-section { |
144 |
| - order: 2; |
145 |
| - } |
146 |
| - .fen-section { |
147 |
| - order: 3; |
148 |
| - } |
149 |
| - .depth-control-section { |
150 |
| - order: 4; |
151 |
| - } |
| 149 | + .depth-control-section { |
| 150 | + order: 4; |
152 | 151 | }
|
| 152 | +} |
153 | 153 |
|
154 |
| - @media (min-width: 769px) { |
155 |
| - .content-wrapper { |
156 |
| - flex-direction: row; |
157 |
| - align-items: flex-start; |
158 |
| - } |
| 154 | +@media (min-width: 769px) { |
| 155 | + .content-wrapper { |
| 156 | + flex-direction: row; |
| 157 | + align-items: flex-start; |
| 158 | + } |
159 | 159 |
|
160 |
| - .left-column { |
161 |
| - width: calc(50% - 1rem); |
162 |
| - position: sticky; |
163 |
| - top: 1rem; |
164 |
| - align-self: flex-start; |
165 |
| - } |
| 160 | + .left-column { |
| 161 | + width: calc(50% - 1rem); |
| 162 | + position: sticky; |
| 163 | + top: 1rem; |
| 164 | + align-self: flex-start; |
| 165 | + } |
166 | 166 |
|
167 |
| - .right-column { |
168 |
| - width: calc(50% - 1rem); |
169 |
| - } |
| 167 | + .right-column { |
| 168 | + width: calc(50% - 1rem); |
| 169 | + } |
170 | 170 |
|
171 |
| - .solution-section { |
172 |
| - height: calc(100vh - 2rem); |
173 |
| - overflow-y: auto; |
174 |
| - order: -1; |
175 |
| - } |
| 171 | + .solution-section { |
| 172 | + height: calc(100vh - 2rem); |
| 173 | + overflow-y: auto; |
| 174 | + order: -1; |
176 | 175 | }
|
| 176 | +} |
177 | 177 | </style>
|
0 commit comments