PointTrackApp / src /components /LabelingView.vue
2nzi's picture
first commit
b4f9490 verified
<template>
<div class="labeling-view">
<div class="labels-container" v-if="selectedObject">
<div class="label-options">
<div class="label-list">
<div
v-for="label in predefinedLabels"
:key="label.name"
class="label-item"
>
<button
class="label-btn"
:class="{ active: selectedObject.label === label.name }"
:style="{
backgroundColor: label.color,
border: selectedObject.label === label.name ? '3px solid #fff' : '3px solid transparent'
}"
@click="assignLabel(label.name)"
>
<span class="label-text">{{ label.name }}</span>
<span class="shortcut-key">{{ getShortcutKey(label.name) }}</span>
</button>
<input
type="color"
:value="label.color"
@input="updateLabelColor(label.name, $event.target.value)"
class="color-picker"
:title="`Changer la couleur de ${label.name}`"
/>
</div>
</div>
</div>
</div>
<div v-else class="no-object-message">
<p>Sélectionnez un objet dans la timeline pour lui attribuer un label</p>
</div>
</div>
</template>
<script>
import { useAnnotationStore } from '@/stores/annotationStore'
export default {
name: 'LabelingView',
data() {
return {
predefinedLabels: [
{ name: 'Player Team 1', color: '#dc3545' },
{ name: 'Player Team 2', color: '#000000' },
{ name: 'Ball', color: '#28a745' }
]
}
},
setup() {
const annotationStore = useAnnotationStore()
return {
annotationStore
}
},
mounted() {
// Ajouter l'écouteur d'événement clavier
window.addEventListener('keydown', this.handleKeyPress)
},
beforeUnmount() {
// Supprimer l'écouteur d'événement clavier
window.removeEventListener('keydown', this.handleKeyPress)
},
computed: {
selectedObject() {
if (!this.annotationStore.selectedObjectId) return null
return this.annotationStore.objects[this.annotationStore.selectedObjectId]
}
},
methods: {
assignLabel(labelName) {
if (!this.selectedObject) return
// Mettre à jour l'objet avec le nouveau label
this.annotationStore.objects[this.selectedObject.id] = {
...this.selectedObject,
label: labelName
}
console.log(`Label "${labelName}" assigné à l'objet ${this.selectedObject.name}`)
},
updateLabelColor(labelName, newColor) {
const labelIndex = this.predefinedLabels.findIndex(label => label.name === labelName)
if (labelIndex !== -1) {
this.predefinedLabels[labelIndex].color = newColor
}
},
removeLabel() {
if (!this.selectedObject) return
// Supprimer le label de l'objet
const updatedObject = { ...this.selectedObject }
delete updatedObject.label
this.annotationStore.objects[this.selectedObject.id] = updatedObject
console.log(`Label supprimé de l'objet ${this.selectedObject.name}`)
},
getLabelColor(labelName) {
const predefinedLabel = this.predefinedLabels.find(label => label.name === labelName)
return predefinedLabel ? predefinedLabel.color : '#6c757d'
},
getShortcutKey(labelName) {
const shortcuts = {
'Player Team 1': '1',
'Player Team 2': '2',
'Ball': '3'
}
return shortcuts[labelName] || ''
},
handleKeyPress(event) {
// Vérifier que nous ne sommes pas dans un champ de saisie
if (event.target.tagName === 'INPUT' || event.target.tagName === 'TEXTAREA') {
return
}
// Vérifier qu'un objet est sélectionné
if (!this.selectedObject) {
return
}
// Gérer les raccourcis clavier
switch(event.key) {
case '1':
event.preventDefault()
this.assignLabel('Player Team 1')
break
case '2':
event.preventDefault()
this.assignLabel('Player Team 2')
break
case '3':
event.preventDefault()
this.assignLabel('Ball')
break
}
}
}
}
</script>
<style scoped>
.labeling-view {
height: 100%;
padding: 16px;
color: white;
overflow-y: auto;
}
.labels-container {
display: flex;
flex-direction: column;
gap: 20px;
}
.label-list {
display: flex;
flex-direction: column;
gap: 8px;
}
.label-item {
display: flex;
align-items: center;
gap: 8px;
}
.label-btn {
flex: 1;
padding: 8px 12px;
border-radius: 4px;
color: white;
font-size: 0.8rem;
font-weight: 500;
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
}
.label-btn:hover {
opacity: 0.8;
transform: translateY(-1px);
}
.label-btn.active {
box-shadow: 0 0 0 1px #fff;
}
.color-picker {
width: 32px;
height: 32px;
border: none;
border-radius: 4px;
cursor: pointer;
background: none;
padding: 0;
}
.color-picker::-webkit-color-swatch-wrapper {
padding: 0;
border-radius: 4px;
}
.color-picker::-webkit-color-swatch {
border: none;
border-radius: 4px;
}
.label-text {
flex: 1;
text-align: left;
}
.shortcut-key {
background-color: rgba(255, 255, 255, 0.2);
border-radius: 3px;
padding: 2px 6px;
font-size: 11px;
font-weight: bold;
min-width: 16px;
text-align: center;
}
.no-object-message {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
text-align: center;
}
.no-object-message p {
color: #999;
font-style: italic;
}
</style>