diff options
Diffstat (limited to 'src/components/BaseLine.vue')
| -rw-r--r-- | src/components/BaseLine.vue | 27 |
1 files changed, 19 insertions, 8 deletions
diff --git a/src/components/BaseLine.vue b/src/components/BaseLine.vue index f3a9e93..3cca6d7 100644 --- a/src/components/BaseLine.vue +++ b/src/components/BaseLine.vue @@ -1,11 +1,13 @@ <template> <div class="flex relative" :class="{'flex-col': vert}" :style="{color: store.color.text}" ref="rootRef"> + <!-- Time periods --> <div v-for="p in periods" :key="p.label" class="relative" :style="periodStyles(p)"> <div :style="labelStyles">{{p.label}}</div> <div v-if="props.vert" class="absolute bottom-0 w-full h-6" style="background-image: linear-gradient(to bottom, rgba(0,0,0,0), rgba(0,0,0,1))"></div> </div> + <!-- Timeline spans --> <TransitionGroup name="fade" v-if="mounted"> <div v-for="(state, idx) in timelines" :key="state.id" class="absolute" :style="spanStyles(idx)"></div> </TransitionGroup> @@ -17,20 +19,19 @@ import {ref, computed, onMounted, PropType, Ref} from 'vue'; import {MIN_DATE, MAX_DATE, SCALES, MONTH_SCALE, DAY_SCALE, WRITING_MODE_HORZ, TimelineState, stepDate} from '../lib'; import {useStore} from '../store'; -// Refs const rootRef = ref(null as HTMLElement | null); -// Global store const store = useStore(); -// Props const props = defineProps({ vert: {type: Boolean, required: true}, timelines: {type: Object as PropType<TimelineState[]>, required: true}, }); -// Static time periods +// ========== Static time periods ========== + type Period = {label: string, len: number}; + const periods: Ref<Period[]> = ref([ {label: 'Pre Hadean', len: 8}, {label: 'Hadean', len: 1}, @@ -39,20 +40,24 @@ const periods: Ref<Period[]> = ref([ {label: 'Phanerozoic', len: 0.5}, ]); -// For skipping transitions on startup +// ========== For skipping transitions on startup ========== + const skipTransition = ref(true); onMounted(() => setTimeout(() => {skipTransition.value = false}, 100)); -// For size and mount-status tracking +// ========== For size and mount-status tracking ========== + const width = ref(0); const height = ref(0); const mounted = ref(false); + onMounted(() => { let rootEl = rootRef.value!; width.value = rootEl.offsetWidth; height.value = rootEl.offsetHeight; mounted.value = true; }) + const resizeObserver = new ResizeObserver((entries) => { for (const entry of entries){ if (entry.contentBoxSize){ @@ -64,7 +69,8 @@ const resizeObserver = new ResizeObserver((entries) => { }); onMounted(() => resizeObserver.observe(rootRef.value as HTMLElement)); -// Styles +// ========== For styles ========== + function periodStyles(period: Period){ return { backgroundColor: store.color.bgDark2, @@ -73,17 +79,20 @@ function periodStyles(period: Period){ overflow: 'hidden', }; } + const labelStyles = computed((): Record<string, string> => ({ transform: props.vert ? 'rotate(90deg) translate(50%, 0)' : 'none', whiteSpace: 'nowrap', width: props.vert ? '40px' : 'auto', padding: props.vert ? '0' : '4px', })); + function spanStyles(stateIdx: number){ const state = props.timelines[stateIdx]; let styles: Record<string,string>; const availLen = props.vert ? height.value : width.value; const availBreadth = props.vert ? width.value : height.value; + // Determine start/end date if (state.startOffset == null || state.endOffset == null || state.scaleIdx == null){ return {display: 'none'}; @@ -95,6 +104,7 @@ function spanStyles(stateIdx: number){ stepDate(start, 1, {forward: false, count: Math.floor(state.startOffset * scale), inplace: true}); stepDate(end, 1, {count: Math.floor(state.endOffset * scale), inplace: true}); } + // Determine positions in full timeline (only uses year information) let startFrac = (start.year - MIN_DATE.year) / (MAX_DATE.year - MIN_DATE.year); let lenFrac = (end.year - start.year) / (MAX_DATE.year - MIN_DATE.year); @@ -104,10 +114,11 @@ function spanStyles(stateIdx: number){ lenPx = 3; startPx -= Math.max(0, startPx + lenPx - availLen); } + // Account for multiple timelines const breadth = availBreadth / props.timelines.length; const sidePx = breadth * stateIdx; - // + if (props.vert){ styles = { top: startPx + 'px', |
