CSS Transform Animation на iOS работает правильно только после главного экрана/блокировки и повторного открытия браузераIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 CSS Transform Animation на iOS работает правильно только после главного экрана/блокировки и повторного открытия браузера

Сообщение Anonymous »

У меня есть элемент в HTML, стилизованный под светодиодный дисплей с горизонтальной прокруткой:

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

.led-display {
width: 100vw;
height: 50px;
background-color: black;
overflow: hidden;
position: relative;
display: flex;
align-items: center;
}

.scrolling-text {
white-space: pre;
color: rgb(255, 94, 94);
font-size: 24px;
font-family: 'Scoreboard';
position: absolute;
}

.scrolling-text,
.message {
text-shadow:
0 0 5px #f00,
0 0 10px #f00,
0 0 20px #f00,
0 0 40px #f00;
will-change: transform;
animation-name: scroll-left;
animation-timing-function: linear;
animation-iteration-count: infinite;
}

@keyframes scroll-left {
from {
transform: translateX(100vw);
-webkit-transform: translateX(100vw);
}

to {
transform: translateX(-100%);
-webkit-transform: translateX(-100%);
}
}

Я использую JavaScript для получения данных для каждого сообщения, добавления интервалов между ними и расчета продолжительности анимации — и все это в прослушивателе событий DOMContentLoaded:

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

fetch('/static/messages.txt')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.text();
})
.then(data => {
const messages = data.split('\n').filter(msg => msg.trim() !== ''); // Split lines and remove empty ones
const scrollingText = document.getElementById('scrollingText');

// Add a large space between each message
const spacedMessages = messages.map(msg => msg + ' '.repeat(20)).join('');
console.log("spaced the messages")

// Wait for the browser to calculate the width
requestAnimationFrame(() => {
const textWidth = scrollingText.offsetWidth; // Measure the full width of the scrolling content
const displayWidth = document.querySelector('.led-display').offsetWidth;

// Calculate animation duration (e.g., 0.05 seconds per pixel)
const animationDuration = (textWidth + displayWidth) / 100; // Adjust speed as needed

// Update the CSS animation duration dynamically
scrollingText.style.animationDuration = `${animationDuration}s`;
const reflowTrigger = scrollingText.offsetHeight; // Read a property to trigger a reflow

// Add precise padding to avoid long pauses
scrollingText.style.paddingRight = `${displayWidth}px`;
});

scrollingText.textContent = spacedMessages;
console.log("appended text content")
})
.catch(err => {
console.error('Error loading messages:', err);
document.getElementById('scrollingText').textContent = 'Error loading messages.';
});
Проблема, с которой я сталкиваюсь только на устройствах iOS (пока), заключается в том, что текстовое содержимое начинает прокручиваться справа налево, как и ожидалось, но вскоре после анимации, текст, перешедший крайний правый край на видимый дисплей, исчезает, а один или два фрагмента оставшегося текста переходят через край на видимый дисплей и также исчезают, обычно после одного или двух таких фрагментов, не более длинных появляется текст.
Наиболее неожиданная часть проблемы заключается в том, что проблема существует при первой загрузке страницы или ее обновлении; но если я проведу пальцем по экрану, чтобы перейти на домашнюю страницу iPhone, и быстро вернусь в браузер, или если я заблокирую устройство и снова разблокирую его, анимация будет воспроизводиться заметно быстрее, чем раньше, и никаких проблем с исчезновением текста не будет. присутствуют!
Если у кого-то есть опыт решения подобных проблем, я был бы очень благодарен услышать, что я мог бы улучшить, чтобы это исправить — спасибо.
Итак, как вы можете заметить по моему дрянному javascript, я хотел вызвать такое поведение в коде, но у меня ничего не получилось, и я не уверен, какой правильный термин для этого поведения — ИИ говорит, что это «перекомпоновка».
Я пытался добавить код после js, чтобы отключить и снова включить видимость, чтобы посмотреть, поможет ли этот повторный запуск, но, увы, нет:

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

scrollingText.style.visibility = 'hidden';

scrollingText.offsetHeight;

scrollingText.style.visibility = 'visible';
Я добавил префиксы webkit в CSS, те, которые, как я знал, не работали, и изо всех сил пытался найти информацию, которая показалась мне особенно полезной.
Я попробовал это на нескольких устройствах iOS, поэтому я уверен, что это не проблема с кэшированием CSS, и я совершенно уверен, что это должно работать на iOS 17; я видел на своем телефоне другие веб-сайты, на которых такой элемент работал нормально.

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

document.addEventListener('DOMContentLoaded', () => {
const multilineString = `
Welcome to our display!
Stay tuned for updates.
Don't miss our special offers!
`;

// Split the multiline string into an array of messages and remove empty ones
const messages = multilineString.trim().split('\n').filter(msg => msg.trim() !== '');

const scrollingText = document.getElementById('scrollingText');

// Add spacing between messages, but not after the last one
const spacedMessages = messages.map((msg, index) => {
return index < messages.length - 1 ? msg + ' '.repeat(20) : msg; // Add spaces only if not the last item
}).join('');
scrollingText.textContent = spacedMessages;

// Use requestAnimationFrame to ensure the text content is fully rendered before measuring
requestAnimationFrame(() => {
const textWidth = scrollingText.scrollWidth; // Measure the full width of the scrolling content
const displayWidth = document.querySelector('.led-display').offsetWidth;

console.log("Measured text width:", textWidth); // Log the measured text width
console.log("Display width:", displayWidth); // Log the display width

// Calculate the animation duration (e.g., 0.05 seconds per pixel)
const animationDuration = (textWidth + displayWidth) / 100; // Adjust speed as needed
console.log("Animation Duration:", animationDuration); // Log the animation duration

// Add precise padding to avoid long pauses
scrollingText.style.paddingRight = `${displayWidth}px`;

// Stop the animation and reinitialize it
scrollingText.style.animation = 'none'; // Stop the animation
scrollingText.offsetHeight; // Trigger a reflow (if needed)
scrollingText.style.animation = ''; // Restart the animation

// Prefetch the animation pipeline
scrollingText.style.animation = 'scroll-left 0s linear infinite'; // Prefetch animation
scrollingText.offsetWidth; // Trigger reflow

// Add a 200ms delay before starting the animation
setTimeout(() => {
scrollingText.style.animation = `scroll-left ${animationDuration}s linear infinite`; // Set correct duration
console.log("Animation initialized successfully.");
}, 200); // 200ms delay before triggering the animation
});
});

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

@keyframes scroll-left {
from {
transform: translateX(100vw);
/* Start from the right edge */
}

to {
transform: translateX(-100%);
/* End after the entire text has moved out of view */
}
}

.doto-  {
font-family: "Doto", sans-serif;
font-optical-sizing: auto;
font-weight: ;
font-style: normal;
font-variation-settings:
"ROND" 0;
}

body {
overflow: hidden;
}

.led-display {
width: 100%;
height: 50px;
background-color: black;
clip-path: inset(0, 0, 0, 0);
position: relative;
display: flex;
align-items: center;
}

.scrolling-text {
white-space: pre;
color: rgb(255, 94, 94);
font-size: 24px;
font-family: 'Doto';
position: absolute;
transform: translateZ(0);
backface-visibility: hidden;
will-change: transform;
position: absolute;
}

.scrolling-text,
.message {
text-shadow:
0 0 5px #f00,
0 0 10px #f00,
0 0 20px #f00,
0 0 40px #f00;
will-change: transform;
animation-name: scroll-left;
animation-timing-function: linear;
animation-iteration-count: infinite;
}

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

@import url('https://fonts.googleapis.com/css2?family=Doto:[email protected]&display=swap');






Я добавил работоспособный фрагмент, как было предложено, теперь JavaScript немного отличается, поскольку я добавил заданное время ожидания 200 мс, но по-прежнему часто сталкиваюсь с теми же проблемами, что и раньше.

Подробнее здесь: https://stackoverflow.com/questions/792 ... ocking-the
Реклама
Ответить Пред. темаСлед. тема

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

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

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

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

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • CSS Animation-Iteration-Count портит режим Animation-fill-mode [закрыто]
    Anonymous » » в форуме CSS
    0 Ответы
    73 Просмотры
    Последнее сообщение Anonymous
  • Safari не учитывает CSS-transform-origin, «transform-box: fill-box» не помогает
    Anonymous » » в форуме CSS
    0 Ответы
    53 Просмотры
    Последнее сообщение Anonymous
  • Swiftui: MatchEdgeMetryEffect и Animation Animation Clipshape
    Anonymous » » в форуме IOS
    0 Ответы
    7 Просмотры
    Последнее сообщение Anonymous
  • Не удалось найти Transform-api.jar (com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api)
    Anonymous » » в форуме Android
    0 Ответы
    34 Просмотры
    Последнее сообщение Anonymous
  • Отслеживание зональных целей не возобновляется после приостановки приложения и его повторного открытия на iOS
    Anonymous » » в форуме IOS
    0 Ответы
    15 Просмотры
    Последнее сообщение Anonymous

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