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.

175 lines
3.8 KiB

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