1
0
Fork 1
mirror of https://github.com/zen-browser/desktop.git synced 2025-07-07 17:15:30 +02:00

chore: Rewrite motion to animejs, b=no-bug, c=common, compact-mode, glance, media, split-view, vendor, welcome, workspaces

This commit is contained in:
Mr. M 2025-06-24 18:43:12 +02:00
parent 12ae2daeba
commit fdeeb972f7
No known key found for this signature in database
GPG key ID: 6292C4C8F8652B18
17 changed files with 117 additions and 73 deletions

View file

@ -92,7 +92,7 @@
# JS Vendor
content/browser/zen-vendor/tsparticles.confetti.bundle.min.js (../../zen/vendor/tsparticles.confetti.bundle.min.js)
content/browser/zen-vendor/motion.min.mjs (../../zen/vendor/motion.min.mjs)
content/browser/zen-vendor/animejs.min.mjs (../../zen/vendor/animejs.min.mjs)
# FavIcons for startup
content/browser/zen-images/favicons/calendar.ico (../../zen/images/favicons/calendar.ico)

View file

@ -117,7 +117,7 @@ export var ZenCustomizableUI = new (class {
window.setTimeout(() => {
button.removeAttribute('open');
}, 500);
window.gZenUIManager.motion.animate(
window.gZenUIManager.anime.animate(
image,
{ transform: ['rotate(45deg)', 'rotate(0deg)'] },
{ duration: 0.2 }
@ -125,7 +125,7 @@ export var ZenCustomizableUI = new (class {
};
popup.addEventListener('popuphidden', handlePopupHidden, { once: true });
popup.openPopup(button, 'after_start');
window.gZenUIManager.motion.animate(
window.gZenUIManager.anime.animate(
image,
{ transform: ['rotate(0deg)', 'rotate(45deg)'] },
{ duration: 0.2 }

View file

@ -107,7 +107,7 @@
document.documentElement.removeAttribute('zen-before-loaded');
if (Services.prefs.getBoolPref('zen.watermark.enabled', false)) {
let elementsToIgnore = this._watermarkIgnoreElements.map((id) => '#' + id).join(', ');
gZenUIManager.motion
gZenUIManager.anime
.animate(
'#browser > *:not(' + elementsToIgnore + '), #urlbar, #tabbrowser-tabbox > *',
{
@ -115,7 +115,6 @@
},
{
delay: 0.6,
easing: 'ease-in-out',
}
)
.then(() => {

View file

@ -36,10 +36,51 @@ var gZenUIManager = {
document.addEventListener('mousedown', this.handleMouseDown.bind(this), true);
ChromeUtils.defineLazyGetter(this, 'motion', () => {
return ChromeUtils.importESModule('chrome://browser/content/zen-vendor/motion.min.mjs', {
global: 'current',
});
ChromeUtils.defineLazyGetter(this, 'anime', () => {
// Polyphill in case we need to change library animations again
const module = ChromeUtils.importESModule(
'chrome://browser/content/zen-vendor/animejs.min.mjs',
{
global: 'current',
}
);
return {
animate: (element, keyframes, options) => {
if (options.duration) {
options.duration *= 1000; // convert seconds to milliseconds
}
if (options.delay) {
options.delay *= 1000; // convert seconds to milliseconds
}
delete options.bounce; // anime.js does not support bounce
delete options.type; // anime.js does not support type
return module.animate(element, {
...keyframes,
...options,
});
},
waapi: (element, keyframes, options) => {
if (options.duration) {
options.duration *= 1000; // convert seconds to milliseconds
}
if (options.delay) {
options.delay *= 1000; // convert seconds to milliseconds
}
return module.waapi.animate(element, {
...keyframes,
...options,
});
},
stagger: (delay, {
startDelay = 0,
} = {}) => {
delay *= 1000; // convert seconds to milliseconds
startDelay *= 1000; // convert seconds to milliseconds
return module.stagger(delay,{
start: startDelay,
});
},
};
});
ChromeUtils.defineLazyGetter(this, '_toastContainer', () => {
@ -479,7 +520,7 @@ var gZenUIManager = {
this._toastContainer.removeAttribute('hidden');
this._toastContainer.appendChild(toast);
const timeoutFunction = () => {
this.motion
this.anime
.animate(toast, { opacity: [1, 0], scale: [1, 0.5] }, { duration: 0.2, bounce: 0 })
.then(() => {
toast.remove();
@ -489,7 +530,7 @@ var gZenUIManager = {
});
};
if (reused) {
await this.motion.animate(toast, { scale: 0.2 }, { duration: 0.1, bounce: 0 });
await this.anime.animate(toast, { scale: 0.2 }, { duration: 0.1, bounce: 0 });
} else {
toast.addEventListener('mouseover', () => {
if (this._toastTimeouts[messageId]) {
@ -506,7 +547,7 @@ var gZenUIManager = {
if (!toast.style.hasOwnProperty('transform')) {
toast.style.transform = 'scale(0)';
}
await this.motion.animate(toast, { scale: 1 }, { type: 'spring', bounce: 0.2, duration: 0.5 });
await this.anime.animate(toast, { scale: 1 }, { type: 'spring', bounce: 0.2, duration: 0.5 });
if (this._toastTimeouts[messageId]) {
clearTimeout(this._toastTimeouts[messageId]);
}
@ -601,7 +642,7 @@ var gZenVerticalTabsManager = {
},
animateTab(aTab) {
if (!gZenUIManager.motion || !aTab || !gZenUIManager._hasLoadedDOM || !aTab.isConnected) {
if (!gZenUIManager.anime || !aTab || !gZenUIManager._hasLoadedDOM || !aTab.isConnected) {
return;
}
// get next visible tab
@ -613,7 +654,7 @@ var gZenVerticalTabsManager = {
try {
const tabSize = aTab.getBoundingClientRect().height;
const transform = `-${tabSize}px`;
gZenUIManager.motion
gZenUIManager.anime
.animate(
aTab,
{
@ -635,7 +676,7 @@ var gZenVerticalTabsManager = {
aTab.style.removeProperty('transform');
aTab.style.removeProperty('opacity');
});
gZenUIManager.motion
gZenUIManager.anime
.animate(
aTab.querySelector('.tab-content'),
{
@ -1060,7 +1101,7 @@ var gZenVerticalTabsManager = {
}
// Maybe add some confetti here?!?
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
this._tabEdited,
{
scale: [1, 0.98, 1],

View file

@ -279,7 +279,7 @@ var gZenCompactModeManager = {
// TODO: Work on this a bit more, needs polishing
if (lazyCompactMode.COMPACT_MODE_CAN_ANIMATE_SIDEBAR && false) {
gZenUIManager.motion
gZenUIManager.anime
.animate(
[
this.sidebar,
@ -299,7 +299,7 @@ var gZenCompactModeManager = {
],
},
{
ease: 'easeIn',
ease: 'in',
type: 'spring',
bounce: 0,
duration: 0.2,
@ -324,18 +324,16 @@ var gZenCompactModeManager = {
} else {
sidebarWidth -= elementSeparation;
}
gZenUIManager.motion
.animate(
gZenUIManager.anime
.waapi(
this.sidebar,
{
marginRight: this.sidebarIsOnRight ? `-${sidebarWidth}px` : 0,
marginLeft: this.sidebarIsOnRight ? 0 : `-${sidebarWidth}px`,
},
{
ease: 'easeIn',
type: 'spring',
bounce: 0,
duration: 0.2,
ease: 'out',
duration: 0.1,
}
)
.then(() => {
@ -373,8 +371,8 @@ var gZenCompactModeManager = {
} else {
this.sidebar.style.marginLeft = `-${sidebarWidth}px`;
}
gZenUIManager.motion
.animate(
gZenUIManager.anime
.waapi(
this.sidebar,
this.sidebarIsOnRight
? {
@ -383,10 +381,8 @@ var gZenCompactModeManager = {
}
: { marginLeft: 0 },
{
ease: 'easeOut',
type: 'spring',
bounce: 0,
duration: 0.2,
ease: 'in',
duration: 0.1,
}
)
.then(() => {

View file

@ -221,7 +221,7 @@
this.#startBoxAnimation(areTabsPositionedRight);
}
await gZenUIManager.motion.animate(arcAnimationElement, sequence, {
await gZenUIManager.anime.animate(arcAnimationElement, sequence, {
duration: Services.prefs.getIntPref('zen.downloads.download-animation-duration') / 1000,
easing: 'cubic-bezier(0.37, 0, 0.63, 1)',
fill: 'forwards',
@ -353,7 +353,7 @@
wrapper.appendChild(this.#boxAnimationElement);
await gZenUIManager.motion.animate(
await gZenUIManager.anime.animate(
this.#boxAnimationElement,
{
[sideProp]: '34px',
@ -366,7 +366,7 @@
}
).finished;
await gZenUIManager.motion.animate(
await gZenUIManager.anime.animate(
this.#boxAnimationElement,
{
[sideProp]: '24px',
@ -411,7 +411,7 @@
try {
const sideProp = areTabsPositionedRight ? 'right' : 'left';
await gZenUIManager.motion.animate(
await gZenUIManager.anime.animate(
this.#boxAnimationElement,
{
transform: 'scale(0.9)',
@ -422,7 +422,7 @@
}
).finished;
await gZenUIManager.motion.animate(
await gZenUIManager.anime.animate(
this.#boxAnimationElement,
{
[sideProp]: '-50px',

View file

@ -131,10 +131,10 @@
const startX = isRightSide ? -50 : 50;
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
this.sidebarButtons.querySelectorAll('toolbarbutton'),
{ x: [startX, 0], opacity: [0, 1] },
{ delay: gZenUIManager.motion.stagger(0.1) }
{ delay: gZenUIManager.anime.stagger(0.1) }
);
}
this.sidebarButtons.removeAttribute('hidden');
@ -180,7 +180,7 @@
this.quickOpenGlance({ dontOpenButtons: true });
this.showSidebarButtons(true);
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer'),
{
scale: [1, 0.98],
@ -211,7 +211,7 @@
};
this.browserWrapper.style.transform = 'translate(-50%, -50%)';
this.overlay.style.overflow = 'visible';
gZenUIManager.motion
gZenUIManager.anime
.animate(
this.browserWrapper,
{
@ -311,7 +311,7 @@
this.overlay.style.pointerEvents = 'none';
this.quickCloseGlance({ justAnimateParent: true, clearID: false });
const originalPosition = this.#glances.get(this.#currentGlanceID).originalPosition;
gZenUIManager.motion
gZenUIManager.anime
.animate(
this.#currentParentTab.linkedBrowser.closest('.browserSidebarContainer'),
{
@ -332,7 +332,7 @@
});
this.browserWrapper.style.opacity = 1;
return new Promise((resolve) => {
gZenUIManager.motion
gZenUIManager.anime
.animate(
this.browserWrapper,
{
@ -653,7 +653,7 @@
this.finishOpeningGlance();
return;
}
await gZenUIManager.motion.animate(
await gZenUIManager.anime.animate(
this.browserWrapper,
{
width: ['85%', '100%'],

View file

@ -219,7 +219,7 @@
hideMediaControls() {
if (this.mediaControlBar.hasAttribute('hidden')) return;
return gZenUIManager.motion
return gZenUIManager.anime
.animate(
this.mediaControlBar,
{
@ -259,7 +259,7 @@
this.mediaControlBar.querySelector('toolbaritem').getBoundingClientRect().height + 'px';
this.mediaControlBar.style.opacity = 0;
gZenUIManager.updateTabsToolbar();
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
this.mediaControlBar,
{
opacity: [0, 1],

View file

@ -322,7 +322,7 @@ class nsZenViewSplitter extends ZenDOMOperatedFeature {
draggedTab._visuallySelected = true;
this.fakeBrowser.setAttribute('side', side);
this._finishAllAnimatingPromise = Promise.all([
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
gBrowser.tabbox,
side === 'left'
? {
@ -338,7 +338,7 @@ class nsZenViewSplitter extends ZenDOMOperatedFeature {
easing: 'ease-out',
}
),
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
this.fakeBrowser,
{
width: [0, `${halfWidth - padding}px`],
@ -401,7 +401,7 @@ class nsZenViewSplitter extends ZenDOMOperatedFeature {
this._draggingTab = null;
try {
Promise.all([
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
gBrowser.tabbox,
side === 'left'
? {
@ -415,7 +415,7 @@ class nsZenViewSplitter extends ZenDOMOperatedFeature {
easing: 'ease-out',
}
),
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
this.fakeBrowser,
{
width: [`${halfWidth - padding * 2}px`, 0],
@ -1763,7 +1763,7 @@ class nsZenViewSplitter extends ZenDOMOperatedFeature {
}
animateBrowserDrop(browserContainer, callback = () => {}) {
gZenUIManager.motion
gZenUIManager.anime
.animate(
browserContainer,
{

1
src/zen/vendor/animejs.dep vendored Normal file
View file

@ -0,0 +1 @@
https://cdn.jsdelivr.net/npm/animejs/+esm: v4.0.2

15
src/zen/vendor/animejs.min.mjs vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -1 +0,0 @@
https://cdn.jsdelivr.net/npm/motion@latest/+esm: v12.16.0

File diff suppressed because one or more lines are too long

View file

@ -18,7 +18,7 @@
}
function getMotion() {
return gZenUIManager.motion;
return gZenUIManager.anime;
}
async function animate(...args) {

View file

@ -772,7 +772,7 @@
);
if (!this.dragging) {
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
existingDot.element,
{
left: `${dotPosition.position.x}px`,
@ -889,7 +889,7 @@
this.handleColorPositions(colorPositions);
this.updateCurrentWorkspace(true);
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
existingPrimaryDot.element,
{
left: `${existingPrimaryDot.position.x}px`,
@ -1129,7 +1129,7 @@
`linear-gradient(to top, ${color3} -30%, transparent 60%)`,
].join(', ');
}
return [`linear-gradient(${rotation}deg, ${color1} -30%, ${color3} 100%)`].join(', ');
return [`linear-gradient(120deg, ${color1} -30%, ${color3} 100%)`].join(', ');
} else {
// Just return a linear gradient with all colors
const gradientColors = themedColors.map((color) =>
@ -1508,7 +1508,7 @@
// Set `--toolbox-textcolor` to have a contrast with the primary color
const blendTarget = isDarkMode ? [255, 255, 255] : [0, 0, 0];
const blendedColor = this.blendColors(dominantColor, blendTarget, 15); // 15% dominantColor, 85% target
await gZenUIManager.motion.animate(
await gZenUIManager.anime.animate(
browser.document.documentElement,
{
'--toolbox-textcolor': blendedColor,

View file

@ -152,7 +152,7 @@
document.getElementById('zen-sidebar-splitter').style.pointerEvents = 'none';
gZenUIManager.motion
gZenUIManager.anime
.animate(
[gBrowser.tabContainer, gURLBar.textbox],
{
@ -172,7 +172,7 @@
this.style.visibility = 'visible';
gZenCompactModeManager.getAndApplySidebarWidth();
this.resolveInitialized();
gZenUIManager.motion
gZenUIManager.anime
.animate(
this.elementsToAnimate,
{
@ -184,7 +184,7 @@
duration: 0.6,
type: 'spring',
bounce: 0,
delay: gZenUIManager.motion.stagger(0.05, { startDelay: 0.2 }),
delay: gZenUIManager.anime.stagger(0.05, { startDelay: 0.2 }),
}
)
.then(() => {
@ -265,7 +265,7 @@
}
async #cleanup() {
await gZenUIManager.motion.animate(
await gZenUIManager.anime.animate(
this.elementsToAnimate.reverse(),
{
y: [0, 20],
@ -276,7 +276,7 @@
duration: 0.4,
type: 'spring',
bounce: 0,
delay: gZenUIManager.motion.stagger(0.05),
delay: gZenUIManager.anime.stagger(0.05),
}
);
@ -311,7 +311,7 @@
await gZenWorkspaces._organizeWorkspaceStripLocations(workspace, true);
await gZenWorkspaces.updateTabsContainers();
await gZenUIManager.motion.animate(
await gZenUIManager.anime.animate(
[gBrowser.tabContainer, gURLBar.textbox],
{
opacity: [0, 1],

View file

@ -1593,8 +1593,8 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
) {
delete this._alwaysAnimatePaddingTop;
const essentialsHeight = essentialContainer.getBoundingClientRect().height;
if (!forAnimation && animateContainer && gZenUIManager.motion) {
gZenUIManager.motion.animate(
if (!forAnimation && animateContainer && gZenUIManager.anime) {
gZenUIManager.anime.animate(
workspaceElement,
{
paddingTop: [workspaceElement.style.paddingTop, essentialsHeight + 'px'],
@ -1743,7 +1743,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
await new Promise((resolve) => {
requestAnimationFrame(() => {
animations.push(
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
document.documentElement,
{
'--zen-background-opacity': [previousBackgroundOpacity, 1],
@ -1773,7 +1773,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (shouldAnimate) {
const existingPaddingTop = element.style.paddingTop;
animations.push(
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
element,
{
transform: existingTransform ? [existingTransform, newTransform] : newTransform,
@ -1912,7 +1912,7 @@ var gZenWorkspaces = new (class extends ZenMultiWindowFeature {
if (shouldAnimate) {
container.style.transform = existingTransform;
animations.push(
gZenUIManager.motion.animate(
gZenUIManager.anime.animate(
container,
{
transform: [