mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
PERF: Animate request animation frame (#13337)
* PERF: requestanimationframe for better performance on pan events * PERF: temporarily remove items on animate
This commit is contained in:
@@ -87,6 +87,7 @@ const SiteHeaderComponent = MountWidget.extend(
|
|||||||
const menuPanels = document.querySelectorAll(".menu-panel");
|
const menuPanels = document.querySelectorAll(".menu-panel");
|
||||||
const menuOrigin = this._panMenuOrigin;
|
const menuOrigin = this._panMenuOrigin;
|
||||||
menuPanels.forEach((panel) => {
|
menuPanels.forEach((panel) => {
|
||||||
|
panel.classList.remove("moving");
|
||||||
if (this._shouldMenuClose(event, menuOrigin)) {
|
if (this._shouldMenuClose(event, menuOrigin)) {
|
||||||
this._animateClosing(panel, menuOrigin);
|
this._animateClosing(panel, menuOrigin);
|
||||||
} else {
|
} else {
|
||||||
@@ -129,6 +130,10 @@ const SiteHeaderComponent = MountWidget.extend(
|
|||||||
) {
|
) {
|
||||||
e.originalEvent.preventDefault();
|
e.originalEvent.preventDefault();
|
||||||
this._isPanning = true;
|
this._isPanning = true;
|
||||||
|
const panel = document.querySelector(".menu-panel");
|
||||||
|
if (panel) {
|
||||||
|
panel.classList.add("moving");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
this._isPanning = false;
|
this._isPanning = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export default Mixin.create({
|
|||||||
//velocity is pixels per ms
|
//velocity is pixels per ms
|
||||||
|
|
||||||
_panState: null,
|
_panState: null,
|
||||||
|
_animationPending: false,
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
@@ -71,9 +72,7 @@ export default Mixin.create({
|
|||||||
//calculate delta x, y, distance from START location
|
//calculate delta x, y, distance from START location
|
||||||
const deltaX = e.clientX - oldState.startLocation.x;
|
const deltaX = e.clientX - oldState.startLocation.x;
|
||||||
const deltaY = e.clientY - oldState.startLocation.y;
|
const deltaY = e.clientY - oldState.startLocation.y;
|
||||||
const distance = Math.round(
|
const distance = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
|
||||||
Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2))
|
|
||||||
);
|
|
||||||
|
|
||||||
//calculate velocity from previous event center location
|
//calculate velocity from previous event center location
|
||||||
const eventDeltaX = e.clientX - oldState.center.x;
|
const eventDeltaX = e.clientX - oldState.center.x;
|
||||||
@@ -87,7 +86,7 @@ export default Mixin.create({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
startLocation: oldState.startLocation,
|
startLocation: oldState.startLocation,
|
||||||
center: { x: Math.round(e.clientX), y: Math.round(e.clientY) },
|
center: { x: e.clientX, y: e.clientY },
|
||||||
velocity,
|
velocity,
|
||||||
velocityX,
|
velocityX,
|
||||||
velocityY,
|
velocityY,
|
||||||
@@ -102,7 +101,7 @@ export default Mixin.create({
|
|||||||
|
|
||||||
_panStart(e) {
|
_panStart(e) {
|
||||||
const newState = {
|
const newState = {
|
||||||
center: { x: Math.round(e.clientX), y: Math.round(e.clientY) },
|
center: { x: e.clientX, y: e.clientY },
|
||||||
startLocation: { x: e.clientX, y: e.clientY },
|
startLocation: { x: e.clientX, y: e.clientY },
|
||||||
velocity: 0,
|
velocity: 0,
|
||||||
velocityX: 0,
|
velocityX: 0,
|
||||||
@@ -122,6 +121,7 @@ export default Mixin.create({
|
|||||||
this._panStart(e);
|
this._panStart(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const previousState = this._panState;
|
const previousState = this._panState;
|
||||||
const newState = this._calculateNewPanState(previousState, e);
|
const newState = this._calculateNewPanState(previousState, e);
|
||||||
if (previousState.start && newState.distance < MINIMUM_SWIPE_DISTANCE) {
|
if (previousState.start && newState.distance < MINIMUM_SWIPE_DISTANCE) {
|
||||||
@@ -137,7 +137,17 @@ export default Mixin.create({
|
|||||||
) {
|
) {
|
||||||
this.panEnd(newState);
|
this.panEnd(newState);
|
||||||
} else if (e.type === "pointermove" && "panMove" in this) {
|
} else if (e.type === "pointermove" && "panMove" in this) {
|
||||||
this.panMove(newState);
|
if (this._animationPending) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._animationPending = true;
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
if (!this._animationPending) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.panMove(newState);
|
||||||
|
this._animationPending = false;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -27,12 +27,20 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.menu-panel.slide-in {
|
.menu-panel.slide-in {
|
||||||
transform: translate(var(--offset), 0);
|
transform: translateX(var(--offset));
|
||||||
@media (prefers-reduced-motion: no-preference) {
|
@media (prefers-reduced-motion: no-preference) {
|
||||||
&.animate {
|
&.animate {
|
||||||
transition: transform 0.1s linear;
|
transition: transform 0.1s linear;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
&.moving,
|
||||||
|
&.animate {
|
||||||
|
// PERF: only render first 20 items in a list to allow for smooth
|
||||||
|
// pan events
|
||||||
|
li:nth-child(n + 20) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-menu .quick-access-panel.quick-access-profile li:not(.show-all) {
|
.user-menu .quick-access-panel.quick-access-profile li:not(.show-all) {
|
||||||
|
|||||||
Reference in New Issue
Block a user