Проблема с эффективной CSS-анимацией развертывания/свертывания при рендеринге текста шрифта.CSS

Разбираемся в CSS
Ответить Пред. темаСлед. тема
Anonymous
 Проблема с эффективной CSS-анимацией развертывания/свертывания при рендеринге текста шрифта.

Сообщение Anonymous »

Я пытаюсь создать анимацию развертывания/свертывания разделов, используя это руководство от Google, чтобы обеспечить максимальную производительность. В конце статьи упоминается

Предостережение по поводу этого конкретного варианта: в Chrome текст на экранах с низким разрешением во время анимации размыт из-за ошибок округления из-за масштаб и контрмасштаб текста. Если вас интересуют подробности, есть сообщение об ошибке, которое вы можете отметить и следить за ним.

Пытался вручную исправить ошибки округления кадров, но не повезло.
Скриншот Firefox во время анимации (текст не плавный):
[img]https://i .sstatic.net/V0fBnhot.png[/img]

Снимок экрана Firefox после завершения анимации (мигает, чтобы сгладить текст):
Изображение

Некоторые наблюдения
  • На экране MacBook Pro проблем с Chrome вообще нет.
  • На экране MacBook Pro Firefox — текст плавный во время анимации, но в конце мигает немного жирнее (эта проблема произойдет в Chrome, если вы опустите will-change в анимированных элементах, но, очевидно, это не поможет FFox).
  • На мониторе с более низким разрешением поведение в значительной степени является то же самое (не плавное во время анимации), но за исключением того, что в Chrome оно остается «не плавным» после окончания анимации, если я ставлю will-change, в противном случае мигание станет плавным.
Поскольку код длиннее, для вашего удобства я также предоставил Codepen, который также встроен сюда.

Код: Выделить всё

"use strict";

class Expando {
constructor() {
this._el = document.querySelector(".content");
const toggleEl = document.querySelectorAll(".section-header");
this._toggleBtn = document.querySelector(".toggle");
this._sections = [...document.querySelectorAll(".expand-collapse-section")];
this._isExpanded = new Array(this._sections.length).fill(false);

this._createEaseAnimations();

toggleEl.forEach((el) => {
el.addEventListener("click", (e) => {
el.querySelector(".toggle").classList.toggle("expanded");
const section = e.target.closest(".expand-collapse-section");
const content = section.querySelector(".content");
const idx = this._sections.indexOf(section);
this.toggle(content, idx);
});
});

// measure single content element's margin-top (they all have the same margin in CSS)
const rgx = /(.+)px/;
const marginTopPx = window.getComputedStyle(this._el, null).marginTop;
const results = rgx.exec(marginTopPx);
this._contentTopMargin = +results[1] || 0;
}

expand(el, sectionIdx) {
if (this._isExpanded[sectionIdx]) {
return;
}

this._isExpanded[sectionIdx] = true;

this._applyAnimation(el, { expand: true });
}

collapse(el, sectionIdx) {
if (!this._isExpanded[sectionIdx]) {
return;
}

this._isExpanded[sectionIdx] = false;

this._applyAnimation(el, { expand: false });
}

toggle(el, sectionIdx) {
const expanded = this._isExpanded[sectionIdx];

if (expanded) {
return this.collapse(el, sectionIdx);
}

this.expand(el, sectionIdx);
}

_applyAnimation(el, { expand } = opts) {
function setTranslation(el, { height, start, expand } = opts) {
const translation = start ? (expand ? -height : 0) : (expand ? 0 : -height);

if (translation === 0) {
el.removeAttribute("style");
} else {
el.style.transform = `translateY(${translation}px)`;
}
}

const elInner = el.querySelector(".content-inner");
el.classList.remove("item--expanded");
el.classList.remove("item--collapsed");
elInner.classList.remove("item__contents--expanded");
elInner.classList.remove("item__contents--collapsed");

const sectionEl = el.closest(".expand-collapse-section");
const sectionContent = sectionEl.querySelector(".content");
sectionContent.style.display = "block"; // block to expand, has no effect on collapse (in the end of animation it gets set to none)
const index = this._sections.indexOf(sectionEl);
const targetContentHeight = sectionContent.offsetHeight + this._contentTopMargin;

for (let i = index + 1; i < this._sections.length; i++) {
const curr = this._sections[i];
// don't animate yet translation of adjacent sections, just set initial value for animation
curr.classList.add("notransition");

// setting section content to display block pushes the other items by its height as it has transform set, but it still occupies its original height
// initial value for animation
setTranslation(curr, { height: targetContentHeight, start: true, expand });
}
// the rest of the content below the expandable sections
const lastSectionSibling = this._sections.slice(-1)[0].nextElementSibling;
lastSectionSibling.classList.add("notransition");
setTranslation(lastSectionSibling, { height: targetContentHeight, start: true, expand });

requestAnimationFrame(() => {
if (expand) {
el.classList.add("item--expanded");
elInner.classList.add("item__contents--expanded");
} else {
el.classList.add("item--collapsed");
elInner.classList.add("item__contents--collapsed");
}

sectionEl.offsetHeight; // needed for Firefox on expand

// sectionEl.offsetHeight; -> not needed in requestAnimationFrame

for (let i = index + 1; i < this._sections.length; i++) {
const curr = this._sections[i];

// trigger translation animation of adjacent sections and rest of the content now
curr.classList.remove("notransition");
setTranslation(curr, { height: targetContentHeight, start: false, expand });
sectionEl.offsetHeight; // needed for Firefox on expand
}
lastSectionSibling.classList.remove("notransition");
setTranslation(lastSectionSibling, { height: targetContentHeight, start: false, expand });

if (!expand) {
sectionContent.addEventListener("animationend", () => {
sectionContent.style.display = "none";

for (let i = index + 1; i < this._sections.length; i++) {
const curr = this._sections[i];
// avoid unexpected animations when removing transform inline style in the end of the animation, needs reflow
curr.classList.add("notransition");
// could also be set to translateY(0)
curr.removeAttribute("style");
// should force reflow here otherwise there will be no net change in notransition class which would animate transform, which we don't want,
// we're just removing the unnecessary style attribute
sectionEl.offsetHeight;
curr.classList.remove("notransition");
}

lastSectionSibling.classList.add("notransition");
lastSectionSibling.removeAttribute("style");
sectionEl.offsetHeight;
lastSectionSibling.classList.remove("notransition");
}, { once: true });
}
});
}

_createEaseAnimations() {
let ease = document.querySelector(".ease");
if (ease) {
return ease;
}

ease = document.createElement("style");
ease.classList.add("ease");

console.log('------------- Expand animation --------------');
const expandAnimation = [];
const expandContentsAnimation = [];
const collapseAnimation = [];
const collapseContentsAnimation = [];
for (let i = 0; i 

Подробнее здесь: [url]https://stackoverflow.com/questions/78467505/efficient-expand-collapse-css-animation-issue-with-font-text-rendering[/url]
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Ярлык для свертывания/свертывания всех методов в PyCharm
    Anonymous » » в форуме Python
    0 Ответы
    25 Просмотры
    Последнее сообщение Anonymous
  • Кнопки закрытия, свертывания и развертывания форм C#
    Anonymous » » в форуме C#
    0 Ответы
    22 Просмотры
    Последнее сообщение Anonymous
  • Удаление кнопок свертывания/развертывания в Tkinter
    Anonymous » » в форуме Python
    0 Ответы
    35 Просмотры
    Последнее сообщение Anonymous
  • Непредсказуемое поведение свертывания/развертывания в реализации UICollectionViewListCell
    Anonymous » » в форуме IOS
    0 Ответы
    47 Просмотры
    Последнее сообщение Anonymous
  • Почему моя анимация развертывания/свертывания «прыгает»?
    Anonymous » » в форуме CSS
    0 Ответы
    5 Просмотры
    Последнее сообщение Anonymous

Вернуться в «CSS»