mirror of
https://github.com/SwingTheVine/Wplace-BlueMarble.git
synced 2026-03-11 17:15:38 +00:00
Added color filter table
This commit is contained in:
parent
1f2d86f73c
commit
fdb571ac6b
14 changed files with 1031 additions and 32 deletions
105
dist/BlueMarble-For-GreasyFork.user.css
vendored
105
dist/BlueMarble-For-GreasyFork.user.css
vendored
|
|
@ -1,4 +1,15 @@
|
|||
/* src/overlay.css */
|
||||
.bm-screenreader {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
.bm-window {
|
||||
position: fixed;
|
||||
background-color: rgba(21, 48, 99, 0.9);
|
||||
|
|
@ -10,6 +21,7 @@
|
|||
top: 75px;
|
||||
left: 60px;
|
||||
width: auto;
|
||||
max-height: calc(100vh - 150px);
|
||||
max-width: calc(100% - 135px);
|
||||
font-family:
|
||||
"Roboto Mono",
|
||||
|
|
@ -114,6 +126,23 @@
|
|||
margin: 0 auto;
|
||||
fill: #111;
|
||||
}
|
||||
.bm-window button.bm-button-trans {
|
||||
background-color: unset;
|
||||
}
|
||||
.bm-button-trans.bm-button-hover-white:hover,
|
||||
.bm-button-trans.bm-button-hover-white:focus {
|
||||
background-color: rgba(255, 255, 255, 0.17);
|
||||
}
|
||||
.bm-button-trans.bm-button-hover-white:active {
|
||||
background-color: rgba(255, 255, 255, 0.22);
|
||||
}
|
||||
.bm-button-trans.bm-button-hover-black:hover,
|
||||
.bm-button-trans.bm-button-hover-black:focus {
|
||||
background-color: rgba(0, 0, 0, 0.17);
|
||||
}
|
||||
.bm-button-trans.bm-button-hover-black:active {
|
||||
background-color: rgba(0, 0, 0, 0.22);
|
||||
}
|
||||
input[type=number].bm-input-coords {
|
||||
appearance: auto;
|
||||
-moz-appearance: textfield;
|
||||
|
|
@ -176,3 +205,79 @@ input[type=file] {
|
|||
align-items: center;
|
||||
gap: 0.5ch;
|
||||
}
|
||||
#bm-window-filter .bm-container:has(table) {
|
||||
max-height: 60vh;
|
||||
overflow: auto;
|
||||
}
|
||||
#bm-window-filter table {
|
||||
table-layout: fixed;
|
||||
width: 50ch;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 0.5em;
|
||||
}
|
||||
#bm-window-filter tr {
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
.bm-filter-tbl-clr {
|
||||
display: block;
|
||||
border: thick double lightgray;
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
padding: 1ch;
|
||||
}
|
||||
.bm-filter-tbl-clr button {
|
||||
padding: 0.75em 0.5ch;
|
||||
}
|
||||
.bm-filter-tbl-clr svg {
|
||||
width: 4ch;
|
||||
isolation: isolate;
|
||||
}
|
||||
.bm-filter-tbl-id {
|
||||
position: relative;
|
||||
top: 0.75em;
|
||||
left: 0.5ch;
|
||||
}
|
||||
.bm-filter-tbl-prmim {
|
||||
position: relative;
|
||||
top: 0.75em;
|
||||
left: -3.5ch;
|
||||
}
|
||||
.bm-filter-tbl-name {
|
||||
position: relative;
|
||||
top: -0.75em;
|
||||
left: -16ch;
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
.bm-filter-tbl-crct {
|
||||
display: block;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
right: 18ch;
|
||||
top: 0.75em;
|
||||
text-align: right;
|
||||
}
|
||||
.bm-filter-tbl-totl {
|
||||
display: block;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
left: -16ch;
|
||||
top: 0.75em;
|
||||
text-align: left;
|
||||
}
|
||||
.bm-filter-tbl-totl::after {
|
||||
content: "/";
|
||||
position: absolute;
|
||||
left: -1.5ch;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
#bm-window-filter tfoot {
|
||||
display: table-header-group;
|
||||
}
|
||||
#bm-window-filter tfoot th {
|
||||
text-align: left;
|
||||
}
|
||||
#bm-window-filter tfoot td {
|
||||
text-align: right;
|
||||
padding-left: 1ch;
|
||||
}
|
||||
|
|
|
|||
353
dist/BlueMarble-For-GreasyFork.user.js
vendored
353
dist/BlueMarble-For-GreasyFork.user.js
vendored
|
|
@ -2,7 +2,7 @@
|
|||
// @name Blue Marble
|
||||
// @name:en Blue Marble
|
||||
// @namespace https://github.com/SwingTheVine/
|
||||
// @version 0.88.179
|
||||
// @version 0.88.207
|
||||
// @description A userscript to automate and/or enhance the user experience on Wplace.live. Make sure to comply with the site's Terms of Service, and rules! This script is not affiliated with Wplace.live in any way, use at your own risk. This script is not affiliated with TamperMonkey. The author of this userscript is not responsible for any damages, issues, loss of data, or punishment that may occur as a result of using this script. This script is provided "as is" under the MPL-2.0 license. The "Blue Marble" icon is licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. The image is owned by NASA.
|
||||
// @description:en A userscript to automate and/or enhance the user experience on Wplace.live. Make sure to comply with the site's Terms of Service, and rules! This script is not affiliated with Wplace.live in any way, use at your own risk. This script is not affiliated with TamperMonkey. The author of this userscript is not responsible for any damages, issues, loss of data, or punishment that may occur as a result of using this script. This script is provided "as is" under the MPL-2.0 license. The "Blue Marble" icon is licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. The image is owned by NASA.
|
||||
// @author SwingTheVine
|
||||
|
|
@ -150,7 +150,7 @@
|
|||
* This `small` element will have properties shared between all `small` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `small` that are NOT shared between all overlay `small` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLParagraphElement):void} [callback=()=>{}] - Additional JS modification to the `small`.
|
||||
* @param {function(Overlay, HTMLElement):void} [callback=()=>{}] - Additional JS modification to the `small`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.55.8
|
||||
* @example
|
||||
|
|
@ -169,11 +169,34 @@
|
|||
callback(this, small);
|
||||
return this;
|
||||
}
|
||||
/** Adds a `span` to the overlay.
|
||||
* This `span` element will have properties shared between all `span` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `span` that are NOT shared between all overlay `span` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLSpanElement):void} [callback=()=>{}] - Additional JS modification to the `span`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.55.8
|
||||
* @example
|
||||
* // Assume all <span> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addSpan({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <span id="foo" class="bar">Foobar.</span>
|
||||
* </body>
|
||||
*/
|
||||
addSpan(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const span = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "span", properties, additionalProperties);
|
||||
callback(this, span);
|
||||
return this;
|
||||
}
|
||||
/** Adds a `details` to the overlay.
|
||||
* This `details` element will have properties shared between all `details` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `details` that are NOT shared between all overlay `details` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLParagraphElement):void} [callback=()=>{}] - Additional JS modification to the `details`.
|
||||
* @param {function(Overlay, HTMLDetailsElement):void} [callback=()=>{}] - Additional JS modification to the `details`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.96
|
||||
* @example
|
||||
|
|
@ -196,7 +219,7 @@
|
|||
* This `summary` element will have properties shared between all `summary` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `summary` that are NOT shared between all overlay `summary` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLParagraphElement):void} [callback=()=>{}] - Additional JS modification to the `summary`.
|
||||
* @param {function(Overlay, HTMLElement):void} [callback=()=>{}] - Additional JS modification to the `summary`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.96
|
||||
* @example
|
||||
|
|
@ -338,6 +361,282 @@
|
|||
callback(this, label, checkbox);
|
||||
return this;
|
||||
}
|
||||
/** Adds an ordered list to the overlay.
|
||||
* This `ol` element will have properties shared between all `ol` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `ol` that are NOT shared between all overlay `ol` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLOListElement):void} [callback=()=>{}] - Additional JS modification to the `ol`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <ol> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addOl({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <ol id="foo" class="bar">Foobar.</ol>
|
||||
* </body>
|
||||
*/
|
||||
addOl(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const ol = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "ol", properties, additionalProperties);
|
||||
callback(this, ol);
|
||||
return this;
|
||||
}
|
||||
/** Adds an unordered list to the overlay.
|
||||
* This `ul` element will have properties shared between all `ul` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `ul` that are NOT shared between all overlay `ul` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLUListElement):void} [callback=()=>{}] - Additional JS modification to the `ul`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <ul> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addUl({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <ul id="foo" class="bar">Foobar.</ul>
|
||||
* </body>
|
||||
*/
|
||||
addUl(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const ul = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "ul", properties, additionalProperties);
|
||||
callback(this, ul);
|
||||
return this;
|
||||
}
|
||||
/** Adds a `menu` to the overlay.
|
||||
* This `menu` element will have properties shared between all `menu` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `menu` that are NOT shared between all overlay `menu` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLMenuElement):void} [callback=()=>{}] - Additional JS modification to the `menu`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <menu> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addMenu({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <menu id="foo" class="bar">Foobar.</menu>
|
||||
* </body>
|
||||
*/
|
||||
addMenu(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const menu = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "menu", properties, additionalProperties);
|
||||
callback(this, menu);
|
||||
return this;
|
||||
}
|
||||
/** Adds a list item to the overlay.
|
||||
* This `li` element will have properties shared between all `li` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `li` that are NOT shared between all overlay `li` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLLIElement):void} [callback=()=>{}] - Additional JS modification to the `li`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <li> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addLi({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <li id="foo" class="bar">Foobar.</li>
|
||||
* </body>
|
||||
*/
|
||||
addLi(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const li = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "li", properties, additionalProperties);
|
||||
callback(this, li);
|
||||
return this;
|
||||
}
|
||||
/** Adds a table to the overlay.
|
||||
* This `table` element will have properties shared between all `table` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `table` that are NOT shared between all overlay `table` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableElement):void} [callback=()=>{}] - Additional JS modification to the `table`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <table> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTable({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <table id="foo" class="bar">Foobar.</table>
|
||||
* </body>
|
||||
*/
|
||||
addTable(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const table = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "table", properties, additionalProperties);
|
||||
callback(this, table);
|
||||
return this;
|
||||
}
|
||||
/** Adds a table caption to the overlay.
|
||||
* This `caption` element will have properties shared between all `caption` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `caption` that are NOT shared between all overlay `caption` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableCaptionElement):void} [callback=()=>{}] - Additional JS modification to the `caption`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <caption> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addCaption({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <caption id="foo" class="bar">Foobar.</caption>
|
||||
* </body>
|
||||
*/
|
||||
addCaption(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const caption = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "caption", properties, additionalProperties);
|
||||
callback(this, caption);
|
||||
return this;
|
||||
}
|
||||
/** Adds a table header to the overlay.
|
||||
* This `thead` element will have properties shared between all `thead` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `thead` that are NOT shared between all overlay `thead` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableSectionElement):void} [callback=()=>{}] - Additional JS modification to the `thead`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <thead> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addThead({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <thead id="foo" class="bar">Foobar.</thead>
|
||||
* </body>
|
||||
*/
|
||||
addThead(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const thead = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "thead", properties, additionalProperties);
|
||||
callback(this, thead);
|
||||
return this;
|
||||
}
|
||||
/** Adds a table body to the overlay.
|
||||
* This `tbody` element will have properties shared between all `tbody` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `tbody` that are NOT shared between all overlay `tbody` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableSectionElement):void} [callback=()=>{}] - Additional JS modification to the `tbody`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <tbody> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTbody({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <tbody id="foo" class="bar">Foobar.</tbody>
|
||||
* </body>
|
||||
*/
|
||||
addTbody(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const tbody = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "tbody", properties, additionalProperties);
|
||||
callback(this, tbody);
|
||||
return this;
|
||||
}
|
||||
/** Adds a table footer to the overlay.
|
||||
* This `tfoot` element will have properties shared between all `tfoot` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `tfoot` that are NOT shared between all overlay `tfoot` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableSectionElement):void} [callback=()=>{}] - Additional JS modification to the `tfoot`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <tfoot> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTfoot({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <tfoot id="foo" class="bar">Foobar.</tfoot>
|
||||
* </body>
|
||||
*/
|
||||
addTfoot(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const tfoot = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "tfoot", properties, additionalProperties);
|
||||
callback(this, tfoot);
|
||||
return this;
|
||||
}
|
||||
/** Adds a table row to the overlay.
|
||||
* This `tr` element will have properties shared between all `tr` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `tr` that are NOT shared between all overlay `tr` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableRowElement):void} [callback=()=>{}] - Additional JS modification to the `tr`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <tr> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTr({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <tr id="foo" class="bar">Foobar.</tr>
|
||||
* </body>
|
||||
*/
|
||||
addTr(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const tr = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "tr", properties, additionalProperties);
|
||||
callback(this, tr);
|
||||
return this;
|
||||
}
|
||||
/** Adds a table header (label) cell to the overlay.
|
||||
* This `th` element will have properties shared between all `th` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `th` that are NOT shared between all overlay `th` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableCellElement):void} [callback=()=>{}] - Additional JS modification to the `th`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <th> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTh({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <th id="foo" class="bar">Foobar.</th>
|
||||
* </body>
|
||||
*/
|
||||
addTh(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const th = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "th", properties, additionalProperties);
|
||||
callback(this, th);
|
||||
return this;
|
||||
}
|
||||
/** Adds a table data cell to the overlay.
|
||||
* This `td` element will have properties shared between all `td` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `td` that are NOT shared between all overlay `td` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableCellElement):void} [callback=()=>{}] - Additional JS modification to the `td`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <td> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTd({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <td id="foo" class="bar">Foobar.</td>
|
||||
* </body>
|
||||
*/
|
||||
addTd(additionalProperties = {}, callback = () => {
|
||||
}) {
|
||||
const properties = {};
|
||||
const td = __privateMethod(this, _Overlay_instances, createElement_fn).call(this, "td", properties, additionalProperties);
|
||||
callback(this, td);
|
||||
return this;
|
||||
}
|
||||
/** Adds a `button` to the overlay.
|
||||
* This `button` element will have properties shared between all `button` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
|
|
@ -502,7 +801,7 @@
|
|||
* This dragbar element will have properties shared between all dragbar elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the dragbar that are NOT shared between all overlay dragbars. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTextAreaElement):void} [callback=()=>{}] - Additional JS modification to the dragbar.
|
||||
* @param {function(Overlay, HTMLDivElement):void} [callback=()=>{}] - Additional JS modification to the dragbar.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.145
|
||||
* @example
|
||||
|
|
@ -872,6 +1171,13 @@
|
|||
}
|
||||
return array;
|
||||
}
|
||||
function calculateRelativeLuminance(array) {
|
||||
const srgb = array.map((channel) => {
|
||||
channel /= 255;
|
||||
return channel <= 0.03928 ? channel / 12.92 : Math.pow((channel + 0.055) / 1.055, 2.4);
|
||||
});
|
||||
return 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2];
|
||||
}
|
||||
function colorpaletteForBlueMarble(tolerance) {
|
||||
const colorpaletteBM = colorpalette;
|
||||
colorpaletteBM.unshift({ "id": -1, "premium": false, "name": "Erased", "rgb": [222, 250, 206] });
|
||||
|
|
@ -1805,7 +2111,7 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String
|
|||
button.onclick = () => instance.handleMinimization(button);
|
||||
button.ontouchend = () => instance.handleMinimization(button);
|
||||
}).buildElement().addDiv().buildElement().buildElement().addDiv({ "class": "bm-window-content" }).addDiv({ "class": "bm-container" }).addImg({ "class": "bm-favicon", "src": "https://raw.githubusercontent.com/SwingTheVine/Wplace-BlueMarble/main/dist/assets/Favicon.png" }).buildElement().addHeader(1, { "textContent": name }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container" }).addP({ "id": "bm-user-droplets", "textContent": "Droplets:" }).buildElement().addP({ "id": "bm-user-nextlevel", "textContent": "Next level in..." }).buildElement().buildElement().addHr().buildElement().addDiv({ "class": "bm-container" }).addDiv({ "class": "bm-container" }).addButton(
|
||||
{ "class": "bm-button-circle bm-button-pin", "style": "margin-top: 0;", "innerHTML": '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 4 6"><circle cx="2" cy="2" r="2"></circle><path d="M2 6 L3.7 3 L0.3 3 Z"></path><circle cx="2" cy="2" r="0.7" fill="white"></circle></svg></svg>' },
|
||||
{ "class": "bm-button-circle bm-button-pin", "style": "margin-top: 0;", "innerHTML": '<svg viewBox="0 0 4 6"><path d="M.5,3.4A2,2 0 1 1 3.5,3.4L2,6"/><circle cx="2" cy="2" r=".7" fill="#fff"/></svg>' },
|
||||
(instance, button) => {
|
||||
button.onclick = () => {
|
||||
const coords2 = instance.apiManager?.coordsTilePixel;
|
||||
|
|
@ -1944,15 +2250,44 @@ Version: ${version}`, "readOnly": true }).buildElement().buildElement().addDiv({
|
|||
}).buildElement().addButton({ "textContent": "Unselect All" }, (instance, button) => {
|
||||
button.onclick = () => {
|
||||
};
|
||||
}).buildElement().buildElement().addDiv().buildElement().buildElement().buildElement().buildOverlay(document.body);
|
||||
}).buildElement().buildElement().buildElement().buildElement().buildOverlay(document.body);
|
||||
overlayFilter.handleDrag("#bm-window-filter.bm-window", "#bm-window-filter .bm-dragbar");
|
||||
const windowContent = document.querySelector("#bm-window-filter .bm-window-content");
|
||||
const { palette, LUT: _ } = templateManager.paletteBM;
|
||||
let allPixelsTotal = 0;
|
||||
let allPixelsCorrectTotal = 0;
|
||||
const allPixelsCorrect = /* @__PURE__ */ new Map();
|
||||
const allPixelsColor = /* @__PURE__ */ new Map();
|
||||
for (const template of templateManager.templatesArray) {
|
||||
const total = template.pixelCount?.total ?? 0;
|
||||
const colors = template.pixelCount?.colors ?? /* @__PURE__ */ new Map();
|
||||
const correct = template.pixelCount?.correct ?? /* @__PURE__ */ new Map();
|
||||
allPixelsTotal += total ?? 0;
|
||||
for (const [colorID, correctPixels] of correct) {
|
||||
const _correctPixels = Number(correctPixels) || 0;
|
||||
allPixelsCorrectTotal += _correctPixels;
|
||||
const allPixelsCorrectSoFar = allPixelsCorrect.get(colorID) ?? 0;
|
||||
allPixelsCorrect.set(colorID, allPixelsCorrectSoFar + _correctPixels);
|
||||
}
|
||||
for (const [colorID, colorPixels] of colors) {
|
||||
const _colorPixels = Number(colorPixels) || 0;
|
||||
const allPixelsColorSoFar = allPixelsColor.get(colorID) ?? 0;
|
||||
allPixelsColor.set(colorID, allPixelsColorSoFar + _colorPixels);
|
||||
}
|
||||
}
|
||||
const colorList = new Overlay(name, version);
|
||||
colorList.addDiv({ "id": "bm-filter-container-colors", "class": "bm-container" });
|
||||
colorList.addDiv({ "class": "bm-container" }).addTable({ "class": "bm-container" }).addCaption().addHeader(2, { "textContent": "Pixels In Templates By Palette Color" }).buildElement().buildElement().addTfoot().addTr().addTh({ "textContent": "Total Correct", "scope": "row" }).buildElement().addTd({ "textContent": allPixelsCorrectTotal.toString() }).buildElement().buildElement().addTr().addTh({ "textContent": "Total Pixels", "scope": "row" }).buildElement().addTd({ "textContent": allPixelsTotal.toString() }).buildElement().buildElement().buildElement().addThead({ "class": "bm-screenreader" }).addTr().addTh({ "textContent": "Hide Color", "scope": "col" }).buildElement().addTh({ "textContent": "ID", "scope": "col" }).buildElement().addTh({ "textContent": "Is Premium", "scope": "col" }).buildElement().addTh({ "textContent": "Name", "scope": "col" }).buildElement().addTh({ "textContent": "Correct Pixels", "scope": "col" }).buildElement().addTh({ "textContent": "Total Pixels", "scope": "col" }).buildElement().buildElement().buildElement();
|
||||
for (const color of palette) {
|
||||
colorList.addDiv({ "class": "bm-container" }).addP({ "textContent": `Color ID: ${color.id?.toString()?.padStart(2, "0")}, Name: ${color.name}` }).buildElement().buildElement();
|
||||
const lumin = calculateRelativeLuminance(color.rgb);
|
||||
const textColorForPaletteColorBackground = 1.05 / (lumin + 0.05) > (lumin + 0.05) / 0.05 ? "white" : "black";
|
||||
const bgEffectForButtons = textColorForPaletteColorBackground == "white" ? "bm-button-hover-white" : "bm-button-hover-black";
|
||||
colorList.addTr().addTd().addDiv({ "class": "bm-filter-tbl-clr", "style": `background-color: rgb(${color.rgb?.map((channel) => Number(channel) || 0).join(",")});` }).addButton({ "class": "bm-button-trans " + bgEffectForButtons, "aria-label": `Hide the color ${color.name || "color"} on templates`, "innerHTML": `<svg viewBox="0 .5 6 3"><path d="M0,2Q3-1 6,2Q3,5 0,2H2A1,1 0 1 0 3,1Q3,2 2,2" fill="${textColorForPaletteColorBackground}"/></svg>` }).buildElement().buildElement().buildElement().addTd().addSpan({ "class": "bm-filter-tbl-id", "textContent": `#${color.id}` }).buildElement().buildElement().addTd().addSpan({ "class": "bm-filter-tbl-prmim", "textContent": color.premium ? "\u2605" : "" }).buildElement().buildElement().addTd().addSpan({ "class": "bm-filter-tbl-name", "textContent": color.name }).buildElement().buildElement().addTd().addSpan({ "class": "bm-filter-tbl-crct", "textContent": middleEllipsis(String(allPixelsCorrect.get(color.id) ?? "???"), 7) }).buildElement().buildElement().addTd().addSpan({ "class": "bm-filter-tbl-totl", "textContent": middleEllipsis(String(allPixelsColor.get(color.id) ?? "0"), 7) }).buildElement().buildElement().buildElement();
|
||||
}
|
||||
colorList.buildOverlay(windowContent);
|
||||
function middleEllipsis(text, maxChars) {
|
||||
if (text.length <= maxChars) return text;
|
||||
const half = Math.floor((maxChars - 3) / 2);
|
||||
return text.slice(0, half) + "\u2026" + text.slice(text.length - half);
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
4
dist/BlueMarble-Standalone.user.js
vendored
4
dist/BlueMarble-Standalone.user.js
vendored
File diff suppressed because one or more lines are too long
2
dist/BlueMarble.user.css
vendored
2
dist/BlueMarble.user.css
vendored
|
|
@ -1 +1 @@
|
|||
.bm-18{position:fixed;background-color:#153063e6;color:#fff;padding:10px;border-radius:8px;z-index:9000;transition:all .3s ease,transform 0s;top:75px;left:60px;width:auto;max-width:calc(100% - 135px);font-family:Roboto Mono,Courier New,Monaco,DejaVu Sans Mono,monospace,Arial;letter-spacing:.05em}#bm-Y{max-width:300px}.bm-16{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.5ch;background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="5" height="5"><circle cx="3" cy="3" r="1.5" fill="CornflowerBlue" /></svg>') repeat;cursor:grab;width:100%;height:fit-content}.bm-16.bm-11{cursor:grabbing}.bm-18:has(.bm-16.bm-11){pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.bm-16.bm-11{pointer-events:auto}.bm-17{display:inline-block;height:2.5em;margin-right:1ch;vertical-align:middle}.bm-18 h1{display:inline-block;font-size:x-large;font-weight:700;vertical-align:middle}.bm-16 h1{font-size:1.2em;user-select:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-shadow:3px 0px rgba(21,48,99,.5),-3px 0px rgba(21,48,99,.5),0px 3px rgba(21,48,99,.5),0px -3px rgba(21,48,99,.5),3px 3px rgba(21,48,99,.5),-3px 3px rgba(21,48,99,.5),3px -3px rgba(21,48,99,.5),-3px -3px rgba(21,48,99,.5)}.bm-16 div:has(h1){display:contents}.bm-10{margin:.5em 0}.bm-18 button{background-color:#144eb9;border-radius:1em;padding:0 .75ch}.bm-18 button:hover,.bm-18 button:focus-visible{background-color:#1061e5}.bm-18 button:active,.bm-18 button:disabled{background-color:#2e97ff}.bm-18 button:disabled{text-decoration:line-through}.bm-U{border:white 1px solid;height:1.5em;width:1.5em;margin-top:2px;text-align:center;line-height:1em;padding:0!important}.bm--{vertical-align:middle}.bm-- svg{width:50%;margin:0 auto;fill:#111}input[type=number].bm-W{appearance:auto;-moz-appearance:textfield;width:5.5ch;margin-left:1ch;background-color:#0003;padding:0 .5ch;font-size:small}input[type=number].bm-W::-webkit-outer-spin-button,input[type=number].bm-W::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}div:has(>.bm-_)>button{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bm-_,input[type=file]{display:none!important;visibility:hidden!important;position:absolute!important;left:-9999px!important;top:-9999px!important;width:0!important;height:0!important;opacity:0!important;z-index:-9999!important;pointer-events:none!important}.bm-P{overflow:hidden;transition:height .3s cubic-bezier(.4,0,.2,1)}.bm-18 textarea{font-size:small;background-color:#0003;padding:0 .5ch;height:5.25em;width:100%}.bm-18 small{font-size:x-small;color:#d3d3d3}.bm-X{display:flex;align-content:center;justify-content:space-between;align-items:center;gap:.5ch}.bm-flex-center{display:flex;align-content:center;justify-content:center;align-items:center;gap:.5ch}
|
||||
.bm-13{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.bm-1h{position:fixed;background-color:#153063e6;color:#fff;padding:10px;border-radius:8px;z-index:9000;transition:all .3s ease,transform 0s;top:75px;left:60px;width:auto;max-height:calc(100vh - 150px);max-width:calc(100% - 135px);font-family:Roboto Mono,Courier New,Monaco,DejaVu Sans Mono,monospace,Arial;letter-spacing:.05em}#bm-15{max-width:300px}.bm-1f{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:.5ch;background:url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="5" height="5"><circle cx="3" cy="3" r="1.5" fill="CornflowerBlue" /></svg>') repeat;cursor:grab;width:100%;height:fit-content}.bm-1f.bm-1a{cursor:grabbing}.bm-1h:has(.bm-1f.bm-1a){pointer-events:none;user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}.bm-1f.bm-1a{pointer-events:auto}.bm-1g{display:inline-block;height:2.5em;margin-right:1ch;vertical-align:middle}.bm-1h h1{display:inline-block;font-size:x-large;font-weight:700;vertical-align:middle}.bm-1f h1{font-size:1.2em;user-select:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;text-shadow:3px 0px rgba(21,48,99,.5),-3px 0px rgba(21,48,99,.5),0px 3px rgba(21,48,99,.5),0px -3px rgba(21,48,99,.5),3px 3px rgba(21,48,99,.5),-3px 3px rgba(21,48,99,.5),3px -3px rgba(21,48,99,.5),-3px -3px rgba(21,48,99,.5)}.bm-1f div:has(h1){display:contents}.bm-19{margin:.5em 0}.bm-1h button{background-color:#144eb9;border-radius:1em;padding:0 .75ch}.bm-1h button:hover,.bm-1h button:focus-visible{background-color:#1061e5}.bm-1h button:active,.bm-1h button:disabled{background-color:#2e97ff}.bm-1h button:disabled{text-decoration:line-through}.bm--{border:white 1px solid;height:1.5em;width:1.5em;margin-top:2px;text-align:center;line-height:1em;padding:0!important}.bm-17{vertical-align:middle}.bm-17 svg{width:50%;margin:0 auto;fill:#111}.bm-1h button.bm-14{background-color:unset}.bm-14.bm-M:hover,.bm-14.bm-M:focus{background-color:#ffffff2b}.bm-14.bm-M:active{background-color:#ffffff38}.bm-14.bm-N:hover,.bm-14.bm-N:focus{background-color:#0000002b}.bm-14.bm-N:active{background-color:#00000038}input[type=number].bm-11{appearance:auto;-moz-appearance:textfield;width:5.5ch;margin-left:1ch;background-color:#0003;padding:0 .5ch;font-size:small}input[type=number].bm-11::-webkit-outer-spin-button,input[type=number].bm-11::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}div:has(>.bm-18)>button{width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.bm-18,input[type=file]{display:none!important;visibility:hidden!important;position:absolute!important;left:-9999px!important;top:-9999px!important;width:0!important;height:0!important;opacity:0!important;z-index:-9999!important;pointer-events:none!important}.bm-U{overflow:hidden;transition:height .3s cubic-bezier(.4,0,.2,1)}.bm-1h textarea{font-size:small;background-color:#0003;padding:0 .5ch;height:5.25em;width:100%}.bm-1h small{font-size:x-small;color:#d3d3d3}.bm-12{display:flex;align-content:center;justify-content:space-between;align-items:center;gap:.5ch}.bm-flex-center{display:flex;align-content:center;justify-content:center;align-items:center;gap:.5ch}#bm-_ .bm-19:has(table){max-height:60vh;overflow:auto}#bm-_ table{table-layout:fixed;width:50ch;border-collapse:separate;border-spacing:0 .5em}#bm-_ tr{padding:.5em 0}.bm-X{display:block;border:thick double lightgray;width:fit-content;height:fit-content;padding:1ch}.bm-X button{padding:.75em .5ch}.bm-X svg{width:4ch;isolation:isolate}.bm-10{position:relative;top:.75em;left:.5ch}.bm-Q{position:relative;top:.75em;left:-3.5ch}.bm-R{position:relative;top:-.75em;left:-16ch;text-wrap:nowrap}.bm-S{display:block;width:100%;position:relative;right:18ch;top:.75em;text-align:right}.bm-T{display:block;width:100%;position:relative;left:-16ch;top:.75em;text-align:left}.bm-T:after{content:"/";position:absolute;left:-1.5ch;top:50%;transform:translateY(-50%)}#bm-_ tfoot{display:table-header-group}#bm-_ tfoot th{text-align:left}#bm-_ tfoot td{text-align:right;padding-left:1ch}
|
||||
|
|
|
|||
4
dist/BlueMarble.user.js
vendored
4
dist/BlueMarble.user.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -51,7 +51,7 @@
|
|||
<a href="https://discord.gg/tpeBPy46hf" target="_blank" rel="noopener noreferrer"><img alt="Contact Me" src="https://img.shields.io/badge/Contact_Me-gray?style=flat&logo=Discord&logoColor=white&logoSize=auto&labelColor=cornflowerblue"></a>
|
||||
<a href="https://bluemarble.lol/" target="_blank" rel="noopener noreferrer"><img alt="Blue Marble Website" src="https://img.shields.io/badge/Blue_Marble_Website-crqch-blue?style=flat&logo=globe&logoColor=white"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="WakaTime" src="https://img.shields.io/badge/Coding_Time-111hrs_12mins-blue?style=flat&logo=wakatime&logoColor=black&logoSize=auto&labelColor=white"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-677-black?style=flat"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Patches" src="https://img.shields.io/badge/Total_Patches-705-black?style=flat"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Lines of Code" src="https://img.shields.io/badge/Lines_Of_Code-498-blue?style=flat"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Total Comments" src="https://img.shields.io/badge/Lines_Of_Comments-498-blue?style=flat"></a>
|
||||
<a href="" target="_blank" rel="noopener noreferrer"><img alt="Compression" src="https://img.shields.io/badge/Compression-70.19%25-blue"></a>
|
||||
|
|
|
|||
4
package-lock.json
generated
4
package-lock.json
generated
|
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.88.179",
|
||||
"version": "0.88.207",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.88.179",
|
||||
"version": "0.88.207",
|
||||
"devDependencies": {
|
||||
"esbuild": "^0.25.0",
|
||||
"jsdoc": "^4.0.5",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "wplace-bluemarble",
|
||||
"version": "0.88.179",
|
||||
"version": "0.88.207",
|
||||
"type": "module",
|
||||
"homepage": "https://bluemarble.lol/",
|
||||
"repository": {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// @name Blue Marble
|
||||
// @name:en Blue Marble
|
||||
// @namespace https://github.com/SwingTheVine/
|
||||
// @version 0.88.179
|
||||
// @version 0.88.207
|
||||
// @description A userscript to automate and/or enhance the user experience on Wplace.live. Make sure to comply with the site's Terms of Service, and rules! This script is not affiliated with Wplace.live in any way, use at your own risk. This script is not affiliated with TamperMonkey. The author of this userscript is not responsible for any damages, issues, loss of data, or punishment that may occur as a result of using this script. This script is provided "as is" under the MPL-2.0 license. The "Blue Marble" icon is licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. The image is owned by NASA.
|
||||
// @description:en A userscript to automate and/or enhance the user experience on Wplace.live. Make sure to comply with the site's Terms of Service, and rules! This script is not affiliated with Wplace.live in any way, use at your own risk. This script is not affiliated with TamperMonkey. The author of this userscript is not responsible for any damages, issues, loss of data, or punishment that may occur as a result of using this script. This script is provided "as is" under the MPL-2.0 license. The "Blue Marble" icon is licensed under CC0 1.0 Universal (CC0 1.0) Public Domain Dedication. The image is owned by NASA.
|
||||
// @author SwingTheVine
|
||||
|
|
|
|||
335
src/Overlay.js
335
src/Overlay.js
|
|
@ -208,12 +208,12 @@ export default class Overlay {
|
|||
callback(this, p); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
/** Adds a `small` to the overlay.
|
||||
* This `small` element will have properties shared between all `small` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `small` that are NOT shared between all overlay `small` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLParagraphElement):void} [callback=()=>{}] - Additional JS modification to the `small`.
|
||||
* @param {function(Overlay, HTMLElement):void} [callback=()=>{}] - Additional JS modification to the `small`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.55.8
|
||||
* @example
|
||||
|
|
@ -234,11 +234,36 @@ export default class Overlay {
|
|||
return this;
|
||||
}
|
||||
|
||||
/** Adds a `span` to the overlay.
|
||||
* This `span` element will have properties shared between all `span` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `span` that are NOT shared between all overlay `span` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLSpanElement):void} [callback=()=>{}] - Additional JS modification to the `span`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.55.8
|
||||
* @example
|
||||
* // Assume all <span> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addSpan({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <span id="foo" class="bar">Foobar.</span>
|
||||
* </body>
|
||||
*/
|
||||
addSpan(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <span> DOM properties
|
||||
|
||||
const span = this.#createElement('span', properties, additionalProperties); // Creates the <span> element
|
||||
callback(this, span); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a `details` to the overlay.
|
||||
* This `details` element will have properties shared between all `details` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `details` that are NOT shared between all overlay `details` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLParagraphElement):void} [callback=()=>{}] - Additional JS modification to the `details`.
|
||||
* @param {function(Overlay, HTMLDetailsElement):void} [callback=()=>{}] - Additional JS modification to the `details`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.96
|
||||
* @example
|
||||
|
|
@ -263,7 +288,7 @@ export default class Overlay {
|
|||
* This `summary` element will have properties shared between all `summary` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `summary` that are NOT shared between all overlay `summary` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLParagraphElement):void} [callback=()=>{}] - Additional JS modification to the `summary`.
|
||||
* @param {function(Overlay, HTMLElement):void} [callback=()=>{}] - Additional JS modification to the `summary`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.96
|
||||
* @example
|
||||
|
|
@ -416,6 +441,306 @@ export default class Overlay {
|
|||
callback(this, label, checkbox); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds an ordered list to the overlay.
|
||||
* This `ol` element will have properties shared between all `ol` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `ol` that are NOT shared between all overlay `ol` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLOListElement):void} [callback=()=>{}] - Additional JS modification to the `ol`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <ol> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addOl({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <ol id="foo" class="bar">Foobar.</ol>
|
||||
* </body>
|
||||
*/
|
||||
addOl(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <ol> DOM properties
|
||||
|
||||
const ol = this.#createElement('ol', properties, additionalProperties); // Creates the <ol> element
|
||||
callback(this, ol); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds an unordered list to the overlay.
|
||||
* This `ul` element will have properties shared between all `ul` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `ul` that are NOT shared between all overlay `ul` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLUListElement):void} [callback=()=>{}] - Additional JS modification to the `ul`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <ul> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addUl({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <ul id="foo" class="bar">Foobar.</ul>
|
||||
* </body>
|
||||
*/
|
||||
addUl(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <ul> DOM properties
|
||||
|
||||
const ul = this.#createElement('ul', properties, additionalProperties); // Creates the <ul> element
|
||||
callback(this, ul); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a `menu` to the overlay.
|
||||
* This `menu` element will have properties shared between all `menu` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `menu` that are NOT shared between all overlay `menu` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLMenuElement):void} [callback=()=>{}] - Additional JS modification to the `menu`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <menu> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addMenu({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <menu id="foo" class="bar">Foobar.</menu>
|
||||
* </body>
|
||||
*/
|
||||
addMenu(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <menu> DOM properties
|
||||
|
||||
const menu = this.#createElement('menu', properties, additionalProperties); // Creates the <menu> element
|
||||
callback(this, menu); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a list item to the overlay.
|
||||
* This `li` element will have properties shared between all `li` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `li` that are NOT shared between all overlay `li` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLLIElement):void} [callback=()=>{}] - Additional JS modification to the `li`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <li> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addLi({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <li id="foo" class="bar">Foobar.</li>
|
||||
* </body>
|
||||
*/
|
||||
addLi(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <li> DOM properties
|
||||
|
||||
const li = this.#createElement('li', properties, additionalProperties); // Creates the <li> element
|
||||
callback(this, li); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a table to the overlay.
|
||||
* This `table` element will have properties shared between all `table` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `table` that are NOT shared between all overlay `table` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableElement):void} [callback=()=>{}] - Additional JS modification to the `table`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <table> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTable({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <table id="foo" class="bar">Foobar.</table>
|
||||
* </body>
|
||||
*/
|
||||
addTable(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <table> DOM properties
|
||||
|
||||
const table = this.#createElement('table', properties, additionalProperties); // Creates the <table> element
|
||||
callback(this, table); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a table caption to the overlay.
|
||||
* This `caption` element will have properties shared between all `caption` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `caption` that are NOT shared between all overlay `caption` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableCaptionElement):void} [callback=()=>{}] - Additional JS modification to the `caption`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <caption> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addCaption({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <caption id="foo" class="bar">Foobar.</caption>
|
||||
* </body>
|
||||
*/
|
||||
addCaption(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <caption> DOM properties
|
||||
|
||||
const caption = this.#createElement('caption', properties, additionalProperties); // Creates the <caption> element
|
||||
callback(this, caption); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a table header to the overlay.
|
||||
* This `thead` element will have properties shared between all `thead` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `thead` that are NOT shared between all overlay `thead` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableSectionElement):void} [callback=()=>{}] - Additional JS modification to the `thead`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <thead> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addThead({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <thead id="foo" class="bar">Foobar.</thead>
|
||||
* </body>
|
||||
*/
|
||||
addThead(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <thead> DOM properties
|
||||
|
||||
const thead = this.#createElement('thead', properties, additionalProperties); // Creates the <thead> element
|
||||
callback(this, thead); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a table body to the overlay.
|
||||
* This `tbody` element will have properties shared between all `tbody` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `tbody` that are NOT shared between all overlay `tbody` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableSectionElement):void} [callback=()=>{}] - Additional JS modification to the `tbody`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <tbody> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTbody({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <tbody id="foo" class="bar">Foobar.</tbody>
|
||||
* </body>
|
||||
*/
|
||||
addTbody(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <tbody> DOM properties
|
||||
|
||||
const tbody = this.#createElement('tbody', properties, additionalProperties); // Creates the <tbody> element
|
||||
callback(this, tbody); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a table footer to the overlay.
|
||||
* This `tfoot` element will have properties shared between all `tfoot` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `tfoot` that are NOT shared between all overlay `tfoot` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableSectionElement):void} [callback=()=>{}] - Additional JS modification to the `tfoot`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <tfoot> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTfoot({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <tfoot id="foo" class="bar">Foobar.</tfoot>
|
||||
* </body>
|
||||
*/
|
||||
addTfoot(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <tfoot> DOM properties
|
||||
|
||||
const tfoot = this.#createElement('tfoot', properties, additionalProperties); // Creates the <tfoot> element
|
||||
callback(this, tfoot); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a table row to the overlay.
|
||||
* This `tr` element will have properties shared between all `tr` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `tr` that are NOT shared between all overlay `tr` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableRowElement):void} [callback=()=>{}] - Additional JS modification to the `tr`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <tr> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTr({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <tr id="foo" class="bar">Foobar.</tr>
|
||||
* </body>
|
||||
*/
|
||||
addTr(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <tfoot> DOM properties
|
||||
|
||||
const tr = this.#createElement('tr', properties, additionalProperties); // Creates the <tr> element
|
||||
callback(this, tr); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a table header (label) cell to the overlay.
|
||||
* This `th` element will have properties shared between all `th` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `th` that are NOT shared between all overlay `th` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableCellElement):void} [callback=()=>{}] - Additional JS modification to the `th`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <th> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTh({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <th id="foo" class="bar">Foobar.</th>
|
||||
* </body>
|
||||
*/
|
||||
addTh(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <th> DOM properties
|
||||
|
||||
const th = this.#createElement('th', properties, additionalProperties); // Creates the <th> element
|
||||
callback(this, th); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a table data cell to the overlay.
|
||||
* This `td` element will have properties shared between all `td` elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the `td` that are NOT shared between all overlay `td` elements. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTableCellElement):void} [callback=()=>{}] - Additional JS modification to the `td`.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.180
|
||||
* @example
|
||||
* // Assume all <td> elements have a shared class (e.g. {'className': 'bar'})
|
||||
* overlay.addTd({'id': 'foo', 'textContent': 'Foobar.'}).buildOverlay(document.body);
|
||||
* // Output:
|
||||
* // (Assume <body> already exists in the webpage)
|
||||
* <body>
|
||||
* <td id="foo" class="bar">Foobar.</td>
|
||||
* </body>
|
||||
*/
|
||||
addTd(additionalProperties = {}, callback = () => {}) {
|
||||
|
||||
const properties = {}; // Shared <td> DOM properties
|
||||
|
||||
const td = this.#createElement('td', properties, additionalProperties); // Creates the <td> element
|
||||
callback(this, td); // Runs any script passed in through the callback
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adds a `button` to the overlay.
|
||||
* This `button` element will have properties shared between all `button` elements in the overlay.
|
||||
|
|
@ -604,7 +929,7 @@ export default class Overlay {
|
|||
* This dragbar element will have properties shared between all dragbar elements in the overlay.
|
||||
* You can override the shared properties by using a callback.
|
||||
* @param {Object.<string, any>} [additionalProperties={}] - The DOM properties of the dragbar that are NOT shared between all overlay dragbars. These should be camelCase.
|
||||
* @param {function(Overlay, HTMLTextAreaElement):void} [callback=()=>{}] - Additional JS modification to the dragbar.
|
||||
* @param {function(Overlay, HTMLDivElement):void} [callback=()=>{}] - Additional JS modification to the dragbar.
|
||||
* @returns {Overlay} Overlay class instance (this)
|
||||
* @since 0.88.145
|
||||
* @example
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ export default class Template {
|
|||
this.chunked = chunked;
|
||||
this.chunked32 = chunked32;
|
||||
this.tileSize = tileSize;
|
||||
this.pixelCount = { total: 0, colors: new Map() }; // Total pixel count in template
|
||||
/** Total pixel count in template @type {{total: number, colors: Map<number, number>, correct?: Map<number, number>}} */
|
||||
this.pixelCount = { total: 0, colors: new Map() };
|
||||
}
|
||||
|
||||
/** Creates chunks of the template for each tile.
|
||||
|
|
|
|||
99
src/main.js
99
src/main.js
|
|
@ -492,7 +492,6 @@ function buildWindowFilter() {
|
|||
}
|
||||
}).buildElement()
|
||||
.buildElement()
|
||||
.addDiv().buildElement()
|
||||
.buildElement()
|
||||
.buildElement().buildOverlay(document.body);
|
||||
|
||||
|
|
@ -505,9 +504,67 @@ function buildWindowFilter() {
|
|||
// Obtains the palette Blue Marble currently uses
|
||||
const { palette: palette, LUT: _ } = templateManager.paletteBM;
|
||||
|
||||
// Pixel totals
|
||||
let allPixelsTotal = 0;
|
||||
let allPixelsCorrectTotal = 0;
|
||||
const allPixelsCorrect = new Map();
|
||||
const allPixelsColor = new Map();
|
||||
|
||||
// Sum the pixel totals across all templates.
|
||||
// If there is no total for a template, it defaults to zero
|
||||
for (const template of templateManager.templatesArray) {
|
||||
|
||||
const total = template.pixelCount?.total ?? 0;
|
||||
const colors = template.pixelCount?.colors ?? new Map();
|
||||
const correct = template.pixelCount?.correct ?? new Map();
|
||||
|
||||
allPixelsTotal += total ?? 0; // Sums the pixels placed as "total" per everything
|
||||
|
||||
// Sums the pixels placed as "correct" per color ID
|
||||
for (const [colorID, correctPixels] of correct) {
|
||||
const _correctPixels = Number(correctPixels) || 0; // Boilerplate
|
||||
allPixelsCorrectTotal += _correctPixels; // Sums the pixels placed as "correct" per everything
|
||||
const allPixelsCorrectSoFar = allPixelsCorrect.get(colorID) ?? 0; // The total correct pixels for this color ID so far, or zero if none counted so far
|
||||
allPixelsCorrect.set(colorID, allPixelsCorrectSoFar + _correctPixels);
|
||||
}
|
||||
|
||||
// Sums the color pixels placed as "total" per color ID
|
||||
for (const [colorID, colorPixels] of colors) {
|
||||
const _colorPixels = Number(colorPixels) || 0; // Boilerplate
|
||||
const allPixelsColorSoFar = allPixelsColor.get(colorID) ?? 0; // The total color pixels for this color ID so far, or zero if none counted so far
|
||||
allPixelsColor.set(colorID, allPixelsColorSoFar + _colorPixels);
|
||||
}
|
||||
}
|
||||
|
||||
// Creates the color list container
|
||||
const colorList = new Overlay(name, version);
|
||||
colorList.addDiv({'id': 'bm-filter-container-colors', 'class': 'bm-container'})
|
||||
colorList.addDiv({'class': 'bm-container'})
|
||||
.addTable({'class': 'bm-container'})
|
||||
.addCaption()
|
||||
.addHeader(2, {'textContent': 'Pixels In Templates By Palette Color'}).buildElement()
|
||||
.buildElement()
|
||||
.addTfoot()
|
||||
.addTr()
|
||||
.addTh({'textContent': 'Total Correct', 'scope': 'row'}).buildElement()
|
||||
.addTd({'textContent': allPixelsCorrectTotal.toString()}).buildElement()
|
||||
.buildElement()
|
||||
.addTr()
|
||||
.addTh({'textContent': 'Total Pixels', 'scope': 'row'}).buildElement()
|
||||
.addTd({'textContent': allPixelsTotal.toString()}).buildElement()
|
||||
.buildElement()
|
||||
.buildElement()
|
||||
.addThead({'class': 'bm-screenreader'})
|
||||
.addTr()
|
||||
.addTh({'textContent': 'Hide Color', 'scope': 'col'}).buildElement()
|
||||
.addTh({'textContent': 'ID', 'scope': 'col'}).buildElement()
|
||||
.addTh({'textContent': 'Is Premium', 'scope': 'col'}).buildElement()
|
||||
.addTh({'textContent': 'Name', 'scope': 'col'}).buildElement()
|
||||
.addTh({'textContent': 'Correct Pixels', 'scope': 'col'}).buildElement()
|
||||
.addTh({'textContent': 'Total Pixels', 'scope': 'col'}).buildElement()
|
||||
.buildElement()
|
||||
.buildElement()
|
||||
// Notice that there is no buildElement() for the table here?
|
||||
// We leave the table open so we can continue to add children.
|
||||
|
||||
// For each color in the palette...
|
||||
for (const color of palette) {
|
||||
|
|
@ -520,19 +577,49 @@ function buildWindowFilter() {
|
|||
(((1.05) / (lumin + 0.05)) > ((lumin + 0.05) / 0.05))
|
||||
? 'white' : 'black';
|
||||
|
||||
const bgEffectForButtons = (textColorForPaletteColorBackground == 'white') ? 'bm-button-hover-white' : 'bm-button-hover-black';
|
||||
|
||||
// <svg viewBox="0 1 12 6"><mask id="a"><path d="M0,0H12V8L0,2" fill="#fff"/></mask><path d="M0,4Q6-2 12,4Q6,10 0,4H4A2,2 0 1 0 6,2Q6,4 4,4ZM1,2L10,6.5L9.5,7L.5,2.5" mask="url(#a)"/></svg>
|
||||
|
||||
|
||||
// Construct the DOM tree
|
||||
colorList.addDiv({'class': 'bm-container flex-space-between'})
|
||||
.addDiv({'class': '' + textColorForPaletteColorBackground, 'style': `border: thick double white`})
|
||||
.addButton({'class': 'bm-button-trans', 'innerHTML': `<svg viewBox="0 .5 6 3"><path d="M0,2Q3-1 6,2Q3,5 0,2H2A1,1 0 1 0 3,1Q3,2 2,2"/></svg>`}).buildElement()
|
||||
colorList.addTr()
|
||||
.addTd()
|
||||
.addDiv({'class': 'bm-filter-tbl-clr', 'style': `background-color: rgb(${color.rgb?.map(channel => Number(channel) || 0).join(',')});`})
|
||||
.addButton({'class': 'bm-button-trans ' + bgEffectForButtons, 'aria-label': `Hide the color ${color.name || 'color'} on templates`, 'innerHTML': `<svg viewBox="0 .5 6 3"><path d="M0,2Q3-1 6,2Q3,5 0,2H2A1,1 0 1 0 3,1Q3,2 2,2" fill="${textColorForPaletteColorBackground}"/></svg>`}).buildElement()
|
||||
.buildElement()
|
||||
.buildElement()
|
||||
.addTd()
|
||||
.addSpan({'class': 'bm-filter-tbl-id', 'textContent': `#${color.id}`}).buildElement()
|
||||
.buildElement()
|
||||
.addTd()
|
||||
.addSpan({'class': 'bm-filter-tbl-prmim', 'textContent': color.premium ? '★' : ''}).buildElement()
|
||||
.buildElement()
|
||||
.addTd()
|
||||
.addSpan({'class': 'bm-filter-tbl-name', 'textContent': color.name}).buildElement()
|
||||
.buildElement()
|
||||
.addTd()
|
||||
.addSpan({'class': 'bm-filter-tbl-crct', 'textContent': middleEllipsis(String(allPixelsCorrect.get(color.id) ?? '0'), 7)}).buildElement()
|
||||
.buildElement()
|
||||
.addTd()
|
||||
.addSpan({'class': 'bm-filter-tbl-totl', 'textContent': middleEllipsis(String(allPixelsColor.get(color.id) ?? '0'), 7)}).buildElement()
|
||||
.buildElement()
|
||||
.addP({'textContent': `Color ID: ${color.id?.toString()?.padStart(2, '0')}, Name: ${color.name}`}).buildElement()
|
||||
.buildElement()
|
||||
}
|
||||
|
||||
// Adds the colors to the color container in the filter window
|
||||
colorList.buildOverlay(windowContent);
|
||||
|
||||
// Overflow ellipse but the ellipse is in the middle, not end of the string
|
||||
function middleEllipsis(text, maxChars) {
|
||||
if (text.length <= maxChars) return text;
|
||||
const half = Math.floor((maxChars - 3) / 2);
|
||||
return (
|
||||
text.slice(0, half) +
|
||||
"…" +
|
||||
text.slice(text.length - half)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function buildOverlayTabTemplate() {
|
||||
|
|
|
|||
147
src/overlay.css
147
src/overlay.css
|
|
@ -1,5 +1,17 @@
|
|||
/* @since 0.5.1 */
|
||||
|
||||
/* Content with this class is only available to screen readers */
|
||||
.bm-screenreader {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* The Blue Marble window(s) */
|
||||
.bm-window {
|
||||
|
|
@ -13,6 +25,7 @@
|
|||
top: 75px;
|
||||
left: 60px;
|
||||
width: auto;
|
||||
max-height: calc(100vh - 150px);
|
||||
max-width: calc(100% - 135px);
|
||||
/* Font stack is as follows:
|
||||
* Highest Priority (Roboto Mono)
|
||||
|
|
@ -152,6 +165,33 @@
|
|||
fill: #111;
|
||||
}
|
||||
|
||||
/* Transparent buttons */
|
||||
.bm-window button.bm-button-trans {
|
||||
background-color: unset;
|
||||
}
|
||||
|
||||
/* Transparent buttons on dark backgrounds when hovered */
|
||||
.bm-button-trans.bm-button-hover-white:hover,
|
||||
.bm-button-trans.bm-button-hover-white:focus {
|
||||
background-color: rgba(255, 255, 255, 0.17);
|
||||
}
|
||||
|
||||
/* Transparent buttons on dark backgrounds when pressed */
|
||||
.bm-button-trans.bm-button-hover-white:active {
|
||||
background-color: rgba(255, 255, 255, 0.22);
|
||||
}
|
||||
|
||||
/* Transparent buttons on light backgrounds when hovered */
|
||||
.bm-button-trans.bm-button-hover-black:hover,
|
||||
.bm-button-trans.bm-button-hover-black:focus {
|
||||
background-color: rgba(0, 0, 0, 0.17);
|
||||
}
|
||||
|
||||
/* Transparent buttons on light backgrounds when pressed */
|
||||
.bm-button-trans.bm-button-hover-black:active {
|
||||
background-color: rgba(0, 0, 0, 0.22);
|
||||
}
|
||||
|
||||
/* Tile (x, y) & Pixel (x, y) input fields */
|
||||
input[type="number"].bm-input-coords {
|
||||
appearance: auto;
|
||||
|
|
@ -230,4 +270,109 @@ input[type="file"] {
|
|||
justify-content: center;
|
||||
align-items: center;
|
||||
gap: 0.5ch;
|
||||
}
|
||||
}
|
||||
|
||||
/* Filter window table container */
|
||||
#bm-window-filter .bm-container:has(table) {
|
||||
max-height: 60vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
/* Filter window table */
|
||||
#bm-window-filter table {
|
||||
table-layout: fixed;
|
||||
width: 50ch;
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 0.5em;
|
||||
}
|
||||
|
||||
/* Filter window table row */
|
||||
#bm-window-filter tr {
|
||||
padding: 0.5em 0;
|
||||
}
|
||||
|
||||
/* Filter window table cell for RGB color display */
|
||||
.bm-filter-tbl-clr {
|
||||
display: block;
|
||||
border: thick double lightgray;
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
padding: 1ch;
|
||||
}
|
||||
|
||||
/* Filter window hide color button */
|
||||
.bm-filter-tbl-clr button {
|
||||
padding: 0.75em 0.5ch;
|
||||
}
|
||||
|
||||
/* Filter window hide color button SVG */
|
||||
.bm-filter-tbl-clr svg {
|
||||
width: 4ch;
|
||||
isolation: isolate;
|
||||
}
|
||||
|
||||
/* Filter window color ID */
|
||||
.bm-filter-tbl-id {
|
||||
position: relative;
|
||||
top: 0.75em;
|
||||
left: 0.5ch;
|
||||
}
|
||||
|
||||
/* Filter window color premium */
|
||||
.bm-filter-tbl-prmim {
|
||||
position: relative;
|
||||
top: 0.75em;
|
||||
left: -3.5ch;
|
||||
}
|
||||
|
||||
/* Filter window color name */
|
||||
.bm-filter-tbl-name {
|
||||
position: relative;
|
||||
top: -0.75em;
|
||||
left: -16ch;
|
||||
text-wrap: nowrap;
|
||||
}
|
||||
|
||||
/* Filter window color correct pixels */
|
||||
.bm-filter-tbl-crct {
|
||||
display: block;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
right: 18ch;
|
||||
top: 0.75em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* Filter window color total pixels */
|
||||
.bm-filter-tbl-totl {
|
||||
display: block;
|
||||
width: 100%;
|
||||
position: relative;
|
||||
left: -16ch;
|
||||
top: 0.75em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.bm-filter-tbl-totl::after {
|
||||
content: "/";
|
||||
position: absolute;
|
||||
left: -1.5ch;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
/* Filter window table footer */
|
||||
#bm-window-filter tfoot {
|
||||
display: table-header-group;
|
||||
}
|
||||
|
||||
/* Filter window table footer header */
|
||||
#bm-window-filter tfoot th {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* Filter window table footer data */
|
||||
#bm-window-filter tfoot td {
|
||||
text-align: right;
|
||||
padding-left: 1ch;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ export default class TemplateManager {
|
|||
// Template
|
||||
this.template = null; // The template image.
|
||||
this.templateState = ''; // The state of the template ('blob', 'proccessing', 'template', etc.)
|
||||
/** @type {Array<Template>} An Array of Template classes */
|
||||
this.templatesArray = []; // All Template instnaces currently loaded (Template)
|
||||
this.templatesJSON = null; // All templates currently loaded (JSON)
|
||||
this.templatesShouldBeDrawn = true; // Should ALL templates be drawn to the canvas?
|
||||
|
|
|
|||
Loading…
Reference in a new issue