Renamed zone > map
This commit is contained in:
178
src/components/gameMaster/mapEditor/partials/Toolbar.vue
Normal file
178
src/components/gameMaster/mapEditor/partials/Toolbar.vue
Normal file
@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<div class="flex justify-center p-5">
|
||||
<div class="toolbar fixed bottom-0 left-0 m-3 rounded flex bg-gray solid border-solid border-2 border-gray-500 text-gray-300 p-1.5 px-3 h-10">
|
||||
<div ref="toolbar" class="tools flex gap-2.5" v-if="mapEditorStore.map">
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditorStore.tool === 'move' }" @click="handleClick('move')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/move.svg" alt="Move camera" /> <span class="h-5" :class="{ 'ml-2.5': mapEditorStore.tool !== 'move' }">(M)</span>
|
||||
</button>
|
||||
|
||||
<div class="w-px bg-cyan"></div>
|
||||
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditorStore.tool === 'pencil' }" @click="handleClick('pencil')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/pencil.svg" alt="Pencil" /> <span class="h-5" :class="{ 'ml-2.5': mapEditorStore.tool !== 'pencil' }">(P)</span>
|
||||
<div class="select" v-if="mapEditorStore.tool === 'pencil'">
|
||||
<div class="select-trigger group capitalize flex gap-3.5" :class="{ open: selectPencilOpen }">
|
||||
{{ mapEditorStore.drawMode }}
|
||||
<img class="group-[.open]:rotate-180 invert w-5 h-5 rotate-0 transition ease-in-out duration-200" src="/assets/icons/mapEditor/chevron.svg" />
|
||||
</div>
|
||||
<div class="flex flex-col absolute bottom-full mb-5 left-1/2 -translate-x-1/2 bg-gray rounded min-w-28 border border-gray-500 border-solid text-left" v-show="selectPencilOpen && mapEditorStore.tool === 'pencil'">
|
||||
<span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="setDrawMode('tile')">
|
||||
Tile
|
||||
<div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
|
||||
</span>
|
||||
<span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="setDrawMode('object')">
|
||||
Object
|
||||
<div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
|
||||
</span>
|
||||
<span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="setDrawMode('teleport')">
|
||||
Teleport
|
||||
<div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
|
||||
</span>
|
||||
<span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="setDrawMode('blocking tile')">Blocking tile</span>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div class="w-px bg-cyan"></div>
|
||||
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditorStore.tool === 'eraser' }" @click="handleClick('eraser')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/eraser.svg" alt="Eraser" /> <span class="h-5" :class="{ 'ml-2.5': mapEditorStore.tool !== 'eraser' }">(E)</span>
|
||||
<div class="select" v-if="mapEditorStore.tool === 'eraser'">
|
||||
<div class="select-trigger group capitalize flex gap-3.5" :class="{ open: selectEraserOpen }">
|
||||
{{ mapEditorStore.eraserMode }}
|
||||
<img class="group-[.open]:rotate-180 invert w-5 h-5 rotate-0 transition ease-in-out duration-200" src="/assets/icons/mapEditor/chevron.svg" />
|
||||
</div>
|
||||
<div class="flex flex-col absolute bottom-full mb-5 left-1/2 -translate-x-1/2 bg-gray rounded min-w-28 border border-gray-500 border-solid text-left" v-show="selectEraserOpen">
|
||||
<span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="setEraserMode('tile')">
|
||||
Tile
|
||||
<div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
|
||||
</span>
|
||||
<span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="setEraserMode('object')">
|
||||
Object
|
||||
<div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
|
||||
</span>
|
||||
<span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="setEraserMode('teleport')">
|
||||
Teleport
|
||||
<div class="absolute w-4/5 left-1/2 -translate-x-1/2 bottom-0 h-px bg-cyan"></div>
|
||||
</span>
|
||||
<span class="py-2 px-2.5 relative hover:bg-cyan hover:text-white" @click="setEraserMode('blocking tile')">Blocking tile</span>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
|
||||
<div class="w-px bg-cyan"></div>
|
||||
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" :class="{ 'border-0 border-b-[3px] border-solid border-cyan gap-2.5': mapEditorStore.tool === 'paint' }" @click="handleClick('paint')">
|
||||
<img class="invert w-5 h-5" src="/assets/icons/mapEditor/paint.svg" alt="Paint bucket" /> <span class="h-5" :class="{ 'ml-2.5': mapEditorStore.tool !== 'paint' }">(B)</span>
|
||||
</button>
|
||||
|
||||
<div class="w-px bg-cyan"></div>
|
||||
|
||||
<button class="flex justify-center items-center min-w-10 p-0 relative" @click="handleClick('settings')" v-if="mapEditorStore.map"><img class="invert w-5 h-5" src="/assets/icons/mapEditor/gear.svg" alt="Map settings" /> <span class="h-5 ml-2.5">(Z)</span></button>
|
||||
</div>
|
||||
|
||||
<div class="toolbar fixed bottom-0 right-0 m-3 rounded flex bg-gray solid border-solid border-2 border-gray-500 text-gray-300 p-1.5 px-3 h-10 space-x-2">
|
||||
<button class="btn-cyan px-3.5" @click="() => mapEditorStore.toggleMapListModal()">Load</button>
|
||||
<button class="btn-cyan px-3.5" @click="() => emit('save')" v-if="mapEditorStore.map">Save</button>
|
||||
<button class="btn-cyan px-3.5" @click="() => emit('clear')" v-if="mapEditorStore.map">Clear</button>
|
||||
<button class="btn-cyan px-3.5" @click="() => mapEditorStore.toggleActive()">Exit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useMapEditorStore } from '@/stores/mapEditorStore'
|
||||
import { onClickOutside } from '@vueuse/core'
|
||||
import { onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
|
||||
const mapEditorStore = useMapEditorStore()
|
||||
|
||||
const emit = defineEmits(['save', 'clear'])
|
||||
|
||||
// track when clicked outside of toolbar items
|
||||
const toolbar = ref(null)
|
||||
|
||||
// track select state
|
||||
let selectPencilOpen = ref(false)
|
||||
let selectEraserOpen = ref(false)
|
||||
|
||||
// drawMode
|
||||
function setDrawMode(value: string) {
|
||||
mapEditorStore.isTileListModalShown = value === 'tile'
|
||||
mapEditorStore.isObjectListModalShown = value === 'object'
|
||||
|
||||
mapEditorStore.setDrawMode(value)
|
||||
selectPencilOpen.value = false
|
||||
}
|
||||
|
||||
// drawMode
|
||||
function setEraserMode(value: string) {
|
||||
mapEditorStore.setEraserMode(value)
|
||||
selectEraserOpen.value = false
|
||||
}
|
||||
|
||||
function handleClick(tool: string) {
|
||||
if (tool === 'settings') {
|
||||
mapEditorStore.toggleSettingsModal()
|
||||
} else {
|
||||
mapEditorStore.setTool(tool)
|
||||
}
|
||||
|
||||
selectPencilOpen.value = tool === 'pencil' ? !selectPencilOpen.value : false
|
||||
selectEraserOpen.value = tool === 'eraser' ? !selectEraserOpen.value : false
|
||||
}
|
||||
|
||||
function cycleToolMode(tool: 'pencil' | 'eraser') {
|
||||
const modes = ['tile', 'object', 'teleport', 'blocking tile']
|
||||
const currentMode = tool === 'pencil' ? mapEditorStore.drawMode : mapEditorStore.eraserMode
|
||||
const currentIndex = modes.indexOf(currentMode)
|
||||
const nextIndex = (currentIndex + 1) % modes.length
|
||||
const nextMode = modes[nextIndex]
|
||||
|
||||
if (tool === 'pencil') {
|
||||
setDrawMode(nextMode)
|
||||
} else {
|
||||
setEraserMode(nextMode)
|
||||
}
|
||||
}
|
||||
|
||||
function initKeyShortcuts(event: KeyboardEvent) {
|
||||
// Check if map is set
|
||||
if (!mapEditorStore.map) return
|
||||
|
||||
// prevent if focused on composables
|
||||
if (document.activeElement?.tagName === 'INPUT') return
|
||||
|
||||
const keyActions: { [key: string]: string } = {
|
||||
m: 'move',
|
||||
p: 'pencil',
|
||||
e: 'eraser',
|
||||
b: 'paint',
|
||||
z: 'settings'
|
||||
}
|
||||
|
||||
if (keyActions.hasOwnProperty(event.key)) {
|
||||
const tool = keyActions[event.key]
|
||||
if ((tool === 'pencil' || tool === 'eraser') && mapEditorStore.tool === tool) {
|
||||
cycleToolMode(tool)
|
||||
} else {
|
||||
handleClick(tool)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleClickOutside() {
|
||||
selectPencilOpen.value = false
|
||||
selectEraserOpen.value = false
|
||||
}
|
||||
onClickOutside(toolbar, handleClickOutside)
|
||||
|
||||
onMounted(() => {
|
||||
addEventListener('keydown', initKeyShortcuts)
|
||||
})
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
removeEventListener('keydown', initKeyShortcuts)
|
||||
})
|
||||
</script>
|
Reference in New Issue
Block a user