mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-22 20:48:56 +01:00
Detective Board UI update (#90591)
## About The Pull Request I've updated the UI of the detective board to make it look more detective-like. Also, it is not necessary to specify the name and description of the evidence to be attached. If it is not specified, these fields are taken from the item. https://github.com/user-attachments/assets/51419478-5fa9-43d4-a903-992ab4f0c91d (The detective smoked a cigar and is now coughing) Before:  After:  ## Why It's Good For The Game Better UI/UX ## Changelog 🆑 FeudeyTF qol: Better UI/UX for detective's board /🆑
This commit is contained in:
@@ -52,12 +52,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/detectiveboard, 32)
|
||||
attaching_evidence = TRUE
|
||||
var/name = tgui_input_text(user, "Please enter the evidence name", "Detective's Board", max_length = MAX_NAME_LEN)
|
||||
if(!name)
|
||||
attaching_evidence = FALSE
|
||||
return
|
||||
name = item.name
|
||||
var/desc = tgui_input_text(user, "Please enter the evidence description", "Detective's Board", max_length = MAX_DESC_LEN)
|
||||
if(!desc)
|
||||
attaching_evidence = FALSE
|
||||
return
|
||||
desc = item.desc
|
||||
|
||||
if(!user.transferItemToLoc(item, src))
|
||||
attaching_evidence = FALSE
|
||||
|
||||
@@ -38,6 +38,8 @@ export function Evidence(props: EvidenceProps) {
|
||||
null,
|
||||
);
|
||||
|
||||
const randomRotation = Math.random() * 2 - 1;
|
||||
|
||||
function handleMouseDown(args) {
|
||||
if (canDrag) {
|
||||
setDragging(true);
|
||||
@@ -74,9 +76,6 @@ export function Evidence(props: EvidenceProps) {
|
||||
};
|
||||
}, [dragging]);
|
||||
|
||||
function getPinPositionByPosition(evidence: Position) {
|
||||
return { x: evidence.x + 15, y: evidence.y + 45 };
|
||||
}
|
||||
useEffect(() => {
|
||||
if (!dragging) {
|
||||
return;
|
||||
@@ -85,13 +84,16 @@ export function Evidence(props: EvidenceProps) {
|
||||
const onMouseMove = (args: MouseEvent) => {
|
||||
if (canDrag) {
|
||||
if (lastMousePosition) {
|
||||
const newX = dragPosition.x - (lastMousePosition.x - args.screenX);
|
||||
const newY = dragPosition.y - (lastMousePosition.y - args.screenY);
|
||||
|
||||
setDragPosition({
|
||||
x: dragPosition.x - (lastMousePosition.x - args.screenX),
|
||||
y: dragPosition.y - (lastMousePosition.y - args.screenY),
|
||||
x: newX,
|
||||
y: newY,
|
||||
});
|
||||
props.onMoving(evidence, {
|
||||
x: dragPosition.x - (lastMousePosition.x - args.screenX),
|
||||
y: dragPosition.y - (lastMousePosition.y - args.screenY),
|
||||
x: newX,
|
||||
y: newY,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -107,10 +109,15 @@ export function Evidence(props: EvidenceProps) {
|
||||
|
||||
return (
|
||||
<Box
|
||||
className={dragging && 'Evidence--dragging'}
|
||||
position="absolute"
|
||||
left={`${dragPosition.x}px`}
|
||||
top={`${dragPosition.y}px`}
|
||||
onMouseDown={handleMouseDown}
|
||||
style={{
|
||||
transform: !dragging ? `rotate(${randomRotation}deg)` : undefined,
|
||||
zIndex: 1,
|
||||
}}
|
||||
>
|
||||
<Stack vertical>
|
||||
<Stack.Item>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { Box, Stack } from 'tgui-core/components';
|
||||
import { classes } from 'tgui-core/react';
|
||||
|
||||
import { DataEvidence } from './DataTypes';
|
||||
|
||||
@@ -48,7 +49,10 @@ export function Pin(props: PinProps) {
|
||||
<Stack>
|
||||
<Stack.Item>
|
||||
<Box
|
||||
className="Evidence__Pin"
|
||||
className={classes([
|
||||
'Evidence__Pin',
|
||||
creatingRope && 'Evidence__Pin--connecting',
|
||||
])}
|
||||
textAlign="center"
|
||||
onMouseDown={handleMouseDown}
|
||||
onMouseUp={(args) => onMouseUp(evidence, args)}
|
||||
|
||||
@@ -291,20 +291,20 @@ export function DetectiveBoard(props) {
|
||||
connections={retrieveConnections(
|
||||
movingEvidenceConnections,
|
||||
)}
|
||||
zLayer={99}
|
||||
zLayer={1}
|
||||
/>
|
||||
)}
|
||||
{connection && (
|
||||
<Connections
|
||||
lineWidth={5}
|
||||
connections={[connection]}
|
||||
zLayer={99}
|
||||
zLayer={1}
|
||||
/>
|
||||
)}
|
||||
<Connections
|
||||
lineWidth={5}
|
||||
connections={connections}
|
||||
zLayer={99}
|
||||
zLayer={1}
|
||||
/>
|
||||
{item?.evidences?.map((evidence, index) => (
|
||||
<Evidence
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
transition-property: background-color, transform;
|
||||
transition-duration: var(--transition-time-medium);
|
||||
}
|
||||
|
||||
.BoardTab__Text {
|
||||
margin-right: var(--space-m);
|
||||
}
|
||||
@@ -39,36 +40,124 @@
|
||||
|
||||
.Evidence__Pin {
|
||||
box-shadow: var(--shadow-glow-small) hsla(0, 0%, 0%, 0.33);
|
||||
background-color: var(--color-red);
|
||||
background-color: hsl(0, 65%, 40%);
|
||||
border-radius: var(--border-radius-circular);
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
transition:
|
||||
transform 0.2s ease,
|
||||
box-shadow 0.2s ease;
|
||||
border: 1px solid hsla(0, 0%, 0%, 0.3);
|
||||
background-image: radial-gradient(
|
||||
circle at 30% 30%,
|
||||
rgba(255, 255, 255, 0.5) 0%,
|
||||
rgba(255, 255, 255, 0) 60%
|
||||
);
|
||||
}
|
||||
|
||||
.Evidence__Pin:hover {
|
||||
transform: scale(1.2);
|
||||
cursor: var(--cursor-pointer);
|
||||
box-shadow: 0 0 12px hsla(0, 72%, 50%, 0.7);
|
||||
}
|
||||
|
||||
.Evidence__Pin--connecting {
|
||||
background-color: hsl(0, 82%, 60%);
|
||||
box-shadow: 0 0 15px hsla(0, 72%, 50%, 0.9);
|
||||
transform: scale(1.3);
|
||||
}
|
||||
|
||||
.Evidence__Box {
|
||||
cursor: var(--cursor-pointer);
|
||||
box-shadow: var(--shadow-glow-medium) hsla(0, 0%, 0%, 0.4);
|
||||
box-shadow: 0 4px 12px hsla(0, 0%, 0%, 0.6);
|
||||
padding: var(--space-m);
|
||||
color: var(--color-black);
|
||||
min-width: 200px;
|
||||
max-width: 300px;
|
||||
background-color: hsl(0, 0%, 100%);
|
||||
border: var(--border-thickness-small) solid hsl(0, 0%, 50%);
|
||||
background-color: hsl(46, 39%, 94%);
|
||||
border: 2px solid hsl(35, 30%, 50%);
|
||||
user-select: none;
|
||||
-ms-user-select: none;
|
||||
text-wrap: wrap;
|
||||
position: relative;
|
||||
background-image: repeating-linear-gradient(
|
||||
0deg,
|
||||
rgba(0, 0, 0, 0.06) 0px,
|
||||
rgba(0, 0, 0, 0.06) 1px,
|
||||
transparent 1px,
|
||||
transparent 22px
|
||||
);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.Evidence__Box:hover {
|
||||
box-shadow: 0 8px 16px hsla(0, 0%, 0%, 0.7);
|
||||
transform: translateY(-4px) rotate(0.5deg);
|
||||
border-color: hsl(35, 40%, 40%);
|
||||
transition: transform 0.3s ease;
|
||||
}
|
||||
|
||||
.Evidence--dragging .Evidence__Box {
|
||||
animation: card-sway 1s ease-in-out infinite;
|
||||
box-shadow: 0 12px 24px hsla(0, 0%, 0%, 0.7);
|
||||
transform: translateY(-8px) rotate(1deg) translateX(10px);
|
||||
transition: all 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
|
||||
border-color: hsl(35, 40%, 30%);
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.Evidence__Box::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
rgba(255, 255, 255, 0.3) 0%,
|
||||
rgba(255, 255, 255, 0) 50%
|
||||
);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.Evidence__Box::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
transparent 0%,
|
||||
transparent 50%,
|
||||
rgba(0, 0, 0, 0.05) 50%,
|
||||
rgba(0, 0, 0, 0.05) 100%
|
||||
);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.Evidence__Box__TextBox {
|
||||
border-top: var(--border-thickness-tiny) solid hsl(0, 0%, 92%);
|
||||
border-top: var(--border-thickness-tiny) dashed hsl(36, 29%, 80%);
|
||||
text-wrap: wrap;
|
||||
padding: var(--space-m) 0;
|
||||
margin-top: var(--space-m);
|
||||
max-width: 240px;
|
||||
text-align: center;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
color: #333;
|
||||
|
||||
&.title {
|
||||
border-top: none;
|
||||
margin-top: 0;
|
||||
font-weight: bold;
|
||||
font-size: 1.1em;
|
||||
color: #22131b;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
text-align: center;
|
||||
text-shadow: 1px 1px 0 rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +167,16 @@
|
||||
padding: var(--space-m);
|
||||
overflow: hidden;
|
||||
height: 95%;
|
||||
background-image: radial-gradient(
|
||||
circle,
|
||||
rgba(0, 0, 0, 0.1) 1px,
|
||||
transparent 1px
|
||||
),
|
||||
radial-gradient(circle, rgba(0, 0, 0, 0.1) 1px, transparent 1px);
|
||||
background-size: 16px 16px;
|
||||
background-position:
|
||||
0 0,
|
||||
8px 8px;
|
||||
}
|
||||
|
||||
.Evidence__Icon {
|
||||
@@ -85,6 +184,14 @@
|
||||
margin-top: var(--space-m);
|
||||
border: var(--border-thickness-large) solid hsl(0, 0%, 88%);
|
||||
width: 100%;
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.3);
|
||||
transition: transform 0.2s ease;
|
||||
filter: sepia(20%);
|
||||
}
|
||||
|
||||
.Evidence__Icon:hover {
|
||||
transform: scale(1.02);
|
||||
filter: sepia(0%);
|
||||
}
|
||||
|
||||
@each $color-name, $color-value in colors.$color-map {
|
||||
@@ -100,3 +207,27 @@
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes float {
|
||||
0% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
50% {
|
||||
transform: translateY(-5px);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(0px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes card-sway {
|
||||
0% {
|
||||
transform: rotate(-1deg) translateX(0);
|
||||
}
|
||||
50% {
|
||||
transform: rotate(1deg) translateX(5px);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(-1deg) translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user