From 4aa28afe7bead19f633e2ce8829a66b7c65ea746 Mon Sep 17 00:00:00 2001
From: Terry Truong <terry06890@gmail.com>
Date: Mon, 10 Oct 2022 21:47:32 +1100
Subject: Prevent span-regions in baseline becoming too small to see

---
 src/components/BaseLine.vue | 40 +++++++++++++++++++++++++++++++---------
 1 file changed, 31 insertions(+), 9 deletions(-)

(limited to 'src/components/BaseLine.vue')

diff --git a/src/components/BaseLine.vue b/src/components/BaseLine.vue
index 84a3846..6f2dbc9 100644
--- a/src/components/BaseLine.vue
+++ b/src/components/BaseLine.vue
@@ -1,11 +1,11 @@
 <template>
-<div class="bg-stone-900 text-stone-50 flex relative" :class="{'flex-col': vert}">
+<div class="bg-stone-900 text-stone-50 flex relative" :class="{'flex-col': vert}" ref="rootRef">
 	<div v-for="p in periods" :key="p.label" :style="periodStyles(p)">
 		<div :style="labelStyles">{{p.label}}</div>
 	</div>
 	<TransitionGroup name="fade">
 		<div v-for="d in timelineData" :key="d.id"
-			class="absolute bg-yellow-200/50" :style="spanStyles(d)">
+			class="absolute bg-yellow-200/30" :style="spanStyles(d)">
 			{{d.id}}
 		</div>
 	</TransitionGroup>
@@ -13,9 +13,12 @@
 </template>
 
 <script setup lang="ts">
-import {ref, computed} from 'vue';
+import {ref, computed, onMounted} from 'vue';
 import {MIN_DATE, MAX_DATE} from '../lib';
 
+// Refs
+const rootRef = ref(null as HTMLElement | null);
+
 // Props
 const props = defineProps({
 	vert: {type: Boolean, required: true},
@@ -29,6 +32,21 @@ const periods = ref([
 	{label: 'Three', len: 1},
 ]);
 
+// For size tracking
+const width = ref(0);
+const height = ref(0);
+const WRITING_MODE_HORZ = window.getComputedStyle(document.body)['writing-mode'].startsWith('horizontal');
+const resizeObserver = new ResizeObserver((entries) => {
+	for (const entry of entries){
+		if (entry.contentBoxSize){
+			const boxSize = Array.isArray(entry.contentBoxSize) ? entry.contentBoxSize[0] : entry.contentBoxSize;
+			width.value = WRITING_MODE_HORZ ? boxSize.inlineSize : boxSize.blockSize;
+			height.value = WRITING_MODE_HORZ ? boxSize.blockSize : boxSize.inlineSize;
+		}
+	}
+});
+onMounted(() => resizeObserver.observe(rootRef.value as HTMLElement));
+
 // Styles
 function periodStyles(period){
 	return {
@@ -44,21 +62,25 @@ const labelStyles: Record<string,string> = computed(() => ({
 }));
 function spanStyles(d){
 	let styles: Record<string,string>;
-	let beforeFrac = Math.max(0, (d.start - MIN_DATE) / (MAX_DATE - MIN_DATE)); // Clip at zero due to end-padding
-	let lenFrac = Math.min(1 - beforeFrac, (d.end - d.start) / (MAX_DATE - MIN_DATE));
+	let availLen = props.vert ? height.value : width.value;
+	let startFrac = (d.start - MIN_DATE) / (MAX_DATE - MIN_DATE);
+	let lenFrac = (d.end - d.start) / (MAX_DATE - MIN_DATE);
+	let startPx = Math.max(0, availLen * startFrac); // Prevent negatives due to end-padding
+	let lenPx = Math.min(availLen - startPx, availLen * lenFrac);
+	lenPx = Math.max(1, lenPx);
 	if (props.vert){
 		styles = {
-			top: beforeFrac * 100 + '%',
+			top: startPx + 'px',
 			left: 0,
-			height: lenFrac * 100 + '%',
+			height: lenPx + 'px',
 			width: '100%',
 		}
 	} else {
 		styles = {
 			top: 0,
-			left: beforeFrac * 100 + '%',
+			left: startPx + 'px',
 			height: '100%',
-			width: lenFrac * 100 + '%',
+			width: lenPx + 'px',
 		}
 	}
 	return {
-- 
cgit v1.2.3

