Changeset 35506 for main


Ignore:
Timestamp:
2021-09-28T12:14:10+13:00 (3 years ago)
Author:
cstephen
Message:

Improve WordTimingSelector logic and prevent invalid movement

Location:
main/trunk/model-interfaces-dev/atea/korero-maori-asr/src/components
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • main/trunk/model-interfaces-dev/atea/korero-maori-asr/src/components/TranscriptionItemEditor.vue

    r35492 r35506  
    2020    </div>
    2121
    22     <!-- <word-timing-selector class="word-timing-selector" :surroundingWords="surroundingWords" :word="selectedWord" /> -->
     22    <word-timing-selector class="word-timing-selector" :surroundingWords="surroundingWords" :word="selectedWord" />
    2323
    2424    <div class="editor-controls">
     
    8787import AudioPlayback from "../js/AudioPlaybackModule"
    8888import AudioTimeBar from "./AudioTimeBar.vue"
    89 // import WordTimingSelector from "./WordTimingSelector.vue"
     89import WordTimingSelector from "./WordTimingSelector.vue"
    9090import Util from "../js/Util";
    9191
     
    121121    name: "TranscriptionItemEditor",
    122122    components: {
    123         AudioTimeBar//,
    124         // WordTimingSelector
     123        AudioTimeBar,
     124        WordTimingSelector
    125125    },
    126126    props: {
  • main/trunk/model-interfaces-dev/atea/korero-maori-asr/src/components/WordTimingSelector.vue

    r35491 r35506  
    11<template>
    22<div class="word-timing-selector-root">
    3     <span>{{ minTime }}</span>
     3    <span>{{ minTimeString }}</span>
    44
    55    <div class="words-container" ref="wordsContainer">
     
    99        </div>
    1010
    11         <span v-if="isMounted" class="material-icons mdi-m word-handle" :style="{ left: leftHandleLeft }"
     11        <span v-if="isMounted" class="material-icons mdi-m word-handle" :style="{ left: leftHandleLeft }" :class="{ 'large-shift-handle': canShiftMinValue }"
    1212            @mousemove="onMinHandleMouseMove" @mouseup="onHandleMouseUp" @mousedown="canShiftMinValue = true">
    1313            first_page
     
    1616    </div>
    1717
    18     <span>{{ maxTime }}</span>
     18    <span>{{ maxTimeString }}</span>
    1919</div>
    2020</template>
     
    7373    top: -100%;
    7474    background-color: var(--highlighted-word-bg);
     75}
     76
     77.large-shift-handle {
     78    border: 100px solid transparent;
    7579}
    7680</style>
     
    8892        this.length = length;
    8993    }
     94
     95    right() {
     96        return this.left + this.length;
     97    }
    9098}
    9199
     
    109117    emits: [ "update:word" ],
    110118    computed: {
    111         minTime() {
     119        myWord() {
     120            console.log("updated");
     121            return this.convertWord(this.word);
     122        },
     123        minTimeString() {
    112124            if (this.surroundingWords.length === 0) {
    113125                return 0;
     
    116128            return Util.formatSecondsTimeString(this.surroundingWords[0].startTime, false, 2);
    117129        },
    118         maxTime() {
     130        maxTimeString() {
    119131            if (this.surroundingWords.length === 0) {
    120132                return 0;
     
    131143        wordIndex() {
    132144            return this.surroundingWords.indexOf(this.word);
     145        },
     146        audioSnippetLength() {
     147            return this.surroundingWords[this.surroundingWords.length - 1].endTime - this.surroundingWords[0].startTime;
     148        },
     149        /**
     150         * Gets the amount of pixel space in which words can be position on-screen.
     151         */
     152        wordSpacePx() {
     153            if (!this.isMounted) {
     154                return 0;
     155            }
     156            else {
     157                return this.$refs.wordsContainer.offsetWidth;
     158            }
     159        },
     160        /**
     161         * Gets the factor used to scale word's audio parameters into on-screen positional values.
     162         * @returns {Number} The scaling factor.
     163         */
     164        scalingFactor() {
     165            return this.wordSpacePx / this.audioSnippetLength;
     166        },
     167        /**
     168         * Gets the required pixel offset of a word's left position.
     169         * @returns {Number} The offset.
     170         */
     171        wordLeftOffsetPx() {
     172            return this.surroundingWords[0].startTime * this.scalingFactor;
    133173        }
    134174    },
    135175    watch: {
    136176        surroundingWords() {
    137             this.getMySurroundingWords();
     177            this.mySurroundingWords = this.convertSurroundingWords();
    138178        }
    139179    },
    140180    methods: {
    141         getMySurroundingWords() {
    142             if (!this.isMounted) {
    143                 return;
    144             }
    145 
     181        convertSurroundingWords() {
    146182            const myWords = [];
     183
    147184            if (this.surroundingWords.length === 0) {
    148185                return myWords;
    149186            }
    150187
    151             const audioLength = this.surroundingWords[this.surroundingWords.length - 1].endTime - this.surroundingWords[0].startTime;
    152             const sliderLengthPx = this.$refs.wordsContainer.offsetWidth;
    153 
    154             const scalingFactor = sliderLengthPx / audioLength;
    155 
    156             const offset = this.surroundingWords[0].startTime * scalingFactor;
    157 
    158188            for (const word of this.surroundingWords) {
    159                 const left = (word.startTime * scalingFactor - offset);
    160                 const length = (word.endTime - word.startTime) * scalingFactor;
    161 
    162                 myWords.push(new Word(word.word, word.startTime, word.endTime, left, length));
    163             }
    164 
    165             this.mySurroundingWords = myWords;
     189                myWords.push(this.convertWord(word));
     190            }
     191
     192            return myWords;
     193        },
     194        convertWord(word) {
     195            const left = (word.startTime * this.scalingFactor - this.wordLeftOffsetPx);
     196            const length = (word.endTime - word.startTime) * this.scalingFactor;
     197
     198            return new Word(word.word, word.startTime, word.endTime, left, length);
    166199        },
    167200        shouldHoist(word) {
     
    180213
    181214            const word = this.getWord();
     215
     216            if (event.movementX < 0 && word.left + event.movementX < 0) {
     217                return;
     218            }
     219
     220            if (event.movementX > 0 && word.left + event.movementX >= word.right()) {
     221                return;
     222            }
     223
    182224            word.left += event.movementX;
    183225            word.length -= event.movementX;
     
    189231
    190232            const word = this.getWord();
     233
     234            const lastWord = this.mySurroundingWords[this.mySurroundingWords.length - 1];
     235
     236            if (event.movementX > 0 && word.right() + event.movementX > lastWord.right()) {
     237                return;
     238            }
     239
     240            if (event.movementX < 0 && word.right() + event.movementX <= word.left) {
     241                return;
     242            }
     243
    191244            word.length += event.movementX;
    192245        },
     
    198251    mounted() {
    199252        this.isMounted = true;
    200         this.getMySurroundingWords();
     253        this.mySurroundingWords = this.convertSurroundingWords();
    201254    }
    202255}
Note: See TracChangeset for help on using the changeset viewer.