From 263ee4cb86634868a4ad4840e7e11c31b158482c Mon Sep 17 00:00:00 2001 From: Aman Agrawal Date: Wed, 24 May 2023 06:12:18 +0000 Subject: [PATCH] feedback_widget: Don't use non-optimal animation properties. Animating `box-shadow` and `top` is slow since the browser drops frames when animating them. We can fix it by using `will-change` property but it is just better to not animate them and instead use transform. --- web/src/feedback_widget.ts | 13 +++++++-- web/styles/zulip.css | 56 ++++++++++++++++++++++---------------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/web/src/feedback_widget.ts b/web/src/feedback_widget.ts index 9568a1b8f7..0820556b7a 100644 --- a/web/src/feedback_widget.ts +++ b/web/src/feedback_widget.ts @@ -64,7 +64,16 @@ const animate = { } if (meta.$container) { - meta.$container.fadeOut(500).removeClass("show"); + meta.$container.addClass("slide-out-feedback-container"); + // Delay setting `display: none` enough that the hide animation starts. + setTimeout( + () => + meta.$container?.removeClass([ + "show-feedback-container", + "slide-out-feedback-container", + ]), + 50, + ); meta.opened = false; meta.alert_hover_state = false; } @@ -75,7 +84,7 @@ const animate = { } if (meta.$container) { - meta.$container.fadeIn(500).addClass("show"); + meta.$container.addClass("show-feedback-container"); meta.opened = true; setTimeout(() => animate.maybe_close(), 100); } diff --git a/web/styles/zulip.css b/web/styles/zulip.css index 5afe8010b1..ca72800abe 100644 --- a/web/styles/zulip.css +++ b/web/styles/zulip.css @@ -284,28 +284,50 @@ p.n-margin { top: -2px; } +/* See https://web.dev/animations-guide/#triggers before adding any funny animation properties here. */ +@keyframes feedback-slide-in { + from { + transform: translateY(-120%); + opacity: 0; + } + + to { + transform: translateY(50px); + opacity: 1; + } +} + +@keyframes feedback-slide-out { + from { + transform: translateY(50px); + opacity: 1; + } + + to { + transform: translateY(-120%); + opacity: 0; + } +} + #feedback_container { display: none; - position: absolute; + position: fixed; width: 400px; top: 0; left: calc(50vw - 220px); padding: 15px; - background-color: hsl(0deg 0% 98%); border-radius: 5px; box-shadow: 0 0 30px hsl(0deg 0% 0% / 25%); z-index: 110; - animation-name: pulse; - animation-iteration-count: infinite; - animation-duration: 2s; + &.show-feedback-container { + display: block; + animation: feedback-slide-in 0.6s forwards; + } - transition-property: top, bottom; - transition-duration: 0.5s; - - &.show { - top: 50px; + &.slide-out-feedback-container { + animation: feedback-slide-out 0.6s; } & h3 { @@ -321,20 +343,6 @@ p.n-margin { } } -@keyframes pulse { - 0% { - box-shadow: 0 0 30px hsl(0deg 0% 0% / 35%); - } - - 50% { - box-shadow: 0 0 30px hsl(0deg 0% 0% / 15%); - } - - 100% { - box-shadow: 0 0 30px hsl(0deg 0% 0% / 35%); - } -} - .fade-in-message { animation-name: fadeInMessage; animation-duration: 1s;