diff options
| author | Terry Truong <terry06890@gmail.com> | 2022-10-19 13:28:56 +1100 |
|---|---|---|
| committer | Terry Truong <terry06890@gmail.com> | 2022-10-19 13:28:56 +1100 |
| commit | 8a0ed6a97837a5fb8faa10ab415759b445aaa2fe (patch) | |
| tree | 43ed3a82fae3d89bdcaae921d8b58532e174d65c /src/components/TimeLine.vue | |
| parent | bc272c3adbdf64f19aba905d9a9616ccf46ebf76 (diff) | |
Prevent jumps in event line angle transitions
Instead of directly using new angles, update old ones
Also prevent event lines from 'detaching' from the mainline during transitions
Also make events displayed in circles
Diffstat (limited to 'src/components/TimeLine.vue')
| -rw-r--r-- | src/components/TimeLine.vue | 48 |
1 files changed, 34 insertions, 14 deletions
diff --git a/src/components/TimeLine.vue b/src/components/TimeLine.vue index 77ef5cc..01561a1 100644 --- a/src/components/TimeLine.vue +++ b/src/components/TimeLine.vue @@ -33,7 +33,7 @@ </svg> <!-- Events --> <div v-for="id in idToPos.keys()" :key="id" - class="absolute bg-black text-white rounded animate-fadein text-sm" + class="absolute bg-black text-white rounded-full border border-amber-400 animate-fadein text-sm text-center" :style="eventStyles(id)"> {{idToEvent.get(id)!.title}} </div> @@ -47,7 +47,7 @@ </template> <script setup lang="ts"> -import {ref, onMounted, computed, watch, PropType, Ref} from 'vue'; +import {ref, onMounted, computed, watch, watchEffect, PropType, Ref, shallowRef, ShallowRef} from 'vue'; // Components import IconButton from './IconButton.vue'; // Icons @@ -329,30 +329,50 @@ const idToPos = computed(() => { // return map; }); -const eventLines = computed(() => { - let lineCoords: Map<number, [number, number, number, number]> = new Map(); - // Maps event ID to x, y, length, and angle +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 + let newEventLines: Map<number, LineCoords> = new Map(); let numUnits = getNumVisibleUnits(); for (let [id, [eventX, eventY, eventW, eventH]] of idToPos.value){ - let x = eventX + eventW/2; - let y = eventY + eventH/2; - let x2: number; + let x: number; // For line end on mainline + let y: number; + let x2: number; // For line end at event + // Note: Drawing the line in the reverse direction causes 'detachment' from the mainline during transitions let y2: number; let event = idToEvent.value.get(id)!; let unitOffset = getUnitDiff(event.start, startDate.value, scale.value) + startOffset.value; let posFrac = unitOffset / numUnits; if (props.vert){ - x2 = availBreadth.value / 2; - y2 = posFrac * availLen.value; + x = availBreadth.value / 2; + y = posFrac * availLen.value; } else { - x2 = posFrac * availLen.value; - y2 = availBreadth.value / 2; + x = posFrac * availLen.value; + y = availBreadth.value / 2; } + x2 = eventX + eventW/2; + y2 = eventY + eventH/2; let l = Math.sqrt((x-x2)**2 + (y-y2)**2); let a = Math.atan2(y2-y, x2-x) * 180 / Math.PI; - lineCoords.set(id, [x, y, l, a]); + if (eventLines.value.has(id)){ // Check if event had previous angle + let oldA = eventLines.value.get(id)![3]; + // Update old angle with difference, to avoid angle transition jumps (eg: change 170 to 185 instead of -175) + let rOldA = oldA >= 0 ? // oldA limited to -180 to 180 + (oldA % 180) + (Math.floor(oldA / 180) % 2 == 0 ? 0 : -180) : + (oldA % 180) + (Math.ceil(oldA / 180) % 2 == 0 ? 0 : 180); + let angleDiff = (a - rOldA) % 360; + if (angleDiff > 180){ + a = oldA - (360 - angleDiff); + } else if (angleDiff < -180){ + a = oldA + (360 + angleDiff); + } else { + a = oldA + angleDiff; + } + } + newEventLines.set(id, [x, y, l, a]); } - return lineCoords; + eventLines.value = newEventLines; }); // For panning/zooming |
