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.
169 lines
3.6 KiB
169 lines
3.6 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 = "";
|
|
|
|
$: {
|
|
let level = Math.floor(count / target);
|
|
if (level >= COLORS.length - 1 || (level > 1 && green)) {
|
|
offs = 0;
|
|
ons = target;
|
|
offClass = "gold";
|
|
onClass = "diamond";
|
|
} else {
|
|
if (count > 0 && count == (level * target)) {
|
|
level -= 1;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
$: {
|
|
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}
|
|
<div style="flex: {ons}" class={"non-segmented on " + onClass}></div>
|
|
<div style="flex: {offs}" class={"non-segmented off " + offClass}></div>
|
|
{:else}
|
|
{#each {length: ons} as _}
|
|
<div class={"on " + onClass}></div>
|
|
{/each}
|
|
{#each {length: offs} 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>
|