forked from noxious/client
Added drag & resize logic to tileList and mapObjectList
This commit is contained in:
parent
04d55f994e
commit
8add054f63
@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div class="absolute border-0 border-l-2 border-solid border-gray-500 w-1/4 min-w-80 flex flex-col top-0 right-0 z-10 h-dvh bg-gray-800" v-if="isOpen">
|
||||
<div class="absolute border-0 border-l-2 border-solid border-gray-500 flex flex-col top-0 right-0 z-10 h-dvh bg-gray-800" :style="{ width: width + 'px' }" v-if="isOpen">
|
||||
<div class="absolute left-0 top-0 w-1 h-full cursor-ew-resize hover:bg-cyan transition-colors duration-200 z-50" @mousedown.stop="startResize"></div>
|
||||
<div class="relative z-10 p-2.5 border-solid border-0 border-b border-gray-500">
|
||||
<h3 class="text-lg text-white">Map objects</h3>
|
||||
</div>
|
||||
@ -47,11 +48,10 @@
|
||||
<script setup lang="ts">
|
||||
import config from '@/application/config'
|
||||
import type { MapObject } from '@/application/types'
|
||||
import Modal from '@/components/utilities/Modal.vue'
|
||||
import { useMapEditorComposable } from '@/composables/useMapEditorComposable'
|
||||
import { MapObjectStorage } from '@/storage/storages'
|
||||
import { liveQuery } from 'dexie'
|
||||
import { computed, onMounted, onUnmounted, ref, useTemplateRef } from 'vue'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
|
||||
const isOpen = ref(false)
|
||||
const mapObjectStorage = new MapObjectStorage()
|
||||
@ -60,6 +60,28 @@ const mapEditor = useMapEditorComposable()
|
||||
const searchQuery = ref('')
|
||||
const selectedTags = ref<string[]>([])
|
||||
const mapObjectList = ref<MapObject[]>([])
|
||||
const width = ref(320)
|
||||
const minWidth = 320
|
||||
const maxWidth = 800
|
||||
|
||||
const startResize = (event: MouseEvent) => {
|
||||
const startX = event.clientX
|
||||
const startWidth = width.value
|
||||
|
||||
const handleMouseMove = (e: MouseEvent) => {
|
||||
const delta = startX - e.clientX
|
||||
const newWidth = Math.min(Math.max(startWidth + delta, minWidth), maxWidth)
|
||||
width.value = newWidth
|
||||
}
|
||||
|
||||
const handleMouseUp = () => {
|
||||
document.removeEventListener('mousemove', handleMouseMove)
|
||||
document.removeEventListener('mouseup', handleMouseUp)
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', handleMouseMove)
|
||||
document.addEventListener('mouseup', handleMouseUp)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open: () => (isOpen.value = true),
|
||||
|
@ -1,28 +1,14 @@
|
||||
<template>
|
||||
<div class="absolute border-0 border-l-2 border-solid border-gray-500 w-1/4 min-w-80 flex flex-col top-0 right-0 z-10 h-dvh bg-gray-800" v-if="isOpen">
|
||||
<div class="absolute border-0 border-l-2 border-solid border-gray-500 flex flex-col top-0 right-0 z-10 h-dvh bg-gray-800" :style="{ width: width + 'px' }" v-if="isOpen">
|
||||
<div class="absolute left-0 top-0 w-1 h-full cursor-ew-resize hover:bg-cyan transition-colors duration-200 z-20" @mousedown.stop="startDragging"></div>
|
||||
<div class="relative z-10 p-2.5 border-solid border-0 border-b border-gray-500">
|
||||
<h3 class="text-lg text-white">Tiles</h3>
|
||||
</div>
|
||||
<div class="overflow-hidden grow relative">
|
||||
<div class="absolute top-0 left-0 h-full w-full">
|
||||
<div class="absolute w-full h-full top-0 left-0">
|
||||
<div class="relative z-10 h-full">
|
||||
<div class="h-full" v-if="!selectedGroup">
|
||||
<div class="flex pt-4 pl-4">
|
||||
<div class="w-full flex gap-1.5 flex-row">
|
||||
<div>
|
||||
<label class="mb-1.5 font-titles hidden" for="search">Search...</label>
|
||||
<input @mousedown.stop class="input-field" type="text" name="search" placeholder="Search" v-model="searchQuery" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col h-[calc(100%_-_170px)] p-4 pb-24">
|
||||
<div class="mb-4 flex flex-wrap gap-2">
|
||||
<button v-for="tag in uniqueTags" :key="tag" @click="toggleTag(tag)" class="btn-cyan" :class="{ 'opacity-50': !selectedTags.includes(tag) }">
|
||||
{{ tag }}
|
||||
</button>
|
||||
</div>
|
||||
<div class="h-full flex-grow overflow-y-auto">
|
||||
<div class="grid grid-cols-4 gap-2 justify-items-center">
|
||||
<div class="grid auto-rows-max gap-2 justify-items-center m-4" style="grid-template-columns: repeat(auto-fill, minmax(80px, 1fr))">
|
||||
<template v-if="!selectedGroup">
|
||||
<div v-for="group in groupedTiles" :key="group.parent.id" class="flex flex-col items-center justify-center relative">
|
||||
<img
|
||||
class="max-w-full max-h-full border-2 border-solid rounded cursor-pointer transition-all duration-300"
|
||||
@ -40,43 +26,29 @@
|
||||
{{ group.children.length + 1 }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="col-span-full mb-4 flex items-center">
|
||||
<button @click="closeGroup" class="flex items-center text-white hover:text-cyan transition-colors duration-200">
|
||||
<img class="invert w-5 h-5 rotate-90 mr-2" src="/assets/icons/mapEditor/chevron.svg" alt="Back" />
|
||||
Back to groups
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="h-full overflow-auto">
|
||||
<div class="p-4">
|
||||
<button @click="closeGroup" class="btn-cyan mb-4">Back to All Tiles</button>
|
||||
<h4 class="text-lg mb-4">{{ selectedGroup.parent.name }} Group</h4>
|
||||
<div class="grid grid-cols-4 gap-2 justify-items-center">
|
||||
<div class="flex flex-col items-center justify-center">
|
||||
<div v-for="tile in [selectedGroup.parent, ...selectedGroup.children]" :key="tile.id" class="flex flex-col items-center justify-center relative">
|
||||
<img
|
||||
class="max-w-full max-h-full border-2 border-solid rounded cursor-pointer transition-all duration-300"
|
||||
:src="`${config.server_endpoint}/textures/tiles/${selectedGroup.parent.id}.png`"
|
||||
:alt="selectedGroup.parent.name"
|
||||
@click="selectTile(selectedGroup.parent.id)"
|
||||
:src="`${config.server_endpoint}/textures/tiles/${tile.id}.png`"
|
||||
:alt="tile.name"
|
||||
@click="selectTile(tile.id)"
|
||||
@load="() => tileProcessor.processTile(tile)"
|
||||
:class="{
|
||||
'border-cyan shadow-lg': isActiveTile(selectedGroup.parent),
|
||||
'border-transparent hover:border-gray-300': !isActiveTile(selectedGroup.parent)
|
||||
'border-cyan shadow-lg': isActiveTile(tile),
|
||||
'border-transparent hover:border-gray-300': !isActiveTile(tile)
|
||||
}"
|
||||
/>
|
||||
<span class="text-xs mt-1">{{ getTileCategory(selectedGroup.parent) }}</span>
|
||||
</div>
|
||||
<div v-for="childTile in selectedGroup.children" :key="childTile.id" class="flex flex-col items-center justify-center">
|
||||
<img
|
||||
class="max-w-full max-h-full border-2 border-solid rounded cursor-pointer transition-all duration-300"
|
||||
:src="`${config.server_endpoint}/textures/tiles/${childTile.id}.png`"
|
||||
:alt="childTile.name"
|
||||
@click="selectTile(childTile.id)"
|
||||
:class="{
|
||||
'border-cyan shadow-lg': isActiveTile(childTile),
|
||||
'border-transparent hover:border-gray-300': !isActiveTile(childTile)
|
||||
}"
|
||||
/>
|
||||
<span class="text-xs mt-1">{{ getTileCategory(childTile) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-xs mt-1">{{ getTileCategory(tile) }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -101,6 +73,31 @@ const selectedTags = ref<string[]>([])
|
||||
const tileCategories = ref<Map<string, string>>(new Map())
|
||||
const selectedGroup = ref<{ parent: Tile; children: Tile[] } | null>(null)
|
||||
const tiles = ref<Tile[]>([])
|
||||
const width = ref(320)
|
||||
const isDragging = ref(false)
|
||||
|
||||
function startDragging(event: MouseEvent) {
|
||||
isDragging.value = true
|
||||
const startX = event.clientX
|
||||
const startWidth = width.value
|
||||
|
||||
function onMouseMove(e: MouseEvent) {
|
||||
if (isDragging.value) {
|
||||
const deltaX = startX - e.clientX
|
||||
const newWidth = Math.max(320, Math.min(800, startWidth + deltaX))
|
||||
width.value = newWidth
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseUp() {
|
||||
isDragging.value = false
|
||||
document.removeEventListener('mousemove', onMouseMove)
|
||||
document.removeEventListener('mouseup', onMouseUp)
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', onMouseMove)
|
||||
document.addEventListener('mouseup', onMouseUp)
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open: () => (isOpen.value = true),
|
||||
|
Loading…
x
Reference in New Issue
Block a user