Spaces:
Running
Running
| <template> | |
| <div class="zoom-section"> | |
| <div class="zoom-header"> | |
| <div class="view-navigation"> | |
| <button | |
| class="nav-button" | |
| @click="previousView" | |
| > | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"> | |
| <path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"/> | |
| </svg> | |
| </button> | |
| <span class="view-indicator"> | |
| {{ currentViewIndex + 1 }} / {{ views.length }} | |
| </span> | |
| <button | |
| class="nav-button" | |
| @click="nextView" | |
| > | |
| <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"> | |
| <path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/> | |
| </svg> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="zoom-content"> | |
| <transition :name="transitionName" mode="out-in"> | |
| <component | |
| :is="currentView.component" | |
| :key="currentViewIndex" | |
| class="view-content" | |
| /> | |
| </transition> | |
| </div> | |
| </div> | |
| </template> | |
| <script> | |
| import { useAnnotationStore } from '@/stores/annotationStore' | |
| import { computed } from 'vue' | |
| import ZoomView from './ZoomView.vue' | |
| import AnnotationsRawView from './AnnotationsRawView.vue' | |
| export default { | |
| name: 'ZoomSection', | |
| components: { | |
| ZoomView, | |
| AnnotationsRawView | |
| }, | |
| setup() { | |
| const annotationStore = useAnnotationStore() | |
| const objectName = computed(() => { | |
| if (!annotationStore.selectedObjectId) return 'Aucun objet sélectionné' | |
| return annotationStore.objects[annotationStore.selectedObjectId]?.name || | |
| annotationStore.selectedObjectId | |
| }) | |
| return { | |
| objectName | |
| } | |
| }, | |
| data() { | |
| return { | |
| currentViewIndex: 0, | |
| transitionName: 'slide-right', | |
| views: [ | |
| { | |
| name: 'Zoom', | |
| component: 'ZoomView' | |
| }, | |
| { | |
| name: 'Raw Annotations', | |
| component: 'AnnotationsRawView' | |
| } | |
| ] | |
| } | |
| }, | |
| computed: { | |
| currentView() { | |
| return this.views[this.currentViewIndex] | |
| } | |
| }, | |
| methods: { | |
| nextView() { | |
| this.transitionName = 'slide-right' | |
| this.currentViewIndex = (this.currentViewIndex + 1) % this.views.length | |
| }, | |
| previousView() { | |
| this.transitionName = 'slide-left' | |
| this.currentViewIndex = this.currentViewIndex === 0 | |
| ? this.views.length - 1 | |
| : this.currentViewIndex - 1 | |
| } | |
| } | |
| } | |
| </script> | |
| <style scoped> | |
| .zoom-section { | |
| width: 100%; | |
| height: 100%; | |
| background: #2c2c2c; | |
| border-radius: 8px; | |
| display: flex; | |
| flex-direction: column; | |
| overflow: hidden; | |
| } | |
| .zoom-header { | |
| padding: 8px 12px; | |
| background: #3c3c3c; | |
| border-bottom: 1px solid #4a4a4a; | |
| display: flex; | |
| justify-content: center; | |
| align-items: center; | |
| } | |
| .view-navigation { | |
| display: flex; | |
| align-items: center; | |
| gap: 8px; | |
| } | |
| .nav-button { | |
| background: #4a4a4a; | |
| border: none; | |
| border-radius: 4px; | |
| color: white; | |
| width: 24px; | |
| height: 24px; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| cursor: pointer; | |
| transition: all 0.2s; | |
| } | |
| .nav-button:hover:not(:disabled) { | |
| background: #5a5a5a; | |
| } | |
| .view-indicator { | |
| color: #ccc; | |
| font-size: 0.8rem; | |
| min-width: 40px; | |
| text-align: center; | |
| } | |
| .zoom-content { | |
| flex: 1; | |
| position: relative; | |
| overflow: hidden; | |
| } | |
| .view-content { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| bottom: 0; | |
| } | |
| /* Animations de transition */ | |
| .slide-right-enter-active, .slide-right-leave-active, | |
| .slide-left-enter-active, .slide-left-leave-active { | |
| transition: transform 0.3s ease; | |
| } | |
| /* Animation vers la droite */ | |
| .slide-right-enter-from { | |
| transform: translateX(100%); | |
| } | |
| .slide-right-leave-to { | |
| transform: translateX(-100%); | |
| } | |
| /* Animation vers la gauche */ | |
| .slide-left-enter-from { | |
| transform: translateX(-100%); | |
| } | |
| .slide-left-leave-to { | |
| transform: translateX(100%); | |
| } | |
| </style> |