Redesign Color Filter fullscreen cards

This commit is contained in:
Alexey 2026-04-21 20:38:31 +05:00
parent 8c366f8065
commit 1215b41c83
7 changed files with 577 additions and 138 deletions

View file

@ -621,20 +621,18 @@ input[type=file] {
padding-right: 0.08rem;
}
#bm-window-filter .bm-filter-insights {
display: block;
margin: 0 0.18rem;
}
#bm-window-filter .bm-filter-stat-grid {
display: grid;
grid-template-columns: minmax(16rem, 20rem) minmax(0, 1fr);
gap: 0.24rem 0.3rem;
align-items: stretch;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 0.24rem;
}
#bm-window-filter .bm-filter-insights > hr,
#bm-window-filter .bm-filter-stat-card,
#bm-window-filter .bm-filter-sort-panel {
grid-column: 1 / -1;
}
#bm-window-filter .bm-filter-stats-card,
#bm-window-filter .bm-filter-note,
#bm-window-filter .bm-filter-sort-panel {
padding: 0.38rem 0.48rem;
border-radius: 13px;
min-width: 0;
border-radius: 11px;
border: 1px solid rgba(255, 255, 255, 0.18);
background:
linear-gradient(
@ -643,25 +641,37 @@ input[type=file] {
rgba(255, 255, 255, 0.07));
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 8px 20px rgba(0, 0, 0, 0.08);
}
#bm-window-filter .bm-filter-stats-card {
display: grid;
gap: 0.18rem;
#bm-window-filter .bm-filter-stat-card {
min-height: 2.7rem;
display: flex;
flex-direction: column;
justify-content: center;
gap: 0.08rem;
padding: 0.34rem 0.45rem;
color: rgba(18, 35, 63, 0.96);
line-height: 1.22;
}
#bm-window-filter .bm-filter-stats-card br {
display: none;
#bm-window-filter .bm-filter-stat-label {
color: rgba(49, 71, 105, 0.82);
font-size: 0.62rem;
letter-spacing: 0;
font-family: var(--bm-font-display);
text-transform: uppercase;
}
#bm-window-filter .bm-filter-stats-card span {
display: block;
padding: 0.28rem 0.38rem;
border-radius: 10px;
background:
linear-gradient(
180deg,
rgba(255, 255, 255, 0.2),
rgba(255, 255, 255, 0.08));
#bm-window-filter .bm-filter-stat-value {
display: inline-block;
min-width: 0;
color: rgba(15, 31, 56, 0.96);
font-size: 1.04em;
font-weight: 700;
overflow-wrap: anywhere;
}
#bm-window-filter .bm-filter-note p {
margin: 0;
#bm-window-filter .bm-filter-stat-card time {
font-family: var(--bm-font-mono);
letter-spacing: 0;
}
#bm-window-filter .bm-filter-sort-panel {
padding: 0.38rem 0.48rem;
}
#bm-window-filter .bm-filter-sort-panel fieldset {
border: none;
@ -686,9 +696,9 @@ input[type=file] {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
justify-content: flex-start;
align-items: stretch;
gap: 0.3rem;
gap: 0.38rem;
}
#bm-window-filter .bm-filter-color {
position: relative;
@ -726,6 +736,32 @@ input[type=file] {
rgba(186, 246, 255, 0.12),
transparent 22%);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color::before {
background:
linear-gradient(
180deg,
rgba(255, 255, 255, 0.08),
rgba(0, 0, 0, 0.04));
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color::after {
content: "";
position: absolute;
left: 0.52rem;
bottom: 0.46rem;
width: 1.65rem;
height: 1.65rem;
background: currentColor;
opacity: 0.72;
pointer-events: none;
z-index: 0;
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3.8 12s3.1-5 8.2-5 8.2 5 8.2 5-3.1 5-8.2 5-8.2-5-8.2-5Z' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Ccircle cx='12' cy='12' r='2.5' fill='none' stroke='black' stroke-width='1.9'/%3E%3C/svg%3E") center / contain no-repeat;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3.8 12s3.1-5 8.2-5 8.2 5 8.2 5-3.1 5-8.2 5-8.2-5-8.2-5Z' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Ccircle cx='12' cy='12' r='2.5' fill='none' stroke='black' stroke-width='1.9'/%3E%3C/svg%3E") center / contain no-repeat;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-state=hidden]::after {
opacity: 0.88;
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.6 9.8C6.1 8.3 8.6 7 12 7c5.1 0 8.2 5 8.2 5a15.2 15.2 0 0 1-2.2 2.7' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M14.1 16.7a8.3 8.3 0 0 1-2.1.3c-5.1 0-8.2-5-8.2-5a14.9 14.9 0 0 1 1.8-2.3' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M5 5l14 14' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M10.4 10.7a2.5 2.5 0 0 0 2.9 2.9' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.6 9.8C6.1 8.3 8.6 7 12 7c5.1 0 8.2 5 8.2 5a15.2 15.2 0 0 1-2.2 2.7' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M14.1 16.7a8.3 8.3 0 0 1-2.1.3c-5.1 0-8.2-5-8.2-5a14.9 14.9 0 0 1 1.8-2.3' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M5 5l14 14' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M10.4 10.7a2.5 2.5 0 0 0 2.9 2.9' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}
#bm-window-filter .bm-filter-color-toggle {
cursor: pointer;
}
@ -733,13 +769,117 @@ input[type=file] {
#bm-window-filter .bm-filter-color:focus-within {
transform: translateY(-2px);
border-color: rgba(146, 221, 255, 0.26);
background:
linear-gradient(
160deg,
rgba(255, 255, 255, 0.22),
rgba(186, 246, 255, 0.1));
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 10px 24px rgba(0, 0, 0, 0.1);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color {
width: min(100%, 23.5rem);
max-width: 23.5rem;
min-height: 6.15rem;
display: grid;
grid-template-columns: minmax(0, 1.2fr) minmax(7.6rem, 0.8fr);
align-items: stretch;
gap: 0.48rem;
padding: 0.5rem;
color: var(--bm-filter-card-fg);
background-color: var(--bm-filter-card-bg);
background-image: none;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="-2"][data-state=shown] {
background-image:
conic-gradient(
#aa0000 0%,
#aaaa00 16.6%,
#00aa00 33.3%,
#00aaaa 50%,
#0000aa 66.6%,
#aa00aa 83.3%,
#aa0000 100%);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="-1"][data-state=shown],
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="0"][data-state=shown] {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 8 8" width="1em" height="1em"><path d="M0,0V8H16V16H8V0" fill="rgba(0,0,0,0.35)"/></svg>');
background-color: rgba(255, 255, 255, 0.18);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-state=hidden] {
color: var(--bm-filter-card-fg);
border-color: rgba(255, 255, 255, 0.16);
background-color: var(--bm-filter-card-bg);
background-image: none;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="-2"][data-state=hidden] {
background-image:
conic-gradient(
#aa0000 0%,
#aaaa00 16.6%,
#00aa00 33.3%,
#00aaaa 50%,
#0000aa 66.6%,
#aa00aa 83.3%,
#aa0000 100%);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="-1"][data-state=hidden],
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="0"][data-state=hidden] {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 8 8" width="1em" height="1em"><path d="M0,0V8H16V16H8V0" fill="rgba(0,0,0,0.28)"/></svg>');
background-color: rgba(255, 255, 255, 0.18);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-state=hidden]::before {
opacity: 0.16;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color > * {
position: relative;
z-index: 1;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-premium-star {
display: none;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-premium="1"] .bm-filter-premium-star {
position: absolute;
top: 50%;
right: -3.2rem;
z-index: 0;
display: block;
width: 10.5rem;
aspect-ratio: 1;
background: currentColor;
clip-path: polygon(50% 5%, 62% 38%, 98% 38%, 69% 59%, 80% 93%, 50% 72%, 20% 93%, 31% 59%, 2% 38%, 38% 38%);
opacity: 0.12;
pointer-events: none;
transform: translateY(-50%);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-premium="1"][data-state=hidden] .bm-filter-premium-star {
opacity: 0.18;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-main,
#bm-window-filter:not(.bm-windowed) .bm-filter-color-meta,
#bm-window-filter:not(.bm-windowed) .bm-filter-color-progress {
min-width: 0;
display: flex;
flex-direction: column;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-main {
justify-content: flex-start;
gap: 0.4rem;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-title {
min-width: 0;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-meta {
align-items: flex-end;
justify-content: space-between;
gap: 0.42rem;
text-align: right;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-progress {
align-items: flex-end;
gap: 0.08rem;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color .bm-filter-color-pxl-cnt {
font-family: var(--bm-font-display);
font-size: 1rem;
font-weight: 700;
line-height: 1.15;
overflow-wrap: anywhere;
}
#bm-window-filter .bm-filter-color-toggle:focus-visible {
outline: none;
border-color: rgba(116, 231, 255, 0.62);
@ -793,6 +933,22 @@ input[type=file] {
height: 1.55rem;
filter: drop-shadow(0 1px 0 rgba(255, 255, 255, 0.18));
}
#bm-window-filter:not(.bm-windowed) .bm-filter-container-rgb {
display: none;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-container-rgb button {
min-width: 3rem;
min-height: 3rem;
padding: 0;
color: currentColor !important;
pointer-events: none;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-container-rgb .bm-filter-eye-icon {
width: 2.75rem;
height: 2.75rem;
filter: none;
transform: translateY(0.08rem);
}
#bm-window-filter .bm-filter-color > .bm-flex-between {
flex-direction: column;
align-items: flex-start;
@ -801,12 +957,27 @@ input[type=file] {
#bm-window-filter .bm-filter-color h2 {
margin: 0.04rem 0 0;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color h2 {
display: block;
max-width: 100%;
margin: 0.08rem 0 0;
color: currentColor;
font-size: 1.02rem;
letter-spacing: 0;
line-height: 1.12;
overflow-wrap: anywhere;
}
#bm-window-filter .bm-filter-color .bm-filter-color-pxl-desc {
margin: 0.1rem 0 0;
}
#bm-window-filter .bm-filter-color small {
font-size: 0.75em;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color small {
color: currentColor;
letter-spacing: 0;
opacity: 0.82;
}
#bm-window-filter .bm-filter-color.bm-color-hide {
display: none;
}
@ -958,14 +1129,30 @@ input[type=file] {
width: min(100vw - 0.35rem, 50rem);
max-width: min(100vw - 0.35rem, 50rem) !important;
}
#bm-window-filter .bm-filter-insights {
#bm-window-filter .bm-filter-stat-grid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
#bm-window-filter .bm-filter-stat-card-wide {
grid-column: span 2;
}
}
@media (max-width: 620px) {
#bm-window-filter .bm-filter-stat-grid {
grid-template-columns: 1fr;
}
#bm-window-filter .bm-filter-note,
#bm-window-filter .bm-filter-sort-panel,
#bm-window-filter .bm-filter-insights > hr {
#bm-window-filter .bm-filter-stat-card-wide {
grid-column: auto;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color {
width: 100%;
max-width: none;
grid-template-columns: 1fr;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-meta,
#bm-window-filter:not(.bm-windowed) .bm-filter-color-progress {
align-items: flex-start;
text-align: left;
}
}
/* src/WindowMain.css */
@ -1215,4 +1402,4 @@ input[type=file] {
/* src/main.css */
/* Build Hash: 741f270e99de */
/* Build Hash: 893c29fe0ffa */

View file

@ -2535,7 +2535,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
button.onclick = () => __privateMethod(this, _WindowFilter_instances, selectColorList_fn).call(this, false);
}).buildElement().addButton({ "class": "bm-button-secondary", "textContent": "Show All Colors" }, (instance, button) => {
button.onclick = () => __privateMethod(this, _WindowFilter_instances, selectColorList_fn).call(this, true);
}).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-scrollable bm-filter-scrollable" }).addDiv({ "class": "bm-container bm-filter-insights", "style": "margin-left: 2.5ch; margin-right: 2.5ch;" }).addDiv({ "class": "bm-container bm-filter-stats-card" }).addSpan({ "id": "bm-filter-tile-load", "innerHTML": "<b>Tiles Loaded:</b> 0 / ???" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-correct", "innerHTML": "<b>Correct Pixels:</b> ???" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-total", "innerHTML": "<b>Total Pixels:</b> ???" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-remaining", "innerHTML": "<b>Complete:</b> ??? (???)" }).buildElement().addBr().buildElement().addSpan({ "id": "bm-filter-tot-completed", "innerHTML": "??? ???" }).buildElement().buildElement().addDiv({ "class": "bm-container bm-filter-note" }).addP({ "innerHTML": `Press the ${windowedIcon.replace("<svg", '<svg aria-label="Switch to windowed mode"')} button to make this window smaller. Colors with the icon ${this.eyeOpen.replace("<svg", '<svg aria-label="Eye Open"')} will be shown on the canvas. Colors with the icon ${this.eyeClosed.replace("<svg", '<svg aria-label="Eye Closed"')} will not be shown on the canvas. The "Hide All Colors" and "Show All Colors" buttons only apply to colors that display in the list below. The amount of correct pixels is dependent on how many tiles of the template you have loaded since you last opened Wplace.live. If all tiles have been loaded, then the "correct pixel" count is accurate.` }).buildElement().buildElement().addHr().buildElement().addForm({ "class": "bm-container bm-filter-sort-panel" }).addFieldset().addLegend({ "textContent": "Sort Options:", "style": "font-weight: 700;" }).buildElement().addDiv({ "class": "bm-container" }).addSelect({ "id": "bm-filter-sort-primary", "name": "sortPrimary", "textContent": "I want to view " }).addOption({ "value": "id", "textContent": "color IDs" }).buildElement().addOption({ "value": "name", "textContent": "color names" }).buildElement().addOption({ "value": "premium", "textContent": "premium colors" }).buildElement().addOption({ "value": "percent", "textContent": "percentage" }).buildElement().addOption({ "value": "correct", "textContent": "correct pixels" }).buildElement().addOption({ "value": "incorrect", "textContent": "incorrect pixels" }).buildElement().addOption({ "value": "total", "textContent": "total pixels" }).buildElement().buildElement().addSelect({ "id": "bm-filter-sort-secondary", "name": "sortSecondary", "textContent": " in " }).addOption({ "value": "ascending", "textContent": "ascending" }).buildElement().addOption({ "value": "descending", "textContent": "descending" }).buildElement().buildElement().addSpan({ "textContent": " order." }).buildElement().buildElement().addDiv({ "class": "bm-container" }).addCheckbox({ "id": "bm-filter-show-unused", "name": "showUnused", "textContent": "Show unused colors" }).buildElement().buildElement().buildElement().addDiv({ "class": "bm-container bm-filter-sort-actions" }).addButton({ "class": "bm-button-primary", "textContent": "Sort Colors", "type": "submit" }, (instance, button) => {
}).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container bm-scrollable bm-filter-scrollable" }).addDiv({ "class": "bm-container bm-filter-insights" }).addDiv({ "class": "bm-filter-stat-grid" }).addDiv({ "class": "bm-filter-stat-card" }).addSpan({ "class": "bm-filter-stat-label", "textContent": "Tiles" }).buildElement().addSpan({ "id": "bm-filter-tile-load", "class": "bm-filter-stat-value", "textContent": "0 / ???" }).buildElement().buildElement().addDiv({ "class": "bm-filter-stat-card" }).addSpan({ "class": "bm-filter-stat-label", "textContent": "Correct" }).buildElement().addSpan({ "id": "bm-filter-tot-correct", "class": "bm-filter-stat-value", "textContent": "???" }).buildElement().buildElement().addDiv({ "class": "bm-filter-stat-card" }).addSpan({ "class": "bm-filter-stat-label", "textContent": "Total" }).buildElement().addSpan({ "id": "bm-filter-tot-total", "class": "bm-filter-stat-value", "textContent": "???" }).buildElement().buildElement().addDiv({ "class": "bm-filter-stat-card" }).addSpan({ "class": "bm-filter-stat-label", "textContent": "Remaining" }).buildElement().addSpan({ "id": "bm-filter-tot-remaining", "class": "bm-filter-stat-value", "textContent": "???" }).buildElement().buildElement().addDiv({ "class": "bm-filter-stat-card bm-filter-stat-card-wide" }).addSpan({ "class": "bm-filter-stat-label", "textContent": "Finish At" }).buildElement().addSpan({ "id": "bm-filter-tot-completed", "class": "bm-filter-stat-value", "textContent": "???" }).buildElement().buildElement().buildElement().addHr().buildElement().addForm({ "class": "bm-container bm-filter-sort-panel" }).addFieldset().addLegend({ "textContent": "Sort Options:", "style": "font-weight: 700;" }).buildElement().addDiv({ "class": "bm-container" }).addSelect({ "id": "bm-filter-sort-primary", "name": "sortPrimary", "textContent": "I want to view " }).addOption({ "value": "id", "textContent": "color IDs" }).buildElement().addOption({ "value": "name", "textContent": "color names" }).buildElement().addOption({ "value": "premium", "textContent": "premium colors" }).buildElement().addOption({ "value": "percent", "textContent": "percentage" }).buildElement().addOption({ "value": "correct", "textContent": "correct pixels" }).buildElement().addOption({ "value": "incorrect", "textContent": "incorrect pixels" }).buildElement().addOption({ "value": "total", "textContent": "total pixels" }).buildElement().buildElement().addSelect({ "id": "bm-filter-sort-secondary", "name": "sortSecondary", "textContent": " in " }).addOption({ "value": "ascending", "textContent": "ascending" }).buildElement().addOption({ "value": "descending", "textContent": "descending" }).buildElement().buildElement().addSpan({ "textContent": " order." }).buildElement().buildElement().addDiv({ "class": "bm-container" }).addCheckbox({ "id": "bm-filter-show-unused", "name": "showUnused", "textContent": "Show unused colors" }).buildElement().buildElement().buildElement().addDiv({ "class": "bm-container bm-filter-sort-actions" }).addButton({ "class": "bm-button-primary", "textContent": "Sort Colors", "type": "submit" }, (instance, button) => {
button.onclick = (event) => {
event.preventDefault();
const formData = new FormData(document.querySelector(`#${this.windowID} form`));
@ -2552,11 +2552,11 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
__privateMethod(this, _WindowFilter_instances, buildColorList_fn).call(this, scrollableContainer);
__privateMethod(this, _WindowFilter_instances, syncSortFormControls_fn).call(this);
__privateMethod(this, _WindowFilter_instances, sortColorList_fn).call(this, this.sortPrimary, this.sortSecondary, this.showUnused);
this.updateInnerHTML("#bm-filter-tile-load", `<b>Tiles Loaded:</b> ${localizeNumber(this.tilesLoadedTotal)} / ${localizeNumber(this.tilesTotal)}`);
this.updateInnerHTML("#bm-filter-tot-correct", `<b>Correct Pixels:</b> ${localizeNumber(this.allPixelsCorrectTotal)}`);
this.updateInnerHTML("#bm-filter-tot-total", `<b>Total Pixels:</b> ${localizeNumber(this.allPixelsTotal)}`);
this.updateInnerHTML("#bm-filter-tot-remaining", `<b>Remaining:</b> ${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`);
this.updateInnerHTML("#bm-filter-tot-completed", `<b>Completed at:</b> <time datetime="${this.timeRemaining.toISOString().replace(/\.\d{3}Z$/, "Z")}">${this.timeRemainingLocalized}</time>`);
this.updateInnerHTML("#bm-filter-tile-load", `${localizeNumber(this.tilesLoadedTotal)} / ${localizeNumber(this.tilesTotal)}`);
this.updateInnerHTML("#bm-filter-tot-correct", localizeNumber(this.allPixelsCorrectTotal));
this.updateInnerHTML("#bm-filter-tot-total", localizeNumber(this.allPixelsTotal));
this.updateInnerHTML("#bm-filter-tot-remaining", `${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`);
this.updateInnerHTML("#bm-filter-tot-completed", `<time datetime="${this.timeRemaining.toISOString().replace(/\.\d{3}Z$/, "Z")}">${this.timeRemainingLocalized}</time>`);
__privateMethod(this, _WindowFilter_instances, startAutoRefresh_fn).call(this);
}
/** Spawns a windowed Color Filter window.
@ -2666,11 +2666,11 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
const allTotal = this.allPixelsTotal.toString().length > 7 ? this.allPixelsTotal.toString().slice(0, 2) + "\u2026" + this.allPixelsTotal.toString().slice(-3) : this.allPixelsTotal.toString();
this.updateInnerHTML("#bm-filter-windowed-color-totals", `${allCorrect}/${allTotal}`, true);
}
this.updateInnerHTML("#bm-filter-tile-load", `<b>Tiles Loaded:</b> ${localizeNumber(this.tilesLoadedTotal)} / ${localizeNumber(this.tilesTotal)}`);
this.updateInnerHTML("#bm-filter-tot-correct", `<b>Correct Pixels:</b> ${localizeNumber(this.allPixelsCorrectTotal)}`);
this.updateInnerHTML("#bm-filter-tot-total", `<b>Total Pixels:</b> ${localizeNumber(this.allPixelsTotal)}`);
this.updateInnerHTML("#bm-filter-tot-remaining", `<b>Remaining:</b> ${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`);
this.updateInnerHTML("#bm-filter-tot-completed", `<b>Completed at:</b> <time datetime="${this.timeRemaining.toISOString().replace(/\.\d{3}Z$/, "Z")}">${this.timeRemainingLocalized}</time>`);
this.updateInnerHTML("#bm-filter-tile-load", `${localizeNumber(this.tilesLoadedTotal)} / ${localizeNumber(this.tilesTotal)}`);
this.updateInnerHTML("#bm-filter-tot-correct", localizeNumber(this.allPixelsCorrectTotal));
this.updateInnerHTML("#bm-filter-tot-total", localizeNumber(this.allPixelsTotal));
this.updateInnerHTML("#bm-filter-tot-remaining", `${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`);
this.updateInnerHTML("#bm-filter-tot-completed", `<time datetime="${this.timeRemaining.toISOString().replace(/\.\d{3}Z$/, "Z")}">${this.timeRemainingLocalized}</time>`);
if (!colorList) {
return colorStatistics;
}
@ -2695,7 +2695,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
}
const pixelDesc = document.querySelector(`#${this.windowID} .bm-filter-color[data-id="${colorID}"] .bm-filter-color-pxl-desc`);
if (pixelDesc) {
pixelDesc.textContent = `${typeof colorIncorrect == "number" && !isNaN(colorIncorrect) ? colorIncorrect : "???"} incorrect pixel${colorIncorrect == 1 ? "" : "s"}. Completed: ${colorPercent}`;
pixelDesc.innerHTML = `${colorPercent} done<br>${typeof colorIncorrect == "number" && !isNaN(colorIncorrect) ? colorIncorrect : "???"} off`;
}
}
__privateMethod(this, _WindowFilter_instances, sortColorList_fn).call(this, this.sortPrimary, this.sortSecondary, this.showUnused);
@ -2973,6 +2973,9 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
textColorForPaletteColorBackground = "transparent";
}
const bgEffectForButtons = textColorForPaletteColorBackground == "white" ? "bm-button-hover-white" : "bm-button-hover-black";
const colorRGB = color.rgb?.map((channel) => Number(channel) || 0).join(",");
const colorCardText = color.id == -2 || color.id == -1 || color.id == 0 ? "white" : textColorForPaletteColorBackground;
const colorCardStyle = `--bm-filter-card-bg: rgb(${colorRGB}); --bm-filter-card-fg: ${colorCardText};`;
const {
colorCorrect,
colorCorrectLocalized,
@ -2990,13 +2993,14 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
"data-id": color.id,
"data-name": color.name,
"data-premium": +color.premium,
"data-state": isColorHidden ? "hidden" : "shown",
"data-correct": !Number.isNaN(parseInt(colorCorrect)) ? colorCorrect : "0",
"data-total": colorTotal,
"data-percent": colorPercent.slice(-1) == "%" ? colorPercent.slice(0, -1) : "0",
"data-incorrect": colorIncorrect || 0
}, (instance, div) => __privateMethod(this, _WindowFilter_instances, initializeColorBlockToggle_fn).call(this, div, color)).addDiv({ "class": "bm-filter-container-rgb", "style": `background-color: rgb(${color.rgb?.map((channel) => Number(channel) || 0).join(",")});${color.premium ? styleBackgroundStar : ""}` }).addButton(
{
"class": "bm-button-trans " + bgEffectForButtons,
"class": "bm-button-trans bm-filter-color-visibility " + bgEffectForButtons,
"data-state": isColorHidden ? "hidden" : "shown",
"aria-label": isColorHidden ? `Show the color ${color.name || ""} on templates.` : `Hide the color ${color.name || ""} on templates.`,
"innerHTML": isColorHidden ? this.eyeClosed : this.eyeOpen,
@ -3016,20 +3020,22 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
} else {
colorList.addDiv({
"class": "bm-container bm-filter-color bm-flex-between",
"style": colorCardStyle,
"data-id": color.id,
"data-name": color.name,
"data-premium": +color.premium,
"data-state": isColorHidden ? "hidden" : "shown",
"data-correct": !Number.isNaN(parseInt(colorCorrect)) ? colorCorrect : "0",
"data-total": colorTotal,
"data-percent": colorPercent.slice(-1) == "%" ? colorPercent.slice(0, -1) : "0",
"data-incorrect": colorIncorrect || 0
}, (instance, div) => __privateMethod(this, _WindowFilter_instances, initializeColorBlockToggle_fn).call(this, div, color)).addDiv({ "class": "bm-flex-center", "style": "flex-direction: column;" }).addDiv({ "class": "bm-filter-container-rgb", "style": `background-color: rgb(${color.rgb?.map((channel) => Number(channel) || 0).join(",")});` }).addButton(
}, (instance, div) => __privateMethod(this, _WindowFilter_instances, initializeColorBlockToggle_fn).call(this, div, color)).addDiv({ "class": "bm-filter-premium-star", "aria-hidden": "true" }).buildElement().addDiv({ "class": "bm-filter-color-main" }).addDiv({ "class": "bm-filter-container-rgb" }).addButton(
{
"class": "bm-button-trans " + bgEffectForButtons,
"class": "bm-button-trans bm-filter-color-visibility " + bgEffectForButtons,
"data-state": isColorHidden ? "hidden" : "shown",
"aria-label": isColorHidden ? `Show the color ${color.name || ""} on templates.` : `Hide the color ${color.name || ""} on templates.`,
"innerHTML": isColorHidden ? this.eyeClosed : this.eyeOpen,
"style": `color: ${textColorForPaletteColorBackground};`
"style": `color: ${colorCardText};`
},
(instance, button) => {
button.onclick = (event) => {
@ -3041,7 +3047,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
}
__privateMethod(this, _WindowFilter_instances, syncColorToggleLabel_fn).call(this, button, color);
}
).buildElement().buildElement().addSmall({ "textContent": color.id == -2 ? "???????" : colorValueHex }).buildElement().buildElement().addDiv({ "class": "bm-flex-between" }).addHeader(2, { "textContent": (color.premium ? "\u2605 " : "") + color.name }).buildElement().addDiv({ "class": "bm-flex-between", "style": "gap: 1.5ch;" }).addSmall({ "textContent": `#${color.id.toString().padStart(2, 0)}` }).buildElement().addSmall({ "class": "bm-filter-color-pxl-cnt", "textContent": `${colorCorrectLocalized} / ${colorTotalLocalized}` }).buildElement().buildElement().addP({ "class": "bm-filter-color-pxl-desc", "textContent": `${typeof colorIncorrect == "number" && !isNaN(colorIncorrect) ? colorIncorrect : "???"} incorrect pixel${colorIncorrect == 1 ? "" : "s"}. Completed: ${colorPercent}` }).buildElement().buildElement().buildElement();
).buildElement().buildElement().addDiv({ "class": "bm-filter-color-title" }).addSmall({ "textContent": `#${color.id.toString().padStart(2, 0)} / ${color.id == -2 ? "mixed" : colorValueHex}` }).buildElement().addHeader(2, { "textContent": color.name }).buildElement().buildElement().buildElement().addDiv({ "class": "bm-filter-color-meta" }).addDiv({ "class": "bm-filter-color-progress" }).addSpan({ "class": "bm-filter-color-pxl-cnt", "textContent": `${colorCorrectLocalized} / ${colorTotalLocalized}` }).buildElement().addSmall({ "class": "bm-filter-color-pxl-desc", "innerHTML": `${colorPercent} done<br>${typeof colorIncorrect == "number" && !isNaN(colorIncorrect) ? colorIncorrect : "???"} off` }).buildElement().buildElement().buildElement().buildElement();
}
}
colorList.buildOverlay(parentElement);
@ -3093,7 +3099,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
if (color.classList?.contains("bm-color-hide")) {
continue;
}
const button = color.querySelector(".bm-filter-container-rgb button");
const button = color.querySelector(".bm-filter-color-visibility");
if (button.dataset["state"] == "hidden" && !userWantsUnselect) {
continue;
}
@ -3111,7 +3117,9 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
syncColorToggleLabel_fn = function(button, color) {
const ariaLabel = button.dataset["state"] == "hidden" ? `Show the color ${color.name || ""} on templates.` : `Hide the color ${color.name || ""} on templates.`;
button.ariaLabel = ariaLabel;
button.closest(".bm-filter-color")?.setAttribute("aria-label", ariaLabel);
const colorElement = button.closest(".bm-filter-color");
colorElement?.setAttribute("aria-label", ariaLabel);
colorElement?.setAttribute("data-state", button.dataset["state"]);
};
/** Toggles a color from the clickable color block or its icon.
* @param {HTMLButtonElement} button - The color visibility button
@ -3153,7 +3161,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
if (event.target instanceof Element && event.target.closest("button, a, input, select, textarea")) {
return;
}
const button = colorElement.querySelector(".bm-filter-container-rgb button");
const button = colorElement.querySelector(".bm-filter-color-visibility");
__privateMethod(this, _WindowFilter_instances, toggleColorVisibility_fn).call(this, button, color);
};
colorElement.onkeydown = (event) => {
@ -4652,4 +4660,4 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String
}
})();
// Build Hash: f552d070dbe3
// Build Hash: a2ac3a13a36f

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -47,22 +47,20 @@
}
#bm-window-filter .bm-filter-insights {
display: block;
margin: 0 0.18rem;
}
#bm-window-filter .bm-filter-stat-grid {
display: grid;
grid-template-columns: minmax(16rem, 20rem) minmax(0, 1fr);
gap: 0.24rem 0.3rem;
align-items: stretch;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 0.24rem;
}
#bm-window-filter .bm-filter-insights > hr,
#bm-window-filter .bm-filter-stat-card,
#bm-window-filter .bm-filter-sort-panel {
grid-column: 1 / -1;
}
#bm-window-filter .bm-filter-stats-card,
#bm-window-filter .bm-filter-note,
#bm-window-filter .bm-filter-sort-panel {
padding: 0.38rem 0.48rem;
border-radius: 13px;
min-width: 0;
border-radius: 11px;
border: 1px solid rgba(255, 255, 255, 0.18);
background: linear-gradient(155deg, rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.07));
box-shadow:
@ -70,24 +68,41 @@
0 8px 20px rgba(0, 0, 0, 0.08);
}
#bm-window-filter .bm-filter-stats-card {
display: grid;
gap: 0.18rem;
#bm-window-filter .bm-filter-stat-card {
min-height: 2.7rem;
display: flex;
flex-direction: column;
justify-content: center;
gap: 0.08rem;
padding: 0.34rem 0.45rem;
color: rgba(18, 35, 63, 0.96);
line-height: 1.22;
}
#bm-window-filter .bm-filter-stats-card br {
display: none;
#bm-window-filter .bm-filter-stat-label {
color: rgba(49, 71, 105, 0.82);
font-size: 0.62rem;
letter-spacing: 0;
font-family: var(--bm-font-display);
text-transform: uppercase;
}
#bm-window-filter .bm-filter-stats-card span {
display: block;
padding: 0.28rem 0.38rem;
border-radius: 10px;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2), rgba(255, 255, 255, 0.08));
#bm-window-filter .bm-filter-stat-value {
display: inline-block;
min-width: 0;
color: rgba(15, 31, 56, 0.96);
font-size: 1.04em;
font-weight: 700;
overflow-wrap: anywhere;
}
#bm-window-filter .bm-filter-note p {
margin: 0;
#bm-window-filter .bm-filter-stat-card time {
font-family: var(--bm-font-mono);
letter-spacing: 0;
}
#bm-window-filter .bm-filter-sort-panel {
padding: 0.38rem 0.48rem;
}
#bm-window-filter .bm-filter-sort-panel fieldset {
@ -119,9 +134,9 @@
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
justify-content: flex-start;
align-items: stretch;
gap: 0.3rem;
gap: 0.38rem;
}
/* Filter color */
@ -155,6 +170,31 @@
radial-gradient(circle at 18% 0%, rgba(186, 246, 255, 0.12), transparent 22%);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color::before {
background: linear-gradient(180deg, rgba(255, 255, 255, 0.08), rgba(0, 0, 0, 0.04));
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color::after {
content: "";
position: absolute;
left: 0.52rem;
bottom: 0.46rem;
width: 1.65rem;
height: 1.65rem;
background: currentColor;
opacity: 0.72;
pointer-events: none;
z-index: 0;
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3.8 12s3.1-5 8.2-5 8.2 5 8.2 5-3.1 5-8.2 5-8.2-5-8.2-5Z' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Ccircle cx='12' cy='12' r='2.5' fill='none' stroke='black' stroke-width='1.9'/%3E%3C/svg%3E") center / contain no-repeat;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M3.8 12s3.1-5 8.2-5 8.2 5 8.2 5-3.1 5-8.2 5-8.2-5-8.2-5Z' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Ccircle cx='12' cy='12' r='2.5' fill='none' stroke='black' stroke-width='1.9'/%3E%3C/svg%3E") center / contain no-repeat;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-state="hidden"]::after {
opacity: 0.88;
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.6 9.8C6.1 8.3 8.6 7 12 7c5.1 0 8.2 5 8.2 5a15.2 15.2 0 0 1-2.2 2.7' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M14.1 16.7a8.3 8.3 0 0 1-2.1.3c-5.1 0-8.2-5-8.2-5a14.9 14.9 0 0 1 1.8-2.3' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M5 5l14 14' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M10.4 10.7a2.5 2.5 0 0 0 2.9 2.9' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M4.6 9.8C6.1 8.3 8.6 7 12 7c5.1 0 8.2 5 8.2 5a15.2 15.2 0 0 1-2.2 2.7' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M14.1 16.7a8.3 8.3 0 0 1-2.1.3c-5.1 0-8.2-5-8.2-5a14.9 14.9 0 0 1 1.8-2.3' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M5 5l14 14' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M10.4 10.7a2.5 2.5 0 0 0 2.9 2.9' fill='none' stroke='black' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}
#bm-window-filter .bm-filter-color-toggle {
cursor: pointer;
}
@ -164,12 +204,138 @@
#bm-window-filter .bm-filter-color:focus-within {
transform: translateY(-2px);
border-color: rgba(146, 221, 255, 0.26);
background: linear-gradient(160deg, rgba(255, 255, 255, 0.22), rgba(186, 246, 255, 0.1));
box-shadow:
inset 0 1px 0 rgba(255, 255, 255, 0.2),
0 10px 24px rgba(0, 0, 0, 0.1);
}
/* Fullscreen filter color cards */
#bm-window-filter:not(.bm-windowed) .bm-filter-color {
width: min(100%, 23.5rem);
max-width: 23.5rem;
min-height: 6.15rem;
display: grid;
grid-template-columns: minmax(0, 1.2fr) minmax(7.6rem, 0.8fr);
align-items: stretch;
gap: 0.48rem;
padding: 0.5rem;
color: var(--bm-filter-card-fg);
background-color: var(--bm-filter-card-bg);
background-image: none;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="-2"][data-state="shown"] {
background-image: conic-gradient(
#aa0000 0%,
#aaaa00 16.6%,
#00aa00 33.3%,
#00aaaa 50%,
#0000aa 66.6%,
#aa00aa 83.3%,
#aa0000 100%
);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="-1"][data-state="shown"],
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="0"][data-state="shown"] {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 8 8" width="1em" height="1em"><path d="M0,0V8H16V16H8V0" fill="rgba(0,0,0,0.35)"/></svg>');
background-color: rgba(255, 255, 255, 0.18);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-state="hidden"] {
color: var(--bm-filter-card-fg);
border-color: rgba(255, 255, 255, 0.16);
background-color: var(--bm-filter-card-bg);
background-image: none;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="-2"][data-state="hidden"] {
background-image: conic-gradient(
#aa0000 0%,
#aaaa00 16.6%,
#00aa00 33.3%,
#00aaaa 50%,
#0000aa 66.6%,
#aa00aa 83.3%,
#aa0000 100%
);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="-1"][data-state="hidden"],
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-id="0"][data-state="hidden"] {
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewbox="0 0 8 8" width="1em" height="1em"><path d="M0,0V8H16V16H8V0" fill="rgba(0,0,0,0.28)"/></svg>');
background-color: rgba(255, 255, 255, 0.18);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-state="hidden"]::before {
opacity: 0.16;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color > * {
position: relative;
z-index: 1;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-premium-star {
display: none;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-premium="1"] .bm-filter-premium-star {
position: absolute;
top: 50%;
right: -3.2rem;
z-index: 0;
display: block;
width: 10.5rem;
aspect-ratio: 1;
background: currentColor;
clip-path: polygon(50% 5%, 62% 38%, 98% 38%, 69% 59%, 80% 93%, 50% 72%, 20% 93%, 31% 59%, 2% 38%, 38% 38%);
opacity: 0.12;
pointer-events: none;
transform: translateY(-50%);
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-premium="1"][data-state="hidden"] .bm-filter-premium-star {
opacity: 0.18;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-main,
#bm-window-filter:not(.bm-windowed) .bm-filter-color-meta,
#bm-window-filter:not(.bm-windowed) .bm-filter-color-progress {
min-width: 0;
display: flex;
flex-direction: column;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-main {
justify-content: flex-start;
gap: 0.4rem;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-title {
min-width: 0;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-meta {
align-items: flex-end;
justify-content: space-between;
gap: 0.42rem;
text-align: right;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-progress {
align-items: flex-end;
gap: 0.08rem;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color .bm-filter-color-pxl-cnt {
font-family: var(--bm-font-display);
font-size: 1rem;
font-weight: 700;
line-height: 1.15;
overflow-wrap: anywhere;
}
#bm-window-filter .bm-filter-color-toggle:focus-visible {
outline: none;
border-color: rgba(116, 231, 255, 0.62);
@ -239,6 +405,25 @@
filter: drop-shadow(0 1px 0 rgba(255, 255, 255, 0.18));
}
#bm-window-filter:not(.bm-windowed) .bm-filter-container-rgb {
display: none;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-container-rgb button {
min-width: 3rem;
min-height: 3rem;
padding: 0;
color: currentColor !important;
pointer-events: none;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-container-rgb .bm-filter-eye-icon {
width: 2.75rem;
height: 2.75rem;
filter: none;
transform: translateY(0.08rem);
}
/* Filter window container for color information */
#bm-window-filter .bm-filter-color > .bm-flex-between {
flex-direction: column;
@ -250,6 +435,17 @@
margin: 0.04rem 0 0;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color h2 {
display: block;
max-width: 100%;
margin: 0.08rem 0 0;
color: currentColor;
font-size: 1.02rem;
letter-spacing: 0;
line-height: 1.12;
overflow-wrap: anywhere;
}
#bm-window-filter .bm-filter-color .bm-filter-color-pxl-desc {
margin: 0.1rem 0 0;
}
@ -259,6 +455,12 @@
font-size: 0.75em;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color small {
color: currentColor;
letter-spacing: 0;
opacity: 0.82;
}
/* Filter window hide unused colors */
#bm-window-filter .bm-filter-color.bm-color-hide {
display: none;
@ -439,13 +641,33 @@
max-width: min(100vw - 0.35rem, 50rem) !important;
}
#bm-window-filter .bm-filter-insights {
#bm-window-filter .bm-filter-stat-grid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
#bm-window-filter .bm-filter-stat-card-wide {
grid-column: span 2;
}
}
@media (max-width: 620px) {
#bm-window-filter .bm-filter-stat-grid {
grid-template-columns: 1fr;
}
#bm-window-filter .bm-filter-note,
#bm-window-filter .bm-filter-sort-panel,
#bm-window-filter .bm-filter-insights > hr {
#bm-window-filter .bm-filter-stat-card-wide {
grid-column: auto;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color {
width: 100%;
max-width: none;
grid-template-columns: 1fr;
}
#bm-window-filter:not(.bm-windowed) .bm-filter-color-meta,
#bm-window-filter:not(.bm-windowed) .bm-filter-color-progress {
align-items: flex-start;
text-align: left;
}
}

View file

@ -133,20 +133,28 @@ export default class WindowFilter extends Overlay {
.buildElement()
.addHr().buildElement()
.addDiv({'class': 'bm-container bm-scrollable bm-filter-scrollable'})
.addDiv({'class': 'bm-container bm-filter-insights', 'style': 'margin-left: 2.5ch; margin-right: 2.5ch;'})
.addDiv({'class': 'bm-container bm-filter-stats-card'})
.addSpan({'id': 'bm-filter-tile-load', 'innerHTML': '<b>Tiles Loaded:</b> 0 / ???'}).buildElement()
.addBr().buildElement()
.addSpan({'id': 'bm-filter-tot-correct', 'innerHTML': '<b>Correct Pixels:</b> ???'}).buildElement()
.addBr().buildElement()
.addSpan({'id': 'bm-filter-tot-total', 'innerHTML': '<b>Total Pixels:</b> ???'}).buildElement()
.addBr().buildElement()
.addSpan({'id': 'bm-filter-tot-remaining', 'innerHTML': '<b>Complete:</b> ??? (???)'}).buildElement()
.addBr().buildElement()
.addSpan({'id': 'bm-filter-tot-completed', 'innerHTML': '??? ???'}).buildElement()
.buildElement()
.addDiv({'class': 'bm-container bm-filter-note'})
.addP({'innerHTML': `Press the ${windowedIcon.replace('<svg', '<svg aria-label="Switch to windowed mode"')} button to make this window smaller. Colors with the icon ${this.eyeOpen.replace('<svg', '<svg aria-label="Eye Open"')} will be shown on the canvas. Colors with the icon ${this.eyeClosed.replace('<svg', '<svg aria-label="Eye Closed"')} will not be shown on the canvas. The "Hide All Colors" and "Show All Colors" buttons only apply to colors that display in the list below. The amount of correct pixels is dependent on how many tiles of the template you have loaded since you last opened Wplace.live. If all tiles have been loaded, then the "correct pixel" count is accurate.`}).buildElement()
.addDiv({'class': 'bm-container bm-filter-insights'})
.addDiv({'class': 'bm-filter-stat-grid'})
.addDiv({'class': 'bm-filter-stat-card'})
.addSpan({'class': 'bm-filter-stat-label', 'textContent': 'Tiles'}).buildElement()
.addSpan({'id': 'bm-filter-tile-load', 'class': 'bm-filter-stat-value', 'textContent': '0 / ???'}).buildElement()
.buildElement()
.addDiv({'class': 'bm-filter-stat-card'})
.addSpan({'class': 'bm-filter-stat-label', 'textContent': 'Correct'}).buildElement()
.addSpan({'id': 'bm-filter-tot-correct', 'class': 'bm-filter-stat-value', 'textContent': '???'}).buildElement()
.buildElement()
.addDiv({'class': 'bm-filter-stat-card'})
.addSpan({'class': 'bm-filter-stat-label', 'textContent': 'Total'}).buildElement()
.addSpan({'id': 'bm-filter-tot-total', 'class': 'bm-filter-stat-value', 'textContent': '???'}).buildElement()
.buildElement()
.addDiv({'class': 'bm-filter-stat-card'})
.addSpan({'class': 'bm-filter-stat-label', 'textContent': 'Remaining'}).buildElement()
.addSpan({'id': 'bm-filter-tot-remaining', 'class': 'bm-filter-stat-value', 'textContent': '???'}).buildElement()
.buildElement()
.addDiv({'class': 'bm-filter-stat-card bm-filter-stat-card-wide'})
.addSpan({'class': 'bm-filter-stat-label', 'textContent': 'Finish At'}).buildElement()
.addSpan({'id': 'bm-filter-tot-completed', 'class': 'bm-filter-stat-value', 'textContent': '???'}).buildElement()
.buildElement()
.buildElement()
.addHr().buildElement()
.addForm({'class': 'bm-container bm-filter-sort-panel'})
@ -209,11 +217,11 @@ export default class WindowFilter extends Overlay {
this.#sortColorList(this.sortPrimary, this.sortSecondary, this.showUnused);
// Displays some template statistics to the user
this.updateInnerHTML('#bm-filter-tile-load', `<b>Tiles Loaded:</b> ${localizeNumber(this.tilesLoadedTotal)} / ${localizeNumber(this.tilesTotal)}`);
this.updateInnerHTML('#bm-filter-tot-correct', `<b>Correct Pixels:</b> ${localizeNumber(this.allPixelsCorrectTotal)}`);
this.updateInnerHTML('#bm-filter-tot-total', `<b>Total Pixels:</b> ${localizeNumber(this.allPixelsTotal)}`);
this.updateInnerHTML('#bm-filter-tot-remaining', `<b>Remaining:</b> ${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`);
this.updateInnerHTML('#bm-filter-tot-completed', `<b>Completed at:</b> <time datetime="${this.timeRemaining.toISOString().replace(/\.\d{3}Z$/, 'Z')}">${this.timeRemainingLocalized}</time>`);
this.updateInnerHTML('#bm-filter-tile-load', `${localizeNumber(this.tilesLoadedTotal)} / ${localizeNumber(this.tilesTotal)}`);
this.updateInnerHTML('#bm-filter-tot-correct', localizeNumber(this.allPixelsCorrectTotal));
this.updateInnerHTML('#bm-filter-tot-total', localizeNumber(this.allPixelsTotal));
this.updateInnerHTML('#bm-filter-tot-remaining', `${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`);
this.updateInnerHTML('#bm-filter-tot-completed', `<time datetime="${this.timeRemaining.toISOString().replace(/\.\d{3}Z$/, 'Z')}">${this.timeRemainingLocalized}</time>`);
this.#startAutoRefresh();
}
@ -606,6 +614,11 @@ export default class WindowFilter extends Overlay {
// Changes the luminance of the hover/focus button effect
const bgEffectForButtons = (textColorForPaletteColorBackground == 'white') ? 'bm-button-hover-white' : 'bm-button-hover-black';
const colorRGB = color.rgb?.map(channel => Number(channel) || 0).join(',');
const colorCardText = ((color.id == -2) || (color.id == -1) || (color.id == 0))
? 'white'
: textColorForPaletteColorBackground;
const colorCardStyle = `--bm-filter-card-bg: rgb(${colorRGB}); --bm-filter-card-fg: ${colorCardText};`;
// Generated by #updateColorList()
const {
@ -631,6 +644,7 @@ export default class WindowFilter extends Overlay {
'data-id': color.id,
'data-name': color.name,
'data-premium': +color.premium,
'data-state': isColorHidden ? 'hidden' : 'shown',
'data-correct': !Number.isNaN(parseInt(colorCorrect)) ? colorCorrect : '0',
'data-total': colorTotal,
'data-percent': (colorPercent.slice(-1) == '%') ? colorPercent.slice(0, -1) : '0',
@ -638,7 +652,7 @@ export default class WindowFilter extends Overlay {
}, (instance, div) => this.#initializeColorBlockToggle(div, color))
.addDiv({'class': 'bm-filter-container-rgb', 'style': `background-color: rgb(${color.rgb?.map(channel => Number(channel) || 0).join(',')});${color.premium ? styleBackgroundStar : ''}`})
.addButton({
'class': 'bm-button-trans ' + bgEffectForButtons,
'class': 'bm-button-trans bm-filter-color-visibility ' + bgEffectForButtons,
'data-state': isColorHidden ? 'hidden' : 'shown',
'aria-label': isColorHidden ? `Show the color ${color.name || ''} on templates.` : `Hide the color ${color.name || ''} on templates.`,
'innerHTML': isColorHidden ? this.eyeClosed : this.eyeOpen,
@ -666,22 +680,25 @@ export default class WindowFilter extends Overlay {
// Add fullscreen mode color DOM to color list
colorList.addDiv({'class': 'bm-container bm-filter-color bm-flex-between',
'style': colorCardStyle,
'data-id': color.id,
'data-name': color.name,
'data-premium': +color.premium,
'data-state': isColorHidden ? 'hidden' : 'shown',
'data-correct': !Number.isNaN(parseInt(colorCorrect)) ? colorCorrect : '0',
'data-total': colorTotal,
'data-percent': (colorPercent.slice(-1) == '%') ? colorPercent.slice(0, -1) : '0',
'data-incorrect': colorIncorrect || 0
}, (instance, div) => this.#initializeColorBlockToggle(div, color))
.addDiv({'class': 'bm-flex-center', 'style': 'flex-direction: column;'})
.addDiv({'class': 'bm-filter-container-rgb', 'style': `background-color: rgb(${color.rgb?.map(channel => Number(channel) || 0).join(',')});`})
.addDiv({'class': 'bm-filter-premium-star', 'aria-hidden': 'true'}).buildElement()
.addDiv({'class': 'bm-filter-color-main'})
.addDiv({'class': 'bm-filter-container-rgb'})
.addButton({
'class': 'bm-button-trans ' + bgEffectForButtons,
'class': 'bm-button-trans bm-filter-color-visibility ' + bgEffectForButtons,
'data-state': isColorHidden ? 'hidden' : 'shown',
'aria-label': isColorHidden ? `Show the color ${color.name || ''} on templates.` : `Hide the color ${color.name || ''} on templates.`,
'innerHTML': isColorHidden ? this.eyeClosed : this.eyeOpen,
'style': `color: ${textColorForPaletteColorBackground};`},
'style': `color: ${colorCardText};`},
(instance, button) => {
// When the button is clicked
@ -696,15 +713,16 @@ export default class WindowFilter extends Overlay {
}
).buildElement()
.buildElement()
.addSmall({'textContent': (color.id == -2) ? '???????' : colorValueHex}).buildElement()
.buildElement()
.addDiv({'class': 'bm-flex-between'})
.addHeader(2, {'textContent': (color.premium ? '★ ' : '') + color.name}).buildElement()
.addDiv({'class': 'bm-flex-between', 'style': 'gap: 1.5ch;'})
.addSmall({'textContent': `#${color.id.toString().padStart(2, 0)}`}).buildElement()
.addSmall({'class': 'bm-filter-color-pxl-cnt', 'textContent': `${colorCorrectLocalized} / ${colorTotalLocalized}`}).buildElement()
.addDiv({'class': 'bm-filter-color-title'})
.addSmall({'textContent': `#${color.id.toString().padStart(2, 0)} / ${(color.id == -2) ? 'mixed' : colorValueHex}`}).buildElement()
.addHeader(2, {'textContent': color.name}).buildElement()
.buildElement()
.buildElement()
.addDiv({'class': 'bm-filter-color-meta'})
.addDiv({'class': 'bm-filter-color-progress'})
.addSpan({'class': 'bm-filter-color-pxl-cnt', 'textContent': `${colorCorrectLocalized} / ${colorTotalLocalized}`}).buildElement()
.addSmall({'class': 'bm-filter-color-pxl-desc', 'innerHTML': `${colorPercent} done<br>${((typeof colorIncorrect == 'number') && !isNaN(colorIncorrect)) ? colorIncorrect : '???'} off`}).buildElement()
.buildElement()
.addP({'class': 'bm-filter-color-pxl-desc', 'textContent': `${((typeof colorIncorrect == 'number') && !isNaN(colorIncorrect)) ? colorIncorrect : '???'} incorrect pixel${(colorIncorrect == 1) ? '' : 's'}. Completed: ${colorPercent}`}).buildElement()
.buildElement()
.buildElement();
}
@ -784,7 +802,7 @@ export default class WindowFilter extends Overlay {
if (color.classList?.contains('bm-color-hide')) {continue;}
// Gets the button to click
const button = color.querySelector('.bm-filter-container-rgb button');
const button = color.querySelector('.bm-filter-color-visibility');
// Exits early if the button is in its proper state
if ((button.dataset['state'] == 'hidden') && !userWantsUnselect) {continue;} // If the button is selected, and the user wants to select all buttons, then skip this one
@ -805,7 +823,11 @@ export default class WindowFilter extends Overlay {
: `Hide the color ${color.name || ''} on templates.`;
button.ariaLabel = ariaLabel;
button.closest('.bm-filter-color')?.setAttribute('aria-label', ariaLabel);
const colorElement = button.closest('.bm-filter-color');
colorElement?.setAttribute('aria-label', ariaLabel);
colorElement?.setAttribute('data-state', button.dataset['state']);
}
/** Toggles a color from the clickable color block or its icon.
@ -849,7 +871,7 @@ export default class WindowFilter extends Overlay {
colorElement.onclick = event => {
if (event.target instanceof Element && event.target.closest('button, a, input, select, textarea')) {return;}
const button = colorElement.querySelector('.bm-filter-container-rgb button');
const button = colorElement.querySelector('.bm-filter-color-visibility');
this.#toggleColorVisibility(button, color);
};
@ -944,11 +966,11 @@ export default class WindowFilter extends Overlay {
this.updateInnerHTML('#bm-filter-windowed-color-totals', `${allCorrect}/${allTotal}`, true);
}
this.updateInnerHTML('#bm-filter-tile-load', `<b>Tiles Loaded:</b> ${localizeNumber(this.tilesLoadedTotal)} / ${localizeNumber(this.tilesTotal)}`);
this.updateInnerHTML('#bm-filter-tot-correct', `<b>Correct Pixels:</b> ${localizeNumber(this.allPixelsCorrectTotal)}`);
this.updateInnerHTML('#bm-filter-tot-total', `<b>Total Pixels:</b> ${localizeNumber(this.allPixelsTotal)}`);
this.updateInnerHTML('#bm-filter-tot-remaining', `<b>Remaining:</b> ${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`);
this.updateInnerHTML('#bm-filter-tot-completed', `<b>Completed at:</b> <time datetime="${this.timeRemaining.toISOString().replace(/\.\d{3}Z$/, 'Z')}">${this.timeRemainingLocalized}</time>`);
this.updateInnerHTML('#bm-filter-tile-load', `${localizeNumber(this.tilesLoadedTotal)} / ${localizeNumber(this.tilesTotal)}`);
this.updateInnerHTML('#bm-filter-tot-correct', localizeNumber(this.allPixelsCorrectTotal));
this.updateInnerHTML('#bm-filter-tot-total', localizeNumber(this.allPixelsTotal));
this.updateInnerHTML('#bm-filter-tot-remaining', `${localizeNumber((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0))} (${localizePercent(((this.allPixelsTotal || 0) - (this.allPixelsCorrectTotal || 0)) / (this.allPixelsTotal || 1))})`);
this.updateInnerHTML('#bm-filter-tot-completed', `<time datetime="${this.timeRemaining.toISOString().replace(/\.\d{3}Z$/, 'Z')}">${this.timeRemainingLocalized}</time>`);
// Return early if the color list does not exist.
// We can't update DOM elements that don't exist, so we exit now.
@ -983,7 +1005,7 @@ export default class WindowFilter extends Overlay {
// Updates the pixel description if it exists
const pixelDesc = document.querySelector(`#${this.windowID} .bm-filter-color[data-id="${colorID}"] .bm-filter-color-pxl-desc`);
if (pixelDesc) {pixelDesc.textContent = `${((typeof colorIncorrect == 'number') && !isNaN(colorIncorrect)) ? colorIncorrect : '???'} incorrect pixel${(colorIncorrect == 1) ? '' : 's'}. Completed: ${colorPercent}`;}
if (pixelDesc) {pixelDesc.innerHTML = `${colorPercent} done<br>${((typeof colorIncorrect == 'number') && !isNaN(colorIncorrect)) ? colorIncorrect : '???'} off`;}
}
// Since the dataset has changed, we need to sort again