aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/App.vue44
-rw-r--r--src/components/TimeLine.vue26
-rw-r--r--src/components/icon/MinusIcon.vue6
-rw-r--r--src/components/icon/PlusIcon.vue7
4 files changed, 72 insertions, 11 deletions
diff --git a/src/App.vue b/src/App.vue
index 73d74aa..cfd9084 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -5,26 +5,40 @@
<h1 class="my-auto ml-2 text-4xl">Histplorer</h1>
<div class="mx-auto"/> <!-- Spacer -->
<!-- Icons -->
- <icon-button :size="45" class="text-stone-50 bg-yellow-600">
- <help-icon/>
+ <icon-button :size="45" class="text-stone-50 bg-yellow-600" @click="onTimelineAdd" title="Add a timeline">
+ <plus-icon/>
</icon-button>
<icon-button :size="45" class="text-stone-50 bg-yellow-600">
<settings-icon/>
</icon-button>
+ <icon-button :size="45" class="text-stone-50 bg-yellow-600">
+ <help-icon/>
+ </icon-button>
</div>
<!-- Content area -->
- <div class="grow min-h-0 bg-stone-800" ref="contentAreaRef">
- <time-line :width="contentWidth" :height="contentHeight" :vert="contentHeight > contentWidth"/>
+ <div class="grow min-h-0 bg-stone-800 relative" ref="contentAreaRef">
+ <time-line v-for="(data, idx) in timelineData" :key="data"
+ :style="{
+ position: 'absolute',
+ top: (vert ? 0 : idx * contentHeight / timelineData.length) + 'px',
+ left: (vert ? idx * contentWidth / timelineData.length : 0) + 'px',
+ outline: 'black solid 1px',
+ }"
+ :width="vert ? contentWidth / timelineData.length : contentWidth"
+ :height="vert ? contentHeight : contentHeight / timelineData.length"
+ :vert="vert"
+ @close="onTimelineClose(idx)"/>
</div>
</div>
</template>
<script setup lang="ts">
-import {ref, onMounted, onUnmounted} from 'vue';
+import {ref, computed, onMounted, onUnmounted} from 'vue';
// Components
import TimeLine from './components/TimeLine.vue';
import IconButton from './components/IconButton.vue';
// Icons
+import PlusIcon from './components/icon/PlusIcon.vue';
import SettingsIcon from './components/icon/SettingsIcon.vue';
import HelpIcon from './components/icon/HelpIcon.vue';
@@ -41,6 +55,25 @@ function updateAreaDims(){
}
onMounted(updateAreaDims)
+// For multiple timelines
+const vert = computed(() => contentHeight.value > contentWidth.value);
+const timelineData = ref([{}]);
+function onTimelineAdd(){
+ if (vert.value && contentWidth.value / (timelineData.value.length + 1) < 150 ||
+ !vert.value && contentHeight.value / (timelineData.value.length + 1) < 150){
+ console.log('Reached timeline min size');
+ return;
+ }
+ timelineData.value.push({});
+}
+function onTimelineClose(idx: number){
+ if (timelineData.value.length == 1){
+ console.log('Ignored close for last timeline')
+ return;
+ }
+ timelineData.value.splice(idx, 1);
+}
+
// For resize handling
let lastResizeHdlrTime = 0; // Used to throttle resize handling
let afterResizeHdlr = 0; // Used to trigger handler after ending a run of resize events
@@ -65,5 +98,4 @@ async function onResize(){
}
onMounted(() => window.addEventListener('resize', onResize));
onUnmounted(() => window.removeEventListener('resize', onResize));
-
</script>
diff --git a/src/components/TimeLine.vue b/src/components/TimeLine.vue
index 58e2fbc..187d915 100644
--- a/src/components/TimeLine.vue
+++ b/src/components/TimeLine.vue
@@ -1,13 +1,14 @@
<template>
-<div class="touch-none" :width="width" :height="height"
+<div class="touch-none relative"
+ :style="{minWidth: width + 'px', maxWidth: width + 'px', maxHeight: height + 'px', minHeight: height + 'px'}"
@wheel.exact.prevent="onWheel" @wheel.shift.exact.prevent="onShiftWheel"
@pointerdown.prevent="onPointerDown" @pointermove.prevent="onPointerMove" @pointerup.prevent="onPointerUp"
@pointercancel.prevent="onPointerUp" @pointerout.prevent="onPointerUp" @pointerleave.prevent="onPointerUp"
ref="rootRef">
- <svg :viewBox="`0 0 ${width} ${height}`">
+ <svg :viewBox="`0 0 ${width} ${height}`" width="100%" height="100%">
<line stroke="yellow" stroke-width="2px"
- :x1="vert2 ? '50%' : 0" :y1="vert2 ? 0 : '50%'"
- :x2="vert2 ? '50%' : '100%'" :y2="vert2 ? '100%' : '50%'"/>
+ :x1="vert2 ? width/2 : 0" :y1="vert2 ? 0 : height/2"
+ :x2="vert2 ? width/2 : width" :y2="vert2 ? height : height/2"/>
<template v-for="n in ticks" :key="n">
<line v-if="n == MIN_DATE || n == MAX_DATE"
:x1="vert2 ? -END_TICK_SZ : 0" :y1="vert2 ? 0 : -END_TICK_SZ"
@@ -24,21 +25,31 @@
{{n}}
</text>
</svg>
+ <!-- Icons -->
+ <icon-button :size="30" class="absolute bottom-2 right-2 text-stone-50 bg-yellow-600"
+ @click="onClose" title="Remove timeline">
+ <minus-icon/>
+ </icon-button>
</div>
</template>
<script setup lang="ts">
import {ref, onMounted, computed, watch, nextTick} from 'vue';
+// Components
+import IconButton from './IconButton.vue';
+// Icons
+import MinusIcon from './icon/MinusIcon.vue';
// Refs
const rootRef = ref(null as HTMLElement | null);
-// Props
+// Props + events
const props = defineProps({
width: {type: Number, required: true},
height: {type: Number, required: true},
vert: {type: Boolean, default: false},
});
+const emit = defineEmits(['close']);
// Vars
const MIN_DATE = -1000; // Lowest date that gets marked
@@ -336,6 +347,11 @@ function onShiftWheel(evt: WheelEvent){
}
}
+// For button handling
+function onClose(){
+ emit('close');
+}
+
// Styles
function tickStyles(tick: number){
let offset = (tick - startDate.value) / (endDate.value - startDate.value) * availLen.value;
diff --git a/src/components/icon/MinusIcon.vue b/src/components/icon/MinusIcon.vue
new file mode 100644
index 0000000..d316073
--- /dev/null
+++ b/src/components/icon/MinusIcon.vue
@@ -0,0 +1,6 @@
+<template>
+<svg viewBox="0 0 24 24"
+ fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+ <line x1="5" y1="12" x2="19" y2="12"/>
+</svg>
+</template>
diff --git a/src/components/icon/PlusIcon.vue b/src/components/icon/PlusIcon.vue
new file mode 100644
index 0000000..e06ba79
--- /dev/null
+++ b/src/components/icon/PlusIcon.vue
@@ -0,0 +1,7 @@
+<template>
+<svg viewBox="0 0 24 24"
+ fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
+ <line x1="12" y1="5" x2="12" y2="19"/>
+ <line x1="5" y1="12" x2="19" y2="12"/>
+</svg>
+</template>