mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-07-21 18:09:54 +02:00
rework fear tracker application, add static positions to hold the tracker, enhance token and bar display, create custom dragger and resize methods
This commit is contained in:
parent
79d6522614
commit
6f040532aa
9 changed files with 469 additions and 112 deletions
10
lang/en.json
10
lang/en.json
|
|
@ -2687,6 +2687,9 @@
|
|||
"displayFear": {
|
||||
"label": "Display Fear"
|
||||
},
|
||||
"fearPosition": {
|
||||
"label": "Fear Position"
|
||||
},
|
||||
"displayCountdownUI": {
|
||||
"label": "Display Countdown UI"
|
||||
},
|
||||
|
|
@ -2738,6 +2741,13 @@
|
|||
"token": "Tokens",
|
||||
"bar": "Bar",
|
||||
"hide": "Hide"
|
||||
},
|
||||
"fearPosition": {
|
||||
"free": "Free",
|
||||
"topCenter": "Top + Center",
|
||||
"bottomCenter": "Bottom + Center",
|
||||
"rightTop": "Right + Top",
|
||||
"leftBottom": "Left + Bottom"
|
||||
}
|
||||
},
|
||||
"Automation": {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { enrichedDualityRoll } from '../../enrichers/DualityRollEnricher.mjs';
|
||||
import { enrichedFateRoll, getFateTypeData } from '../../enrichers/FateRollEnricher.mjs';
|
||||
import { getCommandTarget, rollCommandToJSON } from '../../helpers/utils.mjs';
|
||||
import FearTracker from './fearTracker.mjs';
|
||||
|
||||
export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLog {
|
||||
constructor(options) {
|
||||
|
|
@ -297,4 +298,9 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
const actor = game.actors.get(event.target.dataset.actorId);
|
||||
new game.system.api.applications.dialogs.RiskItAllDialog(actor, resourceValue).render({ force: true });
|
||||
}
|
||||
|
||||
_toggleNotifications({ closing = false } = {}) {
|
||||
super._toggleNotifications(closing)
|
||||
FearTracker.handleOffSet();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,14 @@ const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api;
|
|||
export default class FearTracker extends HandlebarsApplicationMixin(ApplicationV2) {
|
||||
constructor(options = {}) {
|
||||
super(options);
|
||||
|
||||
this._dragData = {
|
||||
isDragging: false,
|
||||
startX: 0,
|
||||
startY: 0,
|
||||
startLeft: 0,
|
||||
startTop: 0
|
||||
}
|
||||
}
|
||||
|
||||
/** @inheritDoc */
|
||||
|
|
@ -21,19 +29,20 @@ export default class FearTracker extends HandlebarsApplicationMixin(ApplicationV
|
|||
classes: [],
|
||||
tag: 'div',
|
||||
window: {
|
||||
frame: true,
|
||||
frame: false,
|
||||
title: 'DAGGERHEART.GENERAL.fear',
|
||||
positioned: true,
|
||||
resizable: true,
|
||||
minimizable: false
|
||||
},
|
||||
classes: ['daggerheart', 'dh-style', 'fear-tracker'],
|
||||
actions: {
|
||||
setFear: FearTracker.setFear,
|
||||
increaseFear: FearTracker.increaseFear
|
||||
},
|
||||
position: {
|
||||
width: 222,
|
||||
height: 222
|
||||
width: 540,
|
||||
height: 'auto'
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -53,6 +62,10 @@ export default class FearTracker extends HandlebarsApplicationMixin(ApplicationV
|
|||
return game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxFear;
|
||||
}
|
||||
|
||||
get fearPosition() {
|
||||
return game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance).fearPosition;
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Rendering */
|
||||
/* -------------------------------------------- */
|
||||
|
|
@ -63,15 +76,51 @@ export default class FearTracker extends HandlebarsApplicationMixin(ApplicationV
|
|||
current = this.currentFear,
|
||||
max = this.maxFear,
|
||||
percent = (current / max) * 100,
|
||||
isGM = game.user.isGM;
|
||||
isGM = game.user.isGM,
|
||||
locked = false,
|
||||
isFree = this.fearPosition == 'free';
|
||||
|
||||
return { display, current, max, percent, isGM };
|
||||
return { display, current, max, percent, isGM, locked, isFree };
|
||||
}
|
||||
|
||||
/** @override */
|
||||
async _preFirstRender(context, options) {
|
||||
options.position =
|
||||
async _onRender(context, options) {
|
||||
await super._onRender(context, options);
|
||||
|
||||
this.#setupDragging();
|
||||
this.#setupResizing();
|
||||
|
||||
const fearPosition = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.appearance).fearPosition;
|
||||
|
||||
if (options.isFirstRender) FearTracker.handleOffSet();
|
||||
if (!options.force) return;
|
||||
|
||||
switch (fearPosition) {
|
||||
case 'topCenter':
|
||||
this.handleStyleElement(fearPosition);
|
||||
document.getElementById('ui-top')?.appendChild(this.element);
|
||||
break;
|
||||
case 'bottomCenter':
|
||||
this.handleStyleElement(fearPosition);
|
||||
document.getElementById('ui-bottom')?.prepend(this.element);
|
||||
break;
|
||||
case 'rightTop':
|
||||
this.handleStyleElement(fearPosition);
|
||||
document.getElementById('ui-right-column-1')?.appendChild(this.element);
|
||||
break;
|
||||
case 'leftBottom':
|
||||
this.handleStyleElement(fearPosition);
|
||||
document.getElementById('ui-left-column-1')?.appendChild(this.element);
|
||||
break;
|
||||
|
||||
default:
|
||||
this.handleStyleElement(fearPosition);
|
||||
document.body?.appendChild(this.element);
|
||||
const position =
|
||||
game.user.getFlag(CONFIG.DH.id, 'app.resources.position') ?? FearTracker.DEFAULT_OPTIONS.position;
|
||||
this.setPosition(position);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** @override */
|
||||
|
|
@ -80,13 +129,39 @@ export default class FearTracker extends HandlebarsApplicationMixin(ApplicationV
|
|||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear, this.maxFear);
|
||||
}
|
||||
|
||||
_onPosition(position) {
|
||||
game.user.setFlag(CONFIG.DH.id, 'app.resources.position', position);
|
||||
handleStyleElement(fearPosition) {
|
||||
const positions = {
|
||||
free: 'free',
|
||||
topCenter: 'top-center',
|
||||
bottomCenter: 'bottom-center',
|
||||
rightTop: 'right-top',
|
||||
leftBottom: 'left-bottom'
|
||||
}
|
||||
|
||||
async close(options = {}) {
|
||||
if (!options.allowed) return;
|
||||
else super.close(options);
|
||||
const containsStyle = position => this.element.classList.contains(position);
|
||||
|
||||
Object.entries(positions).forEach(([key, value]) => {
|
||||
if (containsStyle(value)) this.element.classList.remove(value);
|
||||
})
|
||||
|
||||
this.element.classList.add(positions[fearPosition]);
|
||||
}
|
||||
|
||||
static handleOffSet() {
|
||||
const fearTracker = document.getElementById('resources');
|
||||
const hotbar = document.getElementById('hotbar');
|
||||
|
||||
if (!fearTracker) return;
|
||||
|
||||
const offset = Number(hotbar.style.getPropertyValue('--offset').replace(/px$/, '')) || 0;
|
||||
|
||||
if (offset > 0) return;
|
||||
|
||||
fearTracker.style.setProperty('--offset', `${offset - 13}px`);
|
||||
}
|
||||
|
||||
_onPosition(position) {
|
||||
game.user.setFlag(CONFIG.DH.id, 'app.resources.position', position);
|
||||
}
|
||||
|
||||
static async setFear(event, target) {
|
||||
|
|
@ -110,4 +185,118 @@ export default class FearTracker extends HandlebarsApplicationMixin(ApplicationV
|
|||
value
|
||||
);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Dragging handlers */
|
||||
/* -------------------------------------------- */
|
||||
#setupDragging() {
|
||||
const dragHandle = this.element.querySelector('.drag-handle');
|
||||
if (!dragHandle) return;
|
||||
dragHandle.addEventListener('mousedown', this.#onDragStart.bind(this));
|
||||
}
|
||||
|
||||
#onDragStart(event) {
|
||||
if (event.button !== 0) return;
|
||||
this._dragData.isDragging = true;
|
||||
this._dragData.startX = event.clientX;
|
||||
this._dragData.startY = event.clientY;
|
||||
const rect = this.element.getBoundingClientRect();
|
||||
this._dragData.startLeft = rect.left;
|
||||
this._dragData.startTop = rect.top;
|
||||
this.element.style.cursor = 'grabbing';
|
||||
|
||||
this._dragHandler = this.#onDragging.bind(this);
|
||||
this._dragEndHandler = this.#onDragEnd.bind(this);
|
||||
window.addEventListener('mousemove', this._dragHandler);
|
||||
window.addEventListener('mouseup', this._dragEndHandler);
|
||||
}
|
||||
|
||||
#onDragging(event) {
|
||||
if (!this._dragData.isDragging) return;
|
||||
|
||||
const dragX = event.clientX - this._dragData.startX;
|
||||
const dragY = event.clientY - this._dragData.startY;
|
||||
|
||||
this.element.style.left = `${this._dragData.startLeft + dragX}px`;
|
||||
this.element.style.top = `${this._dragData.startTop + dragY}px`;
|
||||
}
|
||||
|
||||
#onDragEnd() {
|
||||
if (!this._dragData.isDragging) return;
|
||||
this._dragData.isDragging = false;
|
||||
this.element.style.cursor = '';
|
||||
|
||||
if (this._dragHandler) window.removeEventListener('mousemove', this._dragHandler);
|
||||
if (this._dragEndHandler) window.removeEventListener('mouseup', this._dragEndHandler);
|
||||
|
||||
const rect = this.element.getBoundingClientRect();
|
||||
const pos = { top: rect.top, left: rect.left };
|
||||
|
||||
this.setPosition(pos);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
/* Resize handlers */
|
||||
/* -------------------------------------------- */
|
||||
|
||||
#setupResizing() {
|
||||
const resizeHandle = this.element.querySelector('.resize-handle');
|
||||
if (!resizeHandle) return;
|
||||
resizeHandle.addEventListener('mousedown', this.#onResizeStart.bind(this));
|
||||
}
|
||||
|
||||
#onResizeStart(e) {
|
||||
if (e.button !== 0) return;
|
||||
e.stopPropagation();
|
||||
|
||||
let maxAllowedWidth = 10000;
|
||||
|
||||
this._resizeData = {
|
||||
isResizing: true,
|
||||
startX: e.clientX,
|
||||
startY: e.clientY,
|
||||
startWidth: this.element.offsetWidth,
|
||||
startHeight: this.element.offsetHeight,
|
||||
maxAllowedWidth: Math.max(50, maxAllowedWidth)
|
||||
};
|
||||
|
||||
this._resizeHandler = this.#onResizing.bind(this);
|
||||
this._resizeEndHandler = this.#onResizeEnd.bind(this);
|
||||
window.addEventListener('mousemove', this._resizeHandler);
|
||||
window.addEventListener('mouseup', this._resizeEndHandler);
|
||||
}
|
||||
|
||||
#onResizing(e) {
|
||||
if (!this._resizeData?.isResizing) return;
|
||||
|
||||
const currentDx = e.clientX - this._resizeData.startX;
|
||||
const potentialWidth = Math.max(50, this._resizeData.startWidth + currentDx);
|
||||
|
||||
const width = Math.min(potentialWidth, this._resizeData.maxAllowedWidth);
|
||||
|
||||
this.element.style.width = `${width}px`;
|
||||
|
||||
if (width < 100) {
|
||||
this.element.classList.add('narrow');
|
||||
} else {
|
||||
this.element.classList.remove('narrow');
|
||||
}
|
||||
}
|
||||
|
||||
#onResizeEnd() {
|
||||
if (!this._resizeData?.isResizing) return;
|
||||
this._resizeData.isResizing = false;
|
||||
|
||||
if (this._resizeHandler) window.removeEventListener('mousemove', this._resizeHandler);
|
||||
if (this._resizeEndHandler) window.removeEventListener('mouseup', this._resizeEndHandler);
|
||||
|
||||
let width = parseFloat(this.element.style.width);
|
||||
|
||||
|
||||
if (isNaN(width)) {
|
||||
width = this.element.getBoundingClientRect().width;
|
||||
}
|
||||
|
||||
this.setPosition({ width: width });
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -924,6 +924,14 @@ export const fearDisplay = {
|
|||
hide: { value: 'hide', label: 'DAGGERHEART.SETTINGS.Appearance.fearDisplay.hide' }
|
||||
};
|
||||
|
||||
export const fearPosition = {
|
||||
free: { value: 'free', label: 'DAGGERHEART.SETTINGS.Appearance.fearPosition.free' },
|
||||
topCenter: { value: 'topCenter', label: 'DAGGERHEART.SETTINGS.Appearance.fearPosition.topCenter' },
|
||||
bottomCenter: { value: 'bottomCenter', label: 'DAGGERHEART.SETTINGS.Appearance.fearPosition.bottomCenter' },
|
||||
rightTop: { value: 'rightTop', label: 'DAGGERHEART.SETTINGS.Appearance.fearPosition.rightTop' },
|
||||
leftBottom: { value: 'leftBottom', label: 'DAGGERHEART.SETTINGS.Appearance.fearPosition.leftBottom' }
|
||||
};
|
||||
|
||||
export const basicOwnershiplevels = {
|
||||
0: { value: 0, label: 'OWNERSHIP.NONE' },
|
||||
2: { value: 2, label: 'OWNERSHIP.OBSERVER' },
|
||||
|
|
|
|||
|
|
@ -41,6 +41,11 @@ export default class DhAppearance extends foundry.abstract.DataModel {
|
|||
choices: CONFIG.DH.GENERAL.fearDisplay,
|
||||
initial: CONFIG.DH.GENERAL.fearDisplay.token.value
|
||||
}),
|
||||
fearPosition: new StringField({
|
||||
required: true,
|
||||
choices: CONFIG.DH.GENERAL.fearPosition,
|
||||
initial: CONFIG.DH.GENERAL.fearPosition.free.value
|
||||
}),
|
||||
displayCountdownUI: new BooleanField({ initial: true }),
|
||||
diceSoNice: new SchemaField({
|
||||
hope: diceStyle({ fg: '#ffffff', bg: '#ffe760', outline: '#000000', edge: '#ffffff' }),
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
background: var(--background);
|
||||
border-radius: 4px;
|
||||
opacity: var(--ui-fade-opacity);
|
||||
transition: opacity var(--ui-fade-duration);
|
||||
transition: opacity var(--ui-fade-delay) var(--ui-fade-duration);
|
||||
}
|
||||
|
||||
&:not(.performance-low, .noblur) {
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
&:hover::before {
|
||||
opacity: 1;
|
||||
transition: opacity var(--ui-fade-duration);
|
||||
}
|
||||
|
||||
#ui-right:has(#effects-display .effect-container) & {
|
||||
|
|
|
|||
|
|
@ -1,119 +1,221 @@
|
|||
:root {
|
||||
--shadow-text-stroke: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
|
||||
--fear-animation: background 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease, opacity 0.3s ease;
|
||||
--hotbar-size: 60px;
|
||||
}
|
||||
|
||||
#interface.theme-dark,
|
||||
body.theme-dark {
|
||||
.daggerheart.dh-style.fear-tracker {
|
||||
--background: url(../assets/parchments/dh-parchment-dark.png);
|
||||
}
|
||||
}
|
||||
|
||||
#interface.theme-light,
|
||||
body.theme-light {
|
||||
.daggerheart.dh-style.fear-tracker {
|
||||
--background: url('../assets/parchments/dh-parchment-light.png') no-repeat center;
|
||||
}
|
||||
}
|
||||
|
||||
#ui-middle:has(#hotbar.sm),
|
||||
#ui-middle:has(#hotbar.md.offset) {
|
||||
#resources {
|
||||
&.top-center,
|
||||
&.bottom-center {
|
||||
width: calc((var(--hotbar-size) * 5) + 32px) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#resources {
|
||||
position: static;
|
||||
min-height: calc(var(--header-height) + 4rem);
|
||||
min-width: 4rem;
|
||||
color: #d3d3d3;
|
||||
transition: var(--fear-animation);
|
||||
header,
|
||||
.controls,
|
||||
.window-resize-handle {
|
||||
transition: var(--fear-animation);
|
||||
pointer-events: all;
|
||||
padding: var(--spacer-8);
|
||||
max-width: 540px;
|
||||
min-width: 100px;
|
||||
|
||||
&::before {
|
||||
content: ' ';
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
background: var(--background);
|
||||
border-radius: 8px;
|
||||
opacity: var(--ui-fade-opacity);
|
||||
transition: opacity var(--ui-fade-delay) var(--ui-fade-duration);
|
||||
|
||||
}
|
||||
.window-content {
|
||||
padding: 0.5rem;
|
||||
|
||||
&:hover::before {
|
||||
opacity: 1;
|
||||
transition: opacity var(--ui-fade-duration);
|
||||
}
|
||||
|
||||
&.free {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
&.top-center,
|
||||
&.bottom-center {
|
||||
margin: 1rem 0;
|
||||
width: 100% !important;
|
||||
transform: translateX(var(--offset));
|
||||
transition: all 250ms ease;
|
||||
}
|
||||
|
||||
&.right-top {
|
||||
width: 300px;
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
&.left-bottom {
|
||||
width: 200px;
|
||||
max-width: 200px;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
&:not(.performance-low, .noblur) {
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
#ui-right:has(#effects-display .effect-container) & {
|
||||
right: 62px;
|
||||
}
|
||||
|
||||
#resource-fear {
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
.fear-header {
|
||||
opacity: 1;
|
||||
height: 18.75px;
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.resize-handle {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fear-header {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
pointer-events: all;
|
||||
margin-bottom: 0.5rem;
|
||||
opacity: 0;
|
||||
height: 0;
|
||||
visibility: hidden;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
.drag-handle {
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
.fear-title {
|
||||
font-size: var(--font-size-13);
|
||||
}
|
||||
}
|
||||
|
||||
.fear-tokens {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 0.5rem 0.25rem;
|
||||
flex-wrap: wrap;
|
||||
i {
|
||||
font-size: var(--font-size-18);
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
justify-content: center;
|
||||
gap: 0.5rem 0.25rem;
|
||||
|
||||
.fear-token {
|
||||
font-size: var(--font-size-16);
|
||||
border: 1.5px double light-dark(@dark-15, @dark-golden-80);
|
||||
border-radius: 50%;
|
||||
aspect-ratio: 1;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 3rem;
|
||||
width: 2.5rem;
|
||||
background-color: @primary-color-fear;
|
||||
-webkit-box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75);
|
||||
box-shadow: 0px 0px 5px 1px rgba(0, 0, 0, 0.75);
|
||||
color: #d3d3d3;
|
||||
color: @beige;
|
||||
flex-grow: 0;
|
||||
text-shadow: none;
|
||||
|
||||
&.inactive {
|
||||
filter: grayscale(1) !important;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
.controls,
|
||||
.resource-bar {
|
||||
border: 2px solid rgb(153 122 79);
|
||||
background-color: rgb(24 22 46);
|
||||
}
|
||||
|
||||
.resize-handle {
|
||||
position: absolute;
|
||||
bottom: -12px;
|
||||
right: -9px;
|
||||
cursor: nwse-resize;
|
||||
opacity: 0;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
|
||||
.resource-bar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
|
||||
.progress-bar {
|
||||
position: absolute;
|
||||
appearance: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 1px solid light-dark(@dark-15, @dark-golden-80);
|
||||
border-radius: 999px;
|
||||
z-index: 0;
|
||||
background: @dark-blue;
|
||||
|
||||
&::-webkit-progress-bar {
|
||||
border: none;
|
||||
background: @dark-blue;
|
||||
border-radius: 999px;
|
||||
}
|
||||
&::-webkit-progress-value {
|
||||
background: linear-gradient(90deg, rgba(2, 0, 38, 1) 0%, rgba(199, 1, 252, 1) 100%);
|
||||
border-radius: 999px;
|
||||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
margin: auto 0;
|
||||
z-index: 2;
|
||||
height: auto;
|
||||
text-align: center;
|
||||
font-size: var(--font-size-18);
|
||||
color: @beige;
|
||||
}
|
||||
}
|
||||
|
||||
.controls {
|
||||
display: flex;
|
||||
align-self: center;
|
||||
border-radius: 50%;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
font-size: var(--font-size-20);
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
&.disabled {
|
||||
align-items: center;
|
||||
margin-top: 0.5rem;
|
||||
color: light-dark(@dark, @beige);
|
||||
|
||||
.disabled {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
.resource-bar {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
border-radius: 6px;
|
||||
font-size: var(--font-size-20);
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
padding: 0.25rem 0.5rem;
|
||||
flex: 1;
|
||||
text-shadow: var(--shadow-text-stroke);
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: var(--fear-percent);
|
||||
max-width: 100%;
|
||||
background: linear-gradient(90deg, rgba(2, 0, 38, 1) 0%, rgba(199, 1, 252, 1) 100%);
|
||||
z-index: 0;
|
||||
border-radius: 4px;
|
||||
}
|
||||
span {
|
||||
position: inherit;
|
||||
z-index: 1;
|
||||
}
|
||||
&.fear {
|
||||
}
|
||||
}
|
||||
|
||||
&.isGM {
|
||||
i {
|
||||
.fear-token {
|
||||
cursor: pointer;
|
||||
transition: box-shadow 0.15s ease;
|
||||
|
||||
&:hover {
|
||||
font-size: var(--font-size-20);
|
||||
box-shadow: 0 0 8px @primary-color-fear ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
button[data-action='close'] {
|
||||
display: none;
|
||||
}
|
||||
&:not(:hover):not(.minimized) {
|
||||
background: transparent;
|
||||
box-shadow: unset;
|
||||
border-color: transparent;
|
||||
header,
|
||||
#resource-fear .controls,
|
||||
.window-resize-handle {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
&:has(.fear-bar) {
|
||||
min-width: 200px;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@
|
|||
value=setting.displayFear
|
||||
localize=true}}
|
||||
{{formGroup
|
||||
fields.fearPosition
|
||||
value=setting.fearPosition
|
||||
localize=true}}
|
||||
{{formGroup
|
||||
fields.displayCountdownUI
|
||||
value=setting.displayCountdownUI
|
||||
localize=true}}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,48 @@
|
|||
<div>
|
||||
<div id="resource-fear" class="{{#if isGM}}isGM{{/if}}">
|
||||
<div id="resource-fear" class="fear-tracker {{#if isGM}}isGM{{/if}}">
|
||||
{{#if isFree}}
|
||||
<div class="fear-header">
|
||||
<div class="drag-handle">
|
||||
<i class="fa-solid fa-grip-vertical"></i>
|
||||
</div>
|
||||
<span class="fear-title">{{localize 'DAGGERHEART.GENERAL.fear'}}</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq display 'token')}}
|
||||
<div class="fear-tokens">
|
||||
{{#times max}}
|
||||
<i class="fas fa-skull {{#if (gte @this ../current)}} inactive{{/if}}" style="filter: hue-rotate(calc(({{this}}/{{../max}})*75deg))" data-index="{{this}}" data-action="setFear"></i>
|
||||
<a
|
||||
class="fear-token {{#if (gte @this ../current)}} inactive{{/if}}"
|
||||
style="filter: hue-rotate(calc(({{this}}/{{../max}})*75deg))"
|
||||
data-index="{{this}}" data-action="setFear"
|
||||
>
|
||||
<i class="fear-token fas fa-skull"></i>
|
||||
</a>
|
||||
{{/times}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if (eq display 'bar')}}
|
||||
{{#if isGM}}<div class="controls control-minus {{#if (lte current 0)}} disabled{{/if}}" data-increment="-1" data-action="increaseFear">-</div>{{/if}}
|
||||
<div class="resource-bar fear-bar" style="--fear-percent: {{percent}}%">
|
||||
<span>{{current}}/{{max}}</span>
|
||||
<progress
|
||||
class='progress-bar stress-color'
|
||||
value='{{current}}'
|
||||
max='{{max}}'
|
||||
></progress>
|
||||
<h4 class="label">{{current}} / {{max}}</h4>
|
||||
</div>
|
||||
{{#if isGM}}<div class="controls control-plus {{#if (gte current max)}} disabled{{/if}}" data-increment="+1" data-action="increaseFear">+</div>{{/if}}
|
||||
{{#if isGM}}
|
||||
<div class="controls">
|
||||
<a class="{{#if (lte current 0)}} disabled{{/if}}" data-increment="-1" data-action="increaseFear"><i class="fa-solid fa-minus"></i></a>
|
||||
<a class="{{#if (gte current max)}} disabled{{/if}}" data-increment="+1" data-action="increaseFear"><i class="fa-solid fa-plus"></i></a>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
||||
{{#if isFree}}
|
||||
<a class="resize-handle">
|
||||
<i class="fa-solid fa-chevron-right" style="transform: rotate(45deg);"></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue