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.
81 lines
3.8 KiB
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)
|
|
} |