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.

172 lines
3.7 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <script lang="ts" context="module">
  2. const COLORS = [
  3. "none",
  4. "bronze",
  5. "silver",
  6. "gold",
  7. "emerald",
  8. "diamond"
  9. ]
  10. </script>
  11. <script lang="ts">
  12. export let target = 1;
  13. export let count = 0;
  14. export let green = false;
  15. export let thin = false;
  16. export let thinner = false;
  17. export let gray = false;
  18. export let titlePercentageOnly = false;
  19. export let titleTime = false;
  20. export let contextColor = false;
  21. let offClass = COLORS[0];
  22. let onClass = COLORS[1];
  23. let ons = 0;
  24. let offs = 1;
  25. let nonSegmented = false;
  26. let title = "";
  27. $: {
  28. let level = Math.floor(count / target);
  29. if (level >= COLORS.length - 1 || (level > 1 && green)) {
  30. offs = 0;
  31. ons = target;
  32. offClass = "gold";
  33. onClass = "diamond";
  34. } else {
  35. if (count > 0 && count == (level * target)) {
  36. level -= 1;
  37. }
  38. ons = count - (level * target);
  39. offs = target - ons;
  40. offClass = COLORS[level];
  41. onClass = COLORS[level + 1];
  42. }
  43. if (green) {
  44. onClass = "green"
  45. offClass = "none"
  46. }
  47. if (gray) {
  48. onClass = "gray"
  49. offClass = "none"
  50. }
  51. if (contextColor) {
  52. onClass = "sccpb"
  53. offClass = "none"
  54. }
  55. // Mark it non-segmented if the target is too high. This prevents a clunky progress bar,
  56. // or a browser freeze if you set the target very high.
  57. nonSegmented = (target >= 60);
  58. }
  59. $: {
  60. const percentage = ((count / target) * 100).toFixed(0);
  61. if (titlePercentageOnly) {
  62. title = `${percentage}%`;
  63. } else if (titleTime) {
  64. let unit = "days";
  65. let progressTime = (count / 86400000);
  66. let totaltTime = (target / 86400000);
  67. if (totaltTime < 1) {
  68. unit = "hours";
  69. totaltTime *= 24;
  70. progressTime *= 24;
  71. }
  72. title = `${progressTime.toFixed(1)} / ${totaltTime.toFixed(1)} ${unit} (${percentage}%)`;
  73. } else {
  74. title = `${count} / ${target} (${percentage}%)`
  75. }
  76. }
  77. </script>
  78. <div class="bar" title="{title}" class:thin class:thinner>
  79. {#if nonSegmented}
  80. {#if ons > 0}
  81. <div style="flex: {ons}" class={"non-segmented on " + onClass}></div>
  82. {/if}
  83. {#if offs > 0}
  84. <div style="flex: {offs}" class={"non-segmented off " + offClass}></div>
  85. {/if}
  86. {:else}
  87. {#each {length: ons} as _}
  88. <div class={"on " + onClass}></div>
  89. {/each}
  90. {#each {length: offs} as _}
  91. <div class={"off " + offClass}></div>
  92. {/each}
  93. {/if}
  94. </div>
  95. <style>
  96. div.bar {
  97. display: flex;
  98. flex-direction: row;
  99. margin: 0;
  100. box-sizing: border-box;
  101. width: 100%;
  102. height: 16px;
  103. margin: 0.5px 0;
  104. }
  105. div.bar > div {
  106. flex-grow: 1;
  107. flex-basis: 0;
  108. display: inline-block;
  109. box-sizing: border-box;
  110. margin: 0 0.5px;
  111. border: 0.25px solid #111;
  112. }
  113. div.non-segmented {
  114. flex-grow: inherit;
  115. flex-basis: inherit;
  116. }
  117. div.on {
  118. opacity: 0.75;
  119. }
  120. div.none { background-color: #555555; }
  121. div.bronze { background-color: #f4b083; }
  122. div.silver { background-color: #d8dce4; opacity: 0.8; }
  123. div.gold { background-color: #ffd966; opacity: 0.8; }
  124. div.diamond { background-color: #84f5ff; opacity: 0.9; }
  125. div.emerald, div.green { background-color: #8ef88e; opacity: 0.8; }
  126. div.gray { background-color: #777777; }
  127. div.off {
  128. opacity: 0.50;
  129. }
  130. div.bar.thin {
  131. height: 3px;
  132. }
  133. div.bar.thinner {
  134. height: 1px;
  135. }
  136. div.bar.thinner div {
  137. border-bottom: none;
  138. border-top: none;
  139. }
  140. div.bar.thinner div.none {
  141. background-color: #111111;
  142. }
  143. @media screen and (min-width: 1200) {
  144. div.bar div {
  145. margin: 1px 1px;
  146. }
  147. div.bar.thin {
  148. height: 4px;
  149. }
  150. div.bar.thinner {
  151. height: 4px;
  152. }
  153. }
  154. </style>