Текст мерцает при анимации с помощью JS + CSS [закрыто]CSS

Разбираемся в CSS
Ответить
Anonymous
 Текст мерцает при анимации с помощью JS + CSS [закрыто]

Сообщение Anonymous »

Я унаследовал этот фрагмент кода для элемента-героя, который должен быть анимирован, но работает неправильно (актуален только dsektop). Я постараюсь описать это как можно лучше:
Как это должно выглядеть
  • элемент с #centerpiece представляет собой круг с анимированной рамкой; граница рисуется от 0 до 100 в ANIMATION_DURATION,
  • есть строки описаний, каждая из которых имеет формат .description-item-desktop. Их всегда 4, и они располагаются в каждом углу (правом нижнем, левом нижнем, левом верхнем, правом верхнем) относительно #centerpiece. Предполагается, что эти элементы плавают по кривой, следуя за движением часов (и анимированной рамкой, упомянутой ранее),
  • также есть «стрелка» svg — точнее, 4 стрелки, каждая из которых направлена ​​от центра к углу. Они должны оставаться «установленными» в центре и вращать кончик в соответствии с соответствующим элементом описания.
Проблемы, с которыми я столкнулся
В настоящее время у .description-item-desktop есть проблема: при анимации текст мерцает. Похоже, что он рендерится с каждым кадром, но я не уверен. Сейчас это моя самая насущная проблема, но есть и другие: стрелки svg также анимированы правильно, и я не знаю, как добиться желаемого эффекта (подсказка после элемента описания).
Что я пробовал
Я попробовал добавить это в .description-item-desktop, потому что видел, как кто-то упомянул, что это может помочь с мерцающим текстом, но это ничего не изменило.

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

.description-item-desktop {
transition: opacity 1s ease-in-out;
will-change: opacity;
backface-visibility: hidden;
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}

.description-item-desktop.floating-animation {
animation-duration: 7000ms;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
will-change: transform;
transform: translate3d(0, 0, 0);
}
Я также пытался (несколько раз) переработать контроллеры анимации и всю логику, лежащую в их основе, но, честно говоря, не знаю, как это сделать, и для полноценной работы всегда чего-то не хватало (но всегда был мерцающий текст).
Воспроизведение

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

document.addEventListener("DOMContentLoaded", function () {
const configs = {
desktop: {
items: ".description-item-desktop",
progressCircle: ".progress-animated-circle-desktop",
strokeDashoffset: "1071",
hasArrowSvg: true,
backgroundContainer: document.getElementById("hero-background-desktop"),
bgImages: JSON.parse(
document.getElementById("hero-background-desktop").dataset.bgImages ||
"[]",
),
},
mobile: {
items: ".description-item-mobile",
progressCircle: ".progress-animated-circle",
strokeDashoffset: "754",
hasArrowSvg: false,
backgroundContainer: document.getElementById("hero-background-mobile"),
bgImages: JSON.parse(
document.getElementById("hero-background-mobile").dataset.bgImages ||
"[]",
),
},
};

const connectionSvgs = {
rb: document.getElementById("connection-svg-rb"),
lb: document.getElementById("connection-svg-lb"),
rt: document.getElementById("connection-svg-rt"),
lt: document.getElementById("connection-svg-lt"),
};
const ANIMATION_DURATION = 6000; // animation duration
const TRANSITION_DELAY = 500; // delay before starting the next animation for the next container + arrow
const RESET_DELAY = 300;
const START_DELAY = 100;

// controller to handle animations with different parameters, depending on whether env is desktop or mobile
function createAnimationController(type, config) {
const items = document.querySelectorAll(config.items);
const progressCircle = document.querySelector(config.progressCircle);

if (items.length  {
items[currentIndex].classList.remove("opacity-0");
items[currentIndex].classList.add("opacity-100");

updateFloatingAnimation(items[currentIndex], true);

const imageUrl = config.bgImages[currentIndex];
const imageMobileUrl = config.bgImages[currentIndex];

if (type === "desktop") {
const bgEl = document.getElementById("hero-background-desktop");
if (bgEl && imageUrl) {
bgEl.style.backgroundImage = `url('${imageUrl}')`;
}
} else {
const bgEl = document.getElementById("hero-background-mobile");
if (bgEl &&  imageMobileUrl) {
bgEl.style.backgroundImage = `url('${imageMobileUrl}')`;
}
}

if (config.hasArrowSvg) {
updateArrowSvg();
}
}, TRANSITION_DELAY);

resetProgressAnimation();
}

// methods returned by the controller to manually control animations
function start() {
resetProgressAnimation();

if (config.hasArrowSvg) {
updateArrowSvg();
}

interval = setInterval(showNext, ANIMATION_DURATION);
}

function stop() {
if (interval) {
clearInterval(interval);
}
}

return {
start,
stop,
};
}
// creating a controller for each variant
const controllers = {};
Object.keys(configs).forEach((type) => {
const controller = createAnimationController(type, configs[type]);
if (controller) {
controllers[type] = controller;
setTimeout(() =>  controller.start(), START_DELAY);
}
});
});

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

// hero animation
.progress-bg-circle {
@apply fill-none stroke-[rgba(255,255,255,0.2)] stroke-[3];
}
.progress-border {
@apply absolute top-[-3px] left-[-3px] w-[246px] h-[246px] -rotate-90 z-0;
}
.progress-animated-circle {
@apply fill-none stroke-[white] stroke-[3];
stroke-linecap: round;
stroke-dasharray: 754;
stroke-dashoffset: 754;
}
.progress-border-desktop {
@apply absolute top-[-3px] left-[-3px] w-[341px] h-[341px] -rotate-90 z-0;
}
.progress-animated-circle-desktop {
@apply fill-none stroke-[white] stroke-[3];
stroke-linecap: round;
stroke-dasharray: 1071;
stroke-dashoffset: 1071;
}

.right-bottom {
@apply right-[300px] xl:right-[400px];
}
.left-bottom {
@apply left-[300px] xl:left-[400px] text-end;
}
.right-top {
@apply right-[300px] xl:right-[400px] -top-12;
}
.left-top {
@apply left-[300px] xl:left-[400px] text-end -top-12;
}

@keyframes floatArc_rb {
// z lewego dołu do góry
0% {
transform: translateX(0) translateY(0);
}
100% {
transform: translateX(-20px) translateY(-20px);
}
}

@keyframes floatArc_lb {
// z prawego dołu do dołu
0% {
transform: translateX(0) translateY(0);
}
100% {
transform: translateX(-20px) translateY(20px);
}
}

@keyframes floatArc_rt {
// z lewej góry do góry
0% {
transform: translateX(0) translateY(0);
}
100% {
transform: translateX(20px) translateY(-20px);
}
}

@keyframes floatArc_lt {
// z prawej góry do dołu
0% {
transform: translateX(0) translateY(0);
}
100% {
transform: translateX(20px) translateY(20px);
}
}

.description-item-desktop.floating-animation {
animation-duration: 7000ms;
animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
}

.description-item-desktop.floating-rb {
animation-name: floatArc_rb;
}

.description-item-desktop.floating-lb {
animation-name: floatArc_lb;
}

.description-item-desktop.floating-rt {
animation-name: floatArc_rt;
}

.description-item-desktop.floating-lt {
animation-name: floatArc_lt;
}

@keyframes draw-line {
from {
stroke-dasharray: 0 300;
}
to {
stroke-dasharray: 300 300;
}
}

@keyframes scale-circle {
from {
transform: scale(0);
opacity: 0;
}
to {
transform: scale(1);
opacity: 1;
}
}

.arrow-path-animate {
stroke-dasharray: 300 300;
stroke-dashoffset: 0;
animation: draw-line 1s ease-in-out forwards;
}

.arrow-circle-animate {
transform-origin: center;
animation: scale-circle 0.6s ease-in-out forwards;
}

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



[img]

Подробнее здесь: [url]https://stackoverflow.com/questions/79805577/text-flickering-while-animated-with-js-css[/url]
Ответить

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

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

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

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

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