mirror of
https://github.com/SwingTheVine/Wplace-BlueMarble.git
synced 2026-05-06 07:38:56 +00:00
Animate Color Filter eye icon
This commit is contained in:
parent
a051225dc7
commit
ca7b60505b
7 changed files with 171 additions and 58 deletions
74
dist/BlueMarble-For-GreasyFork.user.css
vendored
74
dist/BlueMarble-For-GreasyFork.user.css
vendored
|
|
@ -746,23 +746,7 @@ input[type=file] {
|
|||
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;
|
||||
content: none;
|
||||
}
|
||||
#bm-window-filter .bm-filter-color-toggle {
|
||||
cursor: pointer;
|
||||
|
|
@ -859,6 +843,7 @@ input[type=file] {
|
|||
flex-direction: column;
|
||||
}
|
||||
#bm-window-filter:not(.bm-windowed) .bm-filter-color-main {
|
||||
position: static;
|
||||
justify-content: flex-start;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
|
@ -937,20 +922,61 @@ input[type=file] {
|
|||
filter: drop-shadow(0 1px 0 rgba(255, 255, 255, 0.18));
|
||||
}
|
||||
#bm-window-filter:not(.bm-windowed) .bm-filter-container-rgb {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 0.52rem;
|
||||
bottom: 0.46rem;
|
||||
z-index: 1;
|
||||
display: inline-flex;
|
||||
width: 1.65rem;
|
||||
height: 1.65rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
color: currentColor;
|
||||
background: transparent !important;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
opacity: 0.72;
|
||||
pointer-events: none;
|
||||
}
|
||||
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-state=hidden] .bm-filter-container-rgb {
|
||||
opacity: 0.88;
|
||||
}
|
||||
#bm-window-filter:not(.bm-windowed) .bm-filter-container-rgb button {
|
||||
min-width: 3rem;
|
||||
min-height: 3rem;
|
||||
min-width: 1.65rem;
|
||||
min-height: 1.65rem;
|
||||
padding: 0;
|
||||
border-radius: 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;
|
||||
width: 1.65rem;
|
||||
height: 1.65rem;
|
||||
filter: none;
|
||||
transform: translateY(0.08rem);
|
||||
}
|
||||
#bm-window-filter .bm-filter-color-visibility.bm-filter-eye-animate-hide .bm-filter-eye-icon path:nth-of-type(3),
|
||||
#bm-window-filter .bm-filter-color-visibility.bm-filter-eye-animate-show .bm-filter-eye-icon path:nth-of-type(3) {
|
||||
stroke-dasharray: 20;
|
||||
}
|
||||
#bm-window-filter .bm-filter-color-visibility.bm-filter-eye-animate-hide .bm-filter-eye-icon path:nth-of-type(3) {
|
||||
stroke-dashoffset: 20;
|
||||
animation: bm-filter-eye-slash-draw 220ms ease-out forwards;
|
||||
}
|
||||
#bm-window-filter .bm-filter-color-visibility.bm-filter-eye-animate-show .bm-filter-eye-icon path:nth-of-type(3) {
|
||||
stroke-dashoffset: 0;
|
||||
animation: bm-filter-eye-slash-erase 220ms ease-in forwards;
|
||||
}
|
||||
@keyframes bm-filter-eye-slash-draw {
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
@keyframes bm-filter-eye-slash-erase {
|
||||
to {
|
||||
stroke-dashoffset: 20;
|
||||
}
|
||||
}
|
||||
#bm-window-filter .bm-filter-color > .bm-flex-between {
|
||||
flex-direction: column;
|
||||
|
|
@ -1405,4 +1431,4 @@ input[type=file] {
|
|||
|
||||
/* src/main.css */
|
||||
|
||||
/* Build Hash: 79650aaae24f */
|
||||
/* Build Hash: 25440fe32125 */
|
||||
|
|
|
|||
31
dist/BlueMarble-For-GreasyFork.user.js
vendored
31
dist/BlueMarble-For-GreasyFork.user.js
vendored
|
|
@ -2464,7 +2464,7 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
|
|||
}
|
||||
return `${month}/${day}/${year} ${hour}:${minute}${period}`;
|
||||
}
|
||||
var _WindowFilter_instances, getWindowState_fn2, prefersWindowedMode_fn, setWindowModePreference_fn, syncSortFormControls_fn, closeWindow_fn2, startAutoRefresh_fn, stopAutoRefresh_fn, cleanupWindowPersistence_fn, clampWindowDimension_fn, clampWindowPosition_fn2, restoreWindowState_fn, saveWindowState_fn, scheduleWindowStateSave_fn, initializeWindowedPersistence_fn, buildColorList_fn, sortColorList_fn, selectColorList_fn, syncColorToggleLabel_fn, toggleColorVisibility_fn, initializeColorBlockToggle_fn, calculatePixelStatistics_fn;
|
||||
var _WindowFilter_instances, getWindowState_fn2, prefersWindowedMode_fn, setWindowModePreference_fn, syncSortFormControls_fn, closeWindow_fn2, startAutoRefresh_fn, stopAutoRefresh_fn, cleanupWindowPersistence_fn, clampWindowDimension_fn, clampWindowPosition_fn2, restoreWindowState_fn, saveWindowState_fn, scheduleWindowStateSave_fn, initializeWindowedPersistence_fn, buildColorList_fn, sortColorList_fn, selectColorList_fn, syncColorToggleLabel_fn, toggleColorVisibility_fn, animateColorToggleIcon_fn, initializeColorBlockToggle_fn, calculatePixelStatistics_fn;
|
||||
var WindowFilter = class extends Overlay {
|
||||
/** Constructor for the color filter window
|
||||
* @param {*} executor - The executing class
|
||||
|
|
@ -3157,15 +3157,40 @@ Getting Y ${pixelY}-${pixelY + drawSizeY}`);
|
|||
button.innerHTML = this.eyeClosed;
|
||||
button.dataset["state"] = "hidden";
|
||||
this.templateManager.setColorFiltered(color.id, true);
|
||||
__privateMethod(this, _WindowFilter_instances, animateColorToggleIcon_fn).call(this, button, "hide");
|
||||
} else {
|
||||
button.innerHTML = this.eyeOpen;
|
||||
button.dataset["state"] = "shown";
|
||||
this.templateManager.setColorFiltered(color.id, false);
|
||||
__privateMethod(this, _WindowFilter_instances, animateColorToggleIcon_fn).call(this, button, "show");
|
||||
}
|
||||
__privateMethod(this, _WindowFilter_instances, syncColorToggleLabel_fn).call(this, button, color);
|
||||
button.disabled = false;
|
||||
button.style.textDecoration = "";
|
||||
};
|
||||
/** Animates the eye slash only for direct visibility toggles.
|
||||
* @param {HTMLButtonElement} button - The color visibility button
|
||||
* @param {'hide' | 'show'} direction - Which slash animation to play
|
||||
* @since 0.95.0
|
||||
*/
|
||||
animateColorToggleIcon_fn = function(button, direction) {
|
||||
if (!button) {
|
||||
return;
|
||||
}
|
||||
const animateClass = direction == "hide" ? "bm-filter-eye-animate-hide" : "bm-filter-eye-animate-show";
|
||||
button.classList.remove("bm-filter-eye-animate-hide", "bm-filter-eye-animate-show");
|
||||
void button.offsetWidth;
|
||||
button.classList.add(animateClass);
|
||||
let timeoutID = null;
|
||||
const finishAnimation = () => {
|
||||
window.clearTimeout(timeoutID);
|
||||
button.classList.remove(animateClass);
|
||||
if (direction == "show" && button.dataset["state"] == "shown") {
|
||||
button.innerHTML = this.eyeOpen;
|
||||
}
|
||||
};
|
||||
button.addEventListener("animationend", finishAnimation, { once: true });
|
||||
timeoutID = window.setTimeout(finishAnimation, 280);
|
||||
};
|
||||
/** Makes a color block toggleable by pointer or keyboard.
|
||||
* @param {HTMLElement} colorElement - The color block element
|
||||
* @param {Object} color - Palette color metadata
|
||||
|
|
@ -4681,4 +4706,4 @@ Time Since Blink: ${String(Math.floor(elapsed / 6e4)).padStart(2, "0")}:${String
|
|||
}
|
||||
})();
|
||||
|
||||
// Build Hash: 339f830865b8
|
||||
// Build Hash: a40147b07f84
|
||||
|
|
|
|||
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
4
dist/BlueMarble.user.css
vendored
4
dist/BlueMarble.user.css
vendored
File diff suppressed because one or more lines are too long
4
dist/BlueMarble.user.js
vendored
4
dist/BlueMarble.user.js
vendored
File diff suppressed because one or more lines are too long
|
|
@ -177,24 +177,7 @@
|
|||
}
|
||||
|
||||
#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;
|
||||
content: none;
|
||||
}
|
||||
|
||||
#bm-window-filter .bm-filter-color-toggle {
|
||||
|
|
@ -310,6 +293,7 @@
|
|||
}
|
||||
|
||||
#bm-window-filter:not(.bm-windowed) .bm-filter-color-main {
|
||||
position: static;
|
||||
justify-content: flex-start;
|
||||
gap: 0.4rem;
|
||||
}
|
||||
|
|
@ -409,22 +393,69 @@
|
|||
}
|
||||
|
||||
#bm-window-filter:not(.bm-windowed) .bm-filter-container-rgb {
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 0.52rem;
|
||||
bottom: 0.46rem;
|
||||
z-index: 1;
|
||||
display: inline-flex;
|
||||
width: 1.65rem;
|
||||
height: 1.65rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
color: currentColor;
|
||||
background: transparent !important;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
box-shadow: none;
|
||||
opacity: 0.72;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
#bm-window-filter:not(.bm-windowed) .bm-filter-color[data-state="hidden"] .bm-filter-container-rgb {
|
||||
opacity: 0.88;
|
||||
}
|
||||
|
||||
#bm-window-filter:not(.bm-windowed) .bm-filter-container-rgb button {
|
||||
min-width: 3rem;
|
||||
min-height: 3rem;
|
||||
min-width: 1.65rem;
|
||||
min-height: 1.65rem;
|
||||
padding: 0;
|
||||
border-radius: 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;
|
||||
width: 1.65rem;
|
||||
height: 1.65rem;
|
||||
filter: none;
|
||||
transform: translateY(0.08rem);
|
||||
}
|
||||
|
||||
#bm-window-filter .bm-filter-color-visibility.bm-filter-eye-animate-hide .bm-filter-eye-icon path:nth-of-type(3),
|
||||
#bm-window-filter .bm-filter-color-visibility.bm-filter-eye-animate-show .bm-filter-eye-icon path:nth-of-type(3) {
|
||||
stroke-dasharray: 20;
|
||||
}
|
||||
|
||||
#bm-window-filter .bm-filter-color-visibility.bm-filter-eye-animate-hide .bm-filter-eye-icon path:nth-of-type(3) {
|
||||
stroke-dashoffset: 20;
|
||||
animation: bm-filter-eye-slash-draw 220ms ease-out forwards;
|
||||
}
|
||||
|
||||
#bm-window-filter .bm-filter-color-visibility.bm-filter-eye-animate-show .bm-filter-eye-icon path:nth-of-type(3) {
|
||||
stroke-dashoffset: 0;
|
||||
animation: bm-filter-eye-slash-erase 220ms ease-in forwards;
|
||||
}
|
||||
|
||||
@keyframes bm-filter-eye-slash-draw {
|
||||
to {
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bm-filter-eye-slash-erase {
|
||||
to {
|
||||
stroke-dashoffset: 20;
|
||||
}
|
||||
}
|
||||
|
||||
/* Filter window container for color information */
|
||||
|
|
|
|||
|
|
@ -864,10 +864,11 @@ export default class WindowFilter extends Overlay {
|
|||
button.innerHTML = this.eyeClosed;
|
||||
button.dataset['state'] = 'hidden';
|
||||
this.templateManager.setColorFiltered(color.id, true);
|
||||
this.#animateColorToggleIcon(button, 'hide');
|
||||
} else {
|
||||
button.innerHTML = this.eyeOpen;
|
||||
button.dataset['state'] = 'shown';
|
||||
this.templateManager.setColorFiltered(color.id, false);
|
||||
this.#animateColorToggleIcon(button, 'show');
|
||||
}
|
||||
|
||||
this.#syncColorToggleLabel(button, color);
|
||||
|
|
@ -875,6 +876,36 @@ export default class WindowFilter extends Overlay {
|
|||
button.style.textDecoration = '';
|
||||
}
|
||||
|
||||
/** Animates the eye slash only for direct visibility toggles.
|
||||
* @param {HTMLButtonElement} button - The color visibility button
|
||||
* @param {'hide' | 'show'} direction - Which slash animation to play
|
||||
* @since 0.95.0
|
||||
*/
|
||||
#animateColorToggleIcon(button, direction) {
|
||||
if (!button) {return;}
|
||||
|
||||
const animateClass = direction == 'hide' ? 'bm-filter-eye-animate-hide' : 'bm-filter-eye-animate-show';
|
||||
button.classList.remove('bm-filter-eye-animate-hide', 'bm-filter-eye-animate-show');
|
||||
|
||||
// Restart the class-driven SVG stroke animation when the same color is toggled repeatedly.
|
||||
void button.offsetWidth;
|
||||
|
||||
button.classList.add(animateClass);
|
||||
|
||||
let timeoutID = null;
|
||||
const finishAnimation = () => {
|
||||
window.clearTimeout(timeoutID);
|
||||
button.classList.remove(animateClass);
|
||||
|
||||
if ((direction == 'show') && (button.dataset['state'] == 'shown')) {
|
||||
button.innerHTML = this.eyeOpen;
|
||||
}
|
||||
};
|
||||
|
||||
button.addEventListener('animationend', finishAnimation, {once: true});
|
||||
timeoutID = window.setTimeout(finishAnimation, 280);
|
||||
}
|
||||
|
||||
/** Makes a color block toggleable by pointer or keyboard.
|
||||
* @param {HTMLElement} colorElement - The color block element
|
||||
* @param {Object} color - Palette color metadata
|
||||
|
|
|
|||
Loading…
Reference in a new issue