aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/App.vue38
-rw-r--r--src/components/TutorialPane.vue70
2 files changed, 105 insertions, 3 deletions
diff --git a/src/App.vue b/src/App.vue
index 4a5efe8..66d9a9c 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -7,6 +7,7 @@ import TileInfoModal from './components/TileInfoModal.vue';
import HelpModal from './components/HelpModal.vue';
import SettingsModal from './components/SettingsModal.vue';
import SearchModal from './components/SearchModal.vue';
+import TutorialPane from './components/TutorialPane.vue';
// Icons
import HelpIcon from './components/icon/HelpIcon.vue';
import SearchIcon from './components/icon/SearchIcon.vue';
@@ -83,6 +84,9 @@ const defaultUiOpts = {
ancestryTileMargin: 5, //px (gap between detached-ancestor tiles)
infoModalImgSz: 200,
autoWaitTime: 500, //ms (time to wait between actions (with their transitions))
+ tutorialPaneSz: 200,
+ tutorialPaneBgColor: '#1c1917',
+ tutorialPaneTextColor: 'white',
// Timing related
tileChgDuration: 300, //ms (for tile move/expand/collapse)
clickHoldDuration: 400, //ms (duration after mousedown when a click-and-hold is recognised)
@@ -149,6 +153,9 @@ export default defineComponent({
pos[1] += this.uiOpts.ancestryBarSz;
}
}
+ if (this.tutorialOpen){
+ pos[1] += this.uiOpts.tutorialPaneSz;
+ }
return pos;
},
tileAreaDims(){
@@ -163,15 +170,32 @@ export default defineComponent({
dims[1] -= this.uiOpts.ancestryBarSz;
}
}
+ if (this.tutorialOpen){
+ dims[1] -= this.uiOpts.tutorialPaneSz;
+ }
return dims;
},
+ ancestryBarPos(): [number, number] {
+ let pos = [0, 0];
+ if (this.tutorialOpen){
+ pos[1] += this.uiOpts.tutorialPaneSz;
+ }
+ return pos;
+ },
ancestryBarDims(): [number, number] {
if (this.wideArea){
- return [this.uiOpts.ancestryBarSz, this.height];
+ let dims = [this.uiOpts.ancestryBarSz, this.height];
+ if (this.tutorialOpen){
+ dims[1] -= this.uiOpts.tutorialPaneSz;
+ }
+ return dims;
} else {
return [this.width, this.uiOpts.ancestryBarSz];
}
},
+ tutorialPaneDims(): [number, number] {
+ return [this.width, this.uiOpts.tutorialPaneSz];
+ },
},
methods: {
// For tile expand/collapse events
@@ -530,6 +554,12 @@ export default defineComponent({
// Re-initialise tree
this.initTreeFromServer();
},
+ // For tutorial events
+ onTutorialClose(){
+ this.tutorialOpen = false;
+ tryLayout(this.activeRoot, this.tileAreaPos, this.tileAreaDims, this.lytOpts,
+ {allowCollapse: true, layoutMap: this.layoutMap});
+ },
// For other events
onResize(){
if (this.pendingResizeHdlr == 0){
@@ -606,7 +636,7 @@ export default defineComponent({
components: {
Tile, AncestryBar,
HelpIcon, SettingsIcon, SearchIcon, PlayIcon,
- TileInfoModal, HelpModal, SearchModal, SettingsModal,
+ TileInfoModal, HelpModal, SearchModal, SettingsModal, TutorialPane,
},
});
</script>
@@ -620,9 +650,11 @@ export default defineComponent({
@leaf-click-held="onLeafClickHeld" @nonleaf-click-held="onNonleafClickHeld"
@info-icon-click="onInfoIconClick"/>
<ancestry-bar v-if="detachedAncestors != null"
- :pos="[0,0]" :dims="ancestryBarDims" :nodes="detachedAncestors"
+ :pos="ancestryBarPos" :dims="ancestryBarDims" :nodes="detachedAncestors"
:tolMap="tolMap" :lytOpts="lytOpts" :uiOpts="uiOpts"
@detached-ancestor-click="onDetachedAncestorClick" @info-icon-click="onInfoIconClick"/>
+ <tutorial-pane v-if="tutorialOpen" :pos="[0,0]" :dims="tutorialPaneDims" :uiOpts="uiOpts"
+ @tutorial-close="onTutorialClose"/>
<!-- Icons -->
<help-icon @click="onHelpIconClick"
class="absolute bottom-[6px] right-[6px] w-[18px] h-[18px]
diff --git a/src/components/TutorialPane.vue b/src/components/TutorialPane.vue
new file mode 100644
index 0000000..97bb4cd
--- /dev/null
+++ b/src/components/TutorialPane.vue
@@ -0,0 +1,70 @@
+<script lang="ts">
+import {defineComponent, PropType} from 'vue';
+import CloseIcon from './icon/CloseIcon.vue';
+
+export default defineComponent({
+ props: {
+ pos: {type: Array as unknown as PropType<[number,number]>, required: true},
+ dims: {type: Array as unknown as PropType<[number,number]>, required: true},
+ uiOpts: {type: Object, required: true},
+ },
+ data(){
+ return {
+ stage: 0,
+ };
+ },
+ computed: {
+ styles(): Record<string,string> {
+ return {
+ position: 'absolute',
+ left: this.pos[0] + 'px',
+ top: this.pos[1] + 'px',
+ width: this.dims[0] + 'px',
+ height: this.dims[1] + 'px',
+ backgroundColor: this.uiOpts.tutorialPaneBgColor,
+ color: this.uiOpts.tutorialPaneTextColor,
+ };
+ },
+ },
+ methods: {
+ onCloseClick(evt: Event){
+ this.$emit('tutorial-close');
+ },
+ onTutorialStart(){
+ console.log("Start tutorial");
+ },
+ },
+ components: {CloseIcon, },
+ emits: ['tutorial-close', ],
+});
+</script>
+
+<template>
+<div :style="styles">
+ <close-icon @click.stop="onCloseClick" ref="closeIcon"
+ class="block absolute top-2 right-2 w-6 h-6 hover:cursor-pointer"/>
+ <div v-if="stage == 0" class="h-full flex flex-col justify-evenly">
+ <h1 class="px-4 text-center text-xl font-bold">Welcome</h1>
+ <div class="px-4 max-w-[15cm] mx-auto text-sm">
+ Lorem ipsum dolor sit amet, consectetur adipiscing
+ elit, sed do eiusmod tempor incididunt ut labore
+ et dolore magna aliqua. Ut enim ad minim veniam,
+ quis nostrud exercitation ullamco.
+ </div>
+ <div class="w-full flex justify-evenly">
+ <div>
+ <button class="w-full h-full px-4 py-2 rounded bg-stone-800 hover:bg-stone-700"
+ @click="onTutorialStart">
+ Start Tutorial
+ </button>
+ </div>
+ <div>
+ <button class="w-full h-full px-4 py-2 rounded bg-stone-800 hover:bg-stone-700"
+ @click="onCloseClick">
+ Continue
+ </button>
+ </div>
+ </div>
+ </div>
+</div>
+</template>