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.
 
 
 
 
 
 

176 lines
3.8 KiB

<script lang="ts" context="module">
const COLORS = [
"none",
"bronze",
"silver",
"gold",
"emerald",
"diamond"
]
</script>
<script lang="ts">
export let target = 1;
export let count = 0;
export let green = false;
export let thin = false;
export let thinner = false;
export let gray = false;
export let titlePercentageOnly = false;
export let titleTime = false;
export let contextColor = false;
let offClass = COLORS[0];
let onClass = COLORS[1];
let ons = 0;
let offs = 1;
let nonSegmented = false;
let title = "";
$: {
if (target > 0) {
let level = Math.floor(count / target);
if (level >= COLORS.length - 1 || (level > 1 && green)) {
offs = 0;
ons = target;
offClass = "gold";
onClass = "diamond";
} else {
ons = count - (level * target);
offs = target - ons;
offClass = COLORS[level];
onClass = COLORS[level + 1];
}
if (green) {
onClass = "green"
offClass = "none"
}
if (gray) {
onClass = "gray"
offClass = "none"
}
if (contextColor) {
onClass = "sccpb"
offClass = "none"
}
// Mark it non-segmented if the target is too high. This prevents a clunky progress bar,
// or a browser freeze if you set the target very high.
nonSegmented = (target >= 60);
} else {
offClass = "none";
nonSegmented = false;
ons = 0;
offs = 1;
}
}
$: {
const percentage = ((count / target) * 100).toFixed(0);
if (titlePercentageOnly) {
title = `${percentage}%`;
} else if (titleTime) {
let unit = "days";
let progressTime = (count / 86400000);
let totaltTime = (target / 86400000);
if (totaltTime < 1) {
unit = "hours";
totaltTime *= 24;
progressTime *= 24;
}
title = `${progressTime.toFixed(1)} / ${totaltTime.toFixed(1)} ${unit} (${percentage}%)`;
} else {
title = `${count} / ${target} (${percentage}%)`
}
}
</script>
<div class="bar" title="{title}" class:thin class:thinner>
{#if nonSegmented}
{#if ons > 0}
<div style="flex: {ons}" class={"non-segmented on " + onClass}></div>
{/if}
{#if offs > 0}
<div style="flex: {offs}" class={"non-segmented off " + offClass}></div>
{/if}
{:else}
{#each {length: Math.max(ons, 0)} as _}
<div class={"on " + onClass}></div>
{/each}
{#each {length: Math.max(offs, 0)} as _}
<div class={"off " + offClass}></div>
{/each}
{/if}
</div>
<style>
div.bar {
display: flex;
flex-direction: row;
margin: 0;
box-sizing: border-box;
width: 100%;
height: 16px;
margin: 0.5px 0;
}
div.bar > div {
flex-grow: 1;
flex-basis: 0;
display: inline-block;
box-sizing: border-box;
margin: 0 0.5px;
border: 0.25px solid #111;
}
div.non-segmented {
flex-grow: inherit;
flex-basis: inherit;
}
div.on {
opacity: 0.75;
}
div.none { background-color: #555555; }
div.bronze { background-color: #f4b083; }
div.silver { background-color: #d8dce4; opacity: 0.8; }
div.gold { background-color: #ffd966; opacity: 0.8; }
div.diamond { background-color: #84f5ff; opacity: 0.9; }
div.emerald, div.green { background-color: #8ef88e; opacity: 0.8; }
div.gray { background-color: #777777; }
div.off {
opacity: 0.50;
}
div.bar.thin {
height: 3px;
}
div.bar.thinner {
height: 1px;
}
div.bar.thinner div {
border-bottom: none;
border-top: none;
}
div.bar.thinner div.none {
background-color: #111111;
}
@media screen and (min-width: 1200) {
div.bar div {
margin: 1px 1px;
}
div.bar.thin {
height: 4px;
}
div.bar.thinner {
height: 4px;
}
}
</style>