diff options
| author | Terry Truong <terry06890@gmail.com> | 2023-01-07 19:24:12 +1100 |
|---|---|---|
| committer | Terry Truong <terry06890@gmail.com> | 2023-01-07 19:24:12 +1100 |
| commit | 4b323024f51a8de755e4fb6cab301c36d52132a3 (patch) | |
| tree | e9ba2e092fdb1782ca9f2703d48bc78711897f75 | |
| parent | 4175226e489e850b10b295d8c57bde39f332c4bc (diff) | |
Fix events sometimes not transitioning
For some reason, by updating elements of the idToPos map
individually, instead of assigning over the map itself, events
rendered from the map sometimes don't transition.
Also, skip transitions for events that would move across the
mainline.
| -rw-r--r-- | src/components/TimeLine.vue | 57 |
1 files changed, 41 insertions, 16 deletions
diff --git a/src/components/TimeLine.vue b/src/components/TimeLine.vue index e4fe8ba..9e0a48c 100644 --- a/src/components/TimeLine.vue +++ b/src/components/TimeLine.vue @@ -71,7 +71,7 @@ </template> <script setup lang="ts"> -import {ref, onMounted, onUnmounted, computed, watch, watchEffect, PropType, Ref, shallowRef, ShallowRef} from 'vue'; +import {ref, onMounted, onUnmounted, computed, watch, PropType, Ref} from 'vue'; // Components import IconButton from './IconButton.vue'; // Icons @@ -457,11 +457,15 @@ watch(idToEvent, () => { // Remove highlighting of search results that have beco searchEvent.value = null; } }); -const idToPos = computed(() => { +const idToPos: Ref<Map<number, [number, number, number, number]>> = ref(new Map()); // Maps event IDs to x/y/w/h +const idsToSkipTransition: Ref<Set<number>> = ref(new Set()); // Used to prevent events moving across mainline +type LineCoords = [number, number, number, number]; // x, y, length, angle +const eventLines: Ref<Map<number, LineCoords>> = ref(new Map()); // Maps event ID to event line data +function getEventLayout(): Map<number, [number, number, number, number]> { + let map: Map<number, [number, number, number, number]> = new Map(); if (!mounted.value){ - return new Map(); + return map; } - let map: Map<number, [number, number, number, number]> = new Map(); // Maps visible event IDs to x/y/l/h // Determine columns to place event elements in (or rows if !props.vert) let cols: [number, number][][] = []; // For each column, for each laid out event, stores an ID and pixel offset let colOffsets: number[] = []; // Stores the pixel offset of each column @@ -627,19 +631,38 @@ const idToPos = computed(() => { } } } - // Notify parent - emit('event-display', ID, [...map.keys()], firstDate.value, lastDate.value, minorScaleIdx.value); return map; -}); - -// For event lines -type LineCoords = [number, number, number, number]; -const eventLines: ShallowRef<Map<number, LineCoords>> = shallowRef(new Map()); - // Maps event ID to event line data (x, y, length, and angle) -watchEffect(() => { // Used instead of computed() in order to access old values +} +watch(idToEvent, () => { // Updates idToPos and eventLines + let map = getEventLayout(); + // Check for events that cross mainline + idsToSkipTransition.value.clear(); + for (let [eventId, [x, y, , ]] of map.entries()){ + if (idToPos.value.has(eventId)){ + let [oldX, oldY, , ] = idToPos.value.get(eventId)!; + if (props.vert && (oldX - mainlineOffset.value) * (x - mainlineOffset.value) < 0 + || !props.vert && (oldY - mainlineOffset.value) * (y - mainlineOffset.value) < 0){ + idsToSkipTransition.value.add(eventId); + } + } + } + // Update idToPos // Note: For some reason, if the map is assigned directly, events won't consistently transition + let toDelete = []; + for (let eventId of idToPos.value.keys()){ + if (!map.has(eventId)){ + toDelete.push(eventId); + } + } + for (let eventId of toDelete){ + idToPos.value.delete(eventId); + } + for (let [eventId, pos] of map.entries()){ + idToPos.value.set(eventId, pos); + } + // Update event lines let newEventLines: Map<number, LineCoords> = new Map(); let numUnits = getNumDisplayUnits(); - for (let [id, [eventX, eventY, eventW, eventH]] of idToPos.value){ + for (let [id, [eventX, eventY, eventW, eventH]] of map){ let x: number; // For line end on mainline let y: number; let x2: number; // For line end at event @@ -677,6 +700,8 @@ watchEffect(() => { // Used instead of computed() in order to access old values newEventLines.set(id, [x, y, l, a]); } eventLines.value = newEventLines; + // Notify parent + emit('event-display', ID, [...map.keys()], firstDate.value, lastDate.value, minorScaleIdx.value); }); // For event-count indicators @@ -1257,7 +1282,7 @@ function eventStyles(eventId: number){ top: y + 'px', width: w + 'px', height: h + 'px', - transitionProperty: skipTransition.value ? 'none' : 'all', + transitionProperty: (skipTransition.value || idsToSkipTransition.value.has(eventId)) ? 'none' : 'all', transitionDuration: store.transitionDuration + 'ms', transitionTimingFunction: 'ease-out', }; @@ -1279,7 +1304,7 @@ function eventLineStyles(eventId: number){ const [x, y, , a] = eventLines.value.get(eventId)!; return { transform: `translate(${x}px, ${y}px) rotate(${a}deg)`, - transitionProperty: skipTransition.value ? 'none' : 'transform', + transitionProperty: (skipTransition.value || idsToSkipTransition.value.has(eventId)) ? 'none' : 'transform', transitionDuration: store.transitionDuration + 'ms', transitionTimingFunction: 'ease-out', }; |
