Tracker made in React for keeping track of HP and MP and so on.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
fabula-ultima-react/src/resource_bar.tsx

81 lines
3.8 KiB

import CSS from "csstype";
import {
evaluateSpringyValueInterpolator, interpolateSpringyValueInterpolatables,
SpringyValueInterpolatables,
SpringyValueInterpolate,
SpringyValueInterpolateds,
SpringyValues
} from "./SpringyValueHook";
import {isDefined} from "./type_check";
export interface ResourceBarColors {
filledColor: CSS.Property.Color
toFillColor: CSS.Property.Color
toEmptyColor: CSS.Property.Color
emptiedColor: CSS.Property.Color
}
export function resourceGradient(
{filledColor, toFillColor, toEmptyColor, emptiedColor}: ResourceBarColors,
{displayedValue, recentValue, newValue, maxValue}: SpringyValues,
direction: string): string {
const effectiveMax = isDefined(maxValue) && maxValue !== 0 ? maxValue : Number.POSITIVE_INFINITY
const currentStop = Math.min(Math.max(100 * displayedValue / effectiveMax, 0), 100)
const currentSoftEdgeLeft = Math.min(Math.max(currentStop - 0.2, 0), 100)
const currentSoftEdgeRight = Math.min(Math.max(currentStop + 0.2, 0), 100)
const endFillingStop = Math.min(Math.max(100 * recentValue / effectiveMax, 0), currentStop)
const midFillingStop = Math.min(Math.max(100 * newValue / effectiveMax, endFillingStop), currentStop)
const endFadingStop = Math.min(Math.max(100 * recentValue / effectiveMax, currentStop), 100)
const midFadingStop =
Math.min(Math.max(100 * newValue / effectiveMax, currentStop), endFadingStop)
const layers = []
if (currentStop === 100) {
layers.unshift(filledColor)
} else {
layers.unshift(emptiedColor)
if (currentStop > 0) {
layers.unshift(`linear-gradient(${direction}, ${filledColor} 0% ${currentSoftEdgeLeft.toFixed(4)}%, transparent ${currentSoftEdgeRight.toFixed(4)}% 100%)`)
}
}
if (endFillingStop !== currentStop || midFillingStop !== currentStop) {
layers.unshift(`linear-gradient(${direction}, transparent 0% ${endFillingStop.toFixed(4)}%, ${toFillColor} ${midFillingStop.toFixed(4)}% ${currentSoftEdgeLeft.toFixed(4)}%, transparent ${currentSoftEdgeRight.toFixed(4)}% 100%)`)
}
if (endFadingStop !== currentStop || midFadingStop !== currentStop) {
layers.unshift(`linear-gradient(${direction}, transparent 0% ${currentSoftEdgeLeft.toFixed(4)}%, ${toEmptyColor} ${currentSoftEdgeRight.toFixed(4)}% ${midFadingStop.toFixed(4)}%, transparent ${endFadingStop.toFixed(4)}% 100%)`)
}
return layers.join(", ")
}
export interface ResourceBarStyles extends CSS.Properties {
foreground?: CSS.Properties["background"]
barDirection?: string
barColors?: ResourceBarColors
}
export const DEFAULT_BAR_COLORS: ResourceBarColors = {
emptiedColor: 'black',
filledColor: 'limegreen',
toEmptyColor: 'red',
toFillColor: 'cyan',
} as const
export const DEFAULT_BAR_DIRECTION: string = "to right"
export function evaluateResourceBarStyles(barStyle: SpringyValueInterpolatables<ResourceBarStyles>, interpolate: SpringyValueInterpolate) {
const intermediate: SpringyValueInterpolatables<ResourceBarStyles> = Object.assign({}, barStyle)
delete intermediate.background
delete intermediate.foreground
delete intermediate.barColors
delete intermediate.barDirection
intermediate.background = (v: SpringyValues) => [
evaluateSpringyValueInterpolator(barStyle["foreground"], v) as string | undefined,
resourceGradient(
evaluateSpringyValueInterpolator(barStyle["barColors"], v) ?? DEFAULT_BAR_COLORS, v,
evaluateSpringyValueInterpolator(barStyle["barDirection"], v) ?? DEFAULT_BAR_DIRECTION),
evaluateSpringyValueInterpolator(barStyle["background"], v) as string | undefined
].filter((s) => !!s).join(', ')
return interpolateSpringyValueInterpolatables(intermediate as SpringyValueInterpolateds<CSS.Properties>, interpolate)
}