From c544e0a12aab81fc9caf508d14d03844f747683b Mon Sep 17 00:00:00 2001 From: Colin Kallemein <cakallemein@gmail.com> Date: Sat, 6 Jul 2024 17:18:39 +0200 Subject: [PATCH] Convert GUI components to Tailwind (where possible smh) --- src/components/gui/Hud.vue | 228 +++++++++--------------------------- src/components/gui/Menu.vue | 143 ++++++++-------------- tailwind.config.js | 3 + 3 files changed, 104 insertions(+), 270 deletions(-) diff --git a/src/components/gui/Hud.vue b/src/components/gui/Hud.vue index a92d320..dbd4e0e 100644 --- a/src/components/gui/Hud.vue +++ b/src/components/gui/Hud.vue @@ -1,40 +1,42 @@ <template> - <div class="hud-wrapper"> - <div class="profile"> - <img draggable="false" src="/assets/avatar/default/head.png" /> + <div class="hud-wrapper relative left-0 w-[310px] h-[84px]"> + <div class="profile absolute w-[54px] h-[54px] bg-white bg-opacity-80 rounded-full border-3 border-solid border-white top-1/2 translate-y-[-50%] left-0 z-20"> + <img class="w-[28px] absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%]" draggable="false" src="/assets/avatar/default/head.png" /> </div> - <div class="hud"> - <div class="stats"> - <div class="player-details"> - <span class="player-name">{{ socket.character.name }}</span> - <span class="player-lvl">lvl. {{ socket.character.level }}</span> + <div class="hud-bg absolute top-0 left-[30px] w-[280px] h-[84px] z-10 bg-[url('/assets/bg-hud-2.png')] bg-top bg-[length:cover] bg-no-repeat mask-[url('/assets/shapes/hud-image-shape.svg')] mask-center mask-[length:cover] mask-no-repeat"></div> + <div class="absolute top-0 left-[30px] w-[280px] h-[84px] z-10 bg-[url('/assets/shapes/hud-shape-empty.svg')] bg-center bg-[length:cover] bg-no-repeat"> + <div class="h-[64px] flex flex-col items-end py-[10px] pl-[50px] pr-[20px]"> + <div class="w-full flex items-center justify-between mb-1.5"> + <span class="text-ellipsis overflow-hidden whitespace-nowrap max-w-[125px] text-sm">{{ socket.character.name }}</span> + <span class="text-sm">lvl. {{ socket.character.level }}</span> </div> - <div class="bar"> - <label for="hp">HP</label> - <progress id="hp" :value="socket.character.hitpoints" max="100">{{ socket.character.hitpoints }}%</progress> + <div class="w-full flex items-center justify-between"> + <label class="text-sm" for="hp">HP</label> + <progress class="h-2 rounded-lg w-full max-w-[175px] appearance-none accent-red" id="hp" :value="socket.character.hitpoints" max="100">{{ socket.character.hitpoints }}%</progress> </div> - <div class="bar"> - <label for="mp">MP</label> - <progress id="mp" :value="socket.character.mana" max="100">{{ socket.character.mana }}%</progress> + <div class="w-full flex items-center justify-between"> + <label class="text-sm" for="mp">MP</label> + <progress class="h-2 rounded-lg w-full max-w-[175px] appearance-none accent-blue" id="mp" :value="socket.character.mana" max="100">{{ socket.character.mana }}%</progress> </div> </div> </div> </div> <!-- TODO: Replace socket.character with other (selected) player's --> - <div class="hud-wrapper other-player"> - <div class="profile"> - <img draggable="false" src="/assets/avatar/default/head.png" /> + <div class="hud-wrapper other-player relative right-0 w-[310px] h-[84px]"> + <div class="absolute w-[54px] h-[54px] bg-white bg-opacity-80 rounded-full border-3 border-solid border-white top-1/2 translate-y-[-50%] right-0 z-20"> + <img class="w-[28px] absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] scale-x-[-1]"draggable="false" src="/assets/avatar/default/head.png" /> </div> - <div class="hud"> - <div class="stats"> - <div class="player-details"> - <span class="player-name">{{ socket.character.name }}</span> - <span class="player-lvl">lvl. {{ socket.character.level }}</span> + <div class="hud-bg absolute top-0 right-[30px] w-[280px] h-[84px] z-10 bg-[url('/assets/bg-hud-2.png')] bg-center bg-[length:cover] bg-no-repeat mask-[url('/assets/shapes/hud-image-shape.svg')] mask-center mask-[length:cover] mask-no-repeat"></div> + <div class="absolute top-0 right-[30px] w-[280px] h-[84px] z-10 scale-x-[-1] bg-[url('/assets/shapes/hud-shape-empty.svg')] bg-center bg-[length:cover] bg-no-repeat"> + <div class="h-[64px] flex flex-col items-end scale-x-[-1] py-[10px] pr-[50px] pl-[20px]"> + <div class="w-full flex items-center justify-between mb-1.5"> + <span class="text-ellipsis overflow-hidden whitespace-nowrap max-w-[125px] text-sm">{{ socket.character.name }}</span> + <span class="text-sm">lvl. {{ socket.character.level }}</span> </div> - <div class="bar"> - <label for="hp">HP</label> - <progress id="hp" :value="socket.character.hitpoints" max="100">{{ socket.character.hitpoints }}%</progress> + <div class="w-full flex items-center justify-between"> + <label class="text-sm" for="hp">HP</label> + <progress class="h-2 rounded-lg w-full max-w-[175px] appearance-none accent-red" id="hp" :value="socket.character.hitpoints" max="100">{{ socket.character.hitpoints }}%</progress> </div> </div> </div> @@ -48,161 +50,41 @@ const socket = useSocketStore() </script> <style scoped lang="scss"> -@import '@/assets/scss/main'; - .hud-wrapper { - position: relative; - left: 0; - width: 315px; - height: 84px; - - .hud, - &::before { - position: absolute; - top: 0; - left: 30px; - width: 280px; - height: 84px; - z-index: 1; - } - - .profile { - position: absolute; - width: 54px; - height: 54px; - background-color: rgba($white, 0.8); - border-radius: 100%; - border: 3px solid $white; - top: 50%; - transform: translateY(-50%); - left: 0; - z-index: 2; // Ensure profile is above hud and before - img { - width: 28px; - position: absolute; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); - } - } - - .hud { - background: url('/assets/shapes/hud-shape-empty.svg') center/cover no-repeat; - .stats { - height: calc(100% - 30px); - display: flex; - flex-direction: column; - align-items: end; - padding: 15px 20px 15px 50px; - - .player-details, - .bar { - width: 100%; - display: flex; - align-items: center; - justify-content: space-between; - span, - label { - font-size: 14px; - } - .player-name { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - max-width: 125px; - } - } - - .player-details { - margin-bottom: 5px; - } - - .bar { - progress { - -webkit-appearance: none; - appearance: none; - height: 8px; - border-radius: 8px; - width: 100%; - max-width: 175px; - - &#hp { - accent-color: $red; - // Chrome, Safari, Edge, Opera - &::-webkit-progress-value { - background: $red; - border-radius: 8px; - } - &::-webkit-progress-bar { - background: $white; - border-radius: 8px; - border: 2px solid $white; - } - // Firefox - &::-moz-progress-bar { - background: $red; - border-radius: 8px; - border: 2px solid $white; - } - } - &#mp { - accent-color: $light-blue; - // Chrome, Safari, Edge, Opera - &::-webkit-progress-value { - background: $light-blue; - border-radius: 8px; - } - &::-webkit-progress-bar { - background: $white; - border-radius: 8px; - border: 2px solid $white; - } - // Firefox - &::-moz-progress-bar { - background: $light-blue; - border-radius: 8px; - border: 2px solid $white; - } - } - } - } - } - } - - &::before { - content: ''; - background: url('/assets/bg-hud-2.png') top/cover no-repeat; + .hud-bg { mask: url('/assets/shapes/hud-image-shape.svg') center/cover no-repeat; } + #hp { + // Chrome, Safari, Edge, Opera + &::-webkit-progress-value { + @apply bg-red rounded-lg; + } + &::-webkit-progress-bar { + @apply bg-white rounded-lg border-2 border-solid border-white; + } + // Firefox + &::-moz-progress-bar { + @apply bg-red rounded-lg border-2 border-solid border-white; + } + } + #mp { + // Chrome, Safari, Edge, Opera + &::-webkit-progress-value { + @apply bg-blue rounded-lg; + } + &::-webkit-progress-bar { + @apply bg-white rounded-lg border-2 border-solid border-white; + } + // Firefox + &::-moz-progress-bar { + @apply bg-blue rounded-lg border-2 border-solid border-white; + } + } &.other-player { - left: unset; - right: 0; - - &::before { - left: unset; - right: 30px; - background: url('/assets/bg-hud-2.png') center/cover no-repeat; + .hud-bg { mask: url('/assets/shapes/hud-image-shape-flipped.svg') center/cover no-repeat; } - - .profile { - left: unset; - right: 0; - img { - transform: translate(-50%, -50%) scaleX(-1); - } - } - - .hud { - left: unset; - right: 30px; - transform: scaleX(-1); - .stats { - transform: scaleX(-1); - padding: 15px 50px 15px 20px; - } - } } } </style> diff --git a/src/components/gui/Menu.vue b/src/components/gui/Menu.vue index d05eb37..eac6e54 100644 --- a/src/components/gui/Menu.vue +++ b/src/components/gui/Menu.vue @@ -1,106 +1,55 @@ <template> - <div class="menu-wrapper"> - <ul class="menu"> - <li class="menu-item"> - <p>Chat</p> - <a> - <img draggable="false" src="/assets/icons/chat.png" /> - </a> - </li> - <li class="menu-item"> - <p>World</p> - <a> - <img draggable="false" src="/assets/icons/world.png" /> - </a> - </li> - <li class="menu-item"> - <p>Users</p> - <a> - <img draggable="false" src="/assets/icons/users.png" /> - </a> - </li> - <li class="menu-item"> - <p>Inventory</p> - <a> - <img draggable="false" src="/assets/icons/treasure-chest.png" /> - </a> - </li> - </ul> - </div> + <ul class="list-none flex gap-2.5"> + <li class="menu-item relative"> + <div class="absolute bottom-[65px] left-1/2 translate-x-[-50%] w-[85px] h-[24px] text-center bg-gray-300 border-2 border-solid border-cyan rounded-3xl hidden"> + <p class="absolute w-full bottom-0 m-0 text-sm leading-6">Chat</p> + <div class="absolute top-[26px] bg-white h-[8px] w-[14px] [clip-path:polygon(100%_0,_0_0,_50%_100%)] left-1/2 translate-x-[-50%] hidden"></div> + </div> + <a class="p-2 bg-gray-300 bg-opacity-70 border-2 border-solid border-cyan rounded-lg block w-[45px] h-[35px]"> + <img class="w-[45px] h-[35px] object-contain" draggable="false" src="/assets/icons/chat.png" /> + </a> + </li> + <li class="menu-item relative"> + <div class="absolute bottom-[65px] left-1/2 translate-x-[-50%] w-[85px] h-[24px] text-center bg-gray-300 border-2 border-solid border-cyan rounded-3xl hidden"> + <p class="absolute w-full bottom-0 m-0 text-sm leading-6">World</p> + <div class="absolute top-[26px] bg-white h-[8px] w-[14px] [clip-path:polygon(100%_0,_0_0,_50%_100%)] left-1/2 translate-x-[-50%] hidden"></div> + </div> + <a class="p-2 bg-gray-300 bg-opacity-70 border-2 border-solid border-cyan rounded-lg block w-[45px] h-[35px]"> + <img class="w-[45px] h-[35px] object-contain" draggable="false" src="/assets/icons/world.png" /> + </a> + </li> + <li class="menu-item relative"> + <div class="absolute bottom-[65px] left-1/2 translate-x-[-50%] w-[85px] h-[24px] text-center bg-gray-300 border-2 border-solid border-cyan rounded-3xl hidden"> + <p class="absolute w-full bottom-0 m-0 text-sm leading-6">Users</p> + <div class="absolute top-[26px] bg-white h-[8px] w-[14px] [clip-path:polygon(100%_0,_0_0,_50%_100%)] left-1/2 translate-x-[-50%] hidden"></div> + </div> + <a class="p-2 bg-gray-300 bg-opacity-70 border-2 border-solid border-cyan rounded-lg block w-[45px] h-[35px]"> + <img class="w-[45px] h-[35px] object-contain" draggable="false" src="/assets/icons/users.png" /> + </a> + </li> + <li class="menu-item relative"> + <div class="absolute bottom-[65px] left-1/2 translate-x-[-50%] w-[85px] h-[24px] text-center bg-gray-300 border-2 border-solid border-cyan rounded-3xl hidden"> + <p class="absolute w-full bottom-0 m-0 text-sm leading-6">Inventory</p> + <div class="absolute top-[26px] bg-white h-[8px] w-[14px] [clip-path:polygon(100%_0,_0_0,_50%_100%)] left-1/2 translate-x-[-50%] hidden"></div> + </div> + <a class="p-2 bg-gray-300 bg-opacity-70 border-2 border-solid border-cyan rounded-lg block w-[45px] h-[35px]"> + <img class="w-[45px] h-[35px] object-contain" draggable="false" src="/assets/icons/treasure-chest.png" /> + </a> + </li> + </ul> </template> -<script setup lang="ts"></script> - <style scoped lang="scss"> -@import '@/assets/scss/main'; +.menu-item:hover { + div { + @apply block; + } -.menu-wrapper { - .menu { - list-style: none; - display: flex; - gap: 10px; + a { + @apply bg-gray bg-opacity-70 cursor-pointer; - .menu-item { - position: relative; - - p { - position: absolute; - bottom: 65px; - width: 85px; - text-align: center; - background-color: $dark-gray; - border: 2px solid $cyan; - border-radius: 24px; - height: 24px; - font-size: 0.875rem; - line-height: 24px; - left: 50%; - transform: translateX(-50%); - display: none; - - &::after { - content: ''; - position: absolute; - top: calc(100% + 2px); - background-color: $white; - height: 8px; - width: 14px; - clip-path: polygon(100% 0, 0 0, 50% 100%); - left: 50%; - transform: translateX(-50%); - } - } - - a { - padding: 8px; - background-color: rgba($dark-gray, 0.7); - border: 2px solid $cyan; - border-radius: 8px; - display: block; - width: 45px; - height: 35px; - - img { - height: inherit; - width: inherit; - object-fit: contain; - } - } - - &:hover { - p { - display: block; - } - - a { - background-color: rgba($gray, 0.7); - cursor: pointer; - - img { - filter: drop-shadow(0px 3px 6px $black); - } - } - } + img { + @apply drop-shadow-default; } } } diff --git a/tailwind.config.js b/tailwind.config.js index 49b496c..220ad0f 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -11,6 +11,9 @@ export default { '30px': '30px' }, extend: { + dropShadow: { + 'default': '0 3px 6px rgb(0, 0, 0)' + }, colors: { red: { DEFAULT: '#d50000',