Композитное накопление API веб-анимации

Я пытаюсь понять, возможно ли накапливать анимацию с помощью анимации веб-API, но не могу этого понять.

//move element very fast to 100,100 with no duration
el.animate([{transform: 'translate(100px, 100px)'}], {duration: 0, fill: 'forwards'});

//add another movement after that with duration
el.animate([{transform: 'translateX(200px)'}], {duration: 0, fill: 'forwards', composite: 'accumulate'});

Все происходит правильно, поле перемещается на 100,100, после чего начинается анимация. Проблема в том, что в конце анимации прямоугольники перемещаются вверх, как будто они внезапно потеряли Y-преобразование. Можно ли сохранить преобразование Y в конце? Я думал fill: 'forwards' + composite : 'accumulate' так и сделаю...

Примечание: время от времени он ведет себя правильно, поэтому я не уверен, что происходит. Ожидаемое поведение

  • Переместить поле на 100 100
  • Затем примените относительное преобразование, что означает, что в конечном итоге блок будет равен 300 100.

const el = document.querySelector('.box');

el.animate([{transform: 'translate(100px, 100px)'}], {duration: 0, fill: 'forwards'});

el.animate([{transform: 'translateX(200px)'}], {duration: 2000, fill: 'forwards', composite: 'accumulate'});
.container{
  display: block;
  height: 100vh;
  overflow: hidden;
}
.box{
  position: absolute;
  width: 300px;
  height: 200px;
  background-color: brown;
 }
<div class = "container">
  <div class = "box">  
  </div>
</div>

JsFiddle

Я не думаю, что composite: 'accumulate' применяется глобально, я ожидаю, что стили будут сочетаться только в одном наборе ключевых кадров. Вы уверены, что вам нужны две совершенно разные анимации для одного и того же элемента?

DBS 14.08.2024 11:52

Кроме того, я не думаю, что это проблема, но вам не хватает закрывающей скобки в translate(100px, 100px

DBS 14.08.2024 11:58

Хороший улов, отредактированный, но ведет себя так же. Что вы подразумеваете под «накоплением», которое не применяется глобально? Какой тогда смысл накапливать?

Eric 14.08.2024 12:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
3
50
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я думаю, что для этого вам нужно будет удалить преобразование и установить функцию анимации со свойствами left и top.

Как я ясно понимаю из вашего поста и немного его протестировал, вы хотели, чтобы ваш текущий блок оставался в последней позиции, где заканчивается вторая анимация. Функция преобразования, я думаю, немного сложна, поскольку она каким-то образом сбрасывает положение оси Y и по какой-то причине подталкивает ваш блок к верху контейнера.

Я считаю, что лучше работать с обеими анимациями с вышеупомянутыми свойствами.

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

Я надеюсь, что это поможет вам в том, что вы ищете.

const el = document.querySelector('.box');
el.animate([{left: '100px', top:'0'}], {duration: 0, fill: 'both'});

el.animate([{left: '200px', top: '100px'}], {duration: 2000, fill: 'both', composite: 'accumulate'});
.container{
  display: block;
  height: 100vh;
  overflow: hidden;
}
.box{
  position: absolute;
  width: 300px;
  height: 100px;
  background-color: brown;
 }
<div class = "container">
  <div class = "box">  
  </div>
</div>

Да, он вроде как делает то, что я хочу, но на самом деле речь шла не о перемещении коробки, а о возможности «объединять» преобразования с помощью анимации. Это была скорее проверка концепции, чтобы проверить, действительно ли «накопление» объединяется или накапливает преобразования, но я думаю, что это не то, для чего оно было создано.

Eric 14.08.2024 12:19

Я считаю, что встроенная функция Transforms лучше подходит для использования с ключевыми кадрами. Проверьте этот пост: stackoverflow.com/questions/44110205/… он делает то, чего вы хотите достичь, с помощью ключевых кадров CSS-анимации.

Oris Sin 14.08.2024 12:25

Ну, я пытался проверить, стоит ли мне отойти от CSS-анимации и использовать новую «замещающую» анимацию веб-API, которая поддерживает ключевые кадры. Насколько я понимаю, мне нужно вычислить и обновить ключевые кадры, что в некотором роде контрпродуктивно по сравнению с вычислением и применением преобразования непосредственно в коде...

Eric 14.08.2024 12:29

да, я читал, что вы можете значительно сократить время загрузки с помощью анимации веб-API вместо того, чтобы делать это с помощью ключевых кадров CSS.

Oris Sin 14.08.2024 12:38
Ответ принят как подходящий

Насколько я помню, опция composite не такая уж и умная, она компилирует разные типы преобразований в одно, а больше похоже на конкатенацию строк. Это поведение может измениться в будущем в зависимости от разных поставщиков.

На данный момент вы можете использовать DOMMatrix для выполнения нужных операций перед анимацией элемента. Это дает вам некоторый контроль над тем, как вы хотите, чтобы «композит» вел себя.

В этом примере я использую библиотеку манипуляций с dom, но вы можете легко получить обещание из нативного Element.animate через finished prop. Остальное — получить текущую матрицу преобразования через getComputedStyle и использовать ее для накопления преобразований через DOMMatrix.prototype. В этом примере я использую DOMMAtrix.prototype.translateSelf.

Следует отметить, что при умеренном использовании getComputedStyle в своих сценариях вы обычно делают это посредством опроса/регулирования функции, которая делает позвоните туда. Другой вариант — установить свойство или символ для элемента, который отслеживает текущую DOMMatrix, чтобы вам не приходилось вызывать getComputedStyle.

(async () => {
 const el = document.querySelector('.box');
 await ch(el).animate([{transform: 'translate(100px, 100px)'}], {duration: 2000, fill: 'forwards'}).promiseAnimate();
 const currMatrix = new DOMMatrix(getComputedStyle(el).transform);
 ch.animate([{transform: currMatrix.translateSelf(200)}], {duration: 2000, fill: 'forwards'})
})()
.container{
  display: block;
  height: 100vh;
  overflow: hidden;
}
.box{
  position: absolute;
  width: 300px;
  height: 200px;
  background-color: brown;
 }
<script src = "https://cdn.jsdelivr.net/npm/[email protected]/dist/cahir.0.0.6.evergreen.umd.min.js"></script>
<script src = "https://cdn.jsdelivr.net/npm/[email protected]/collections/DOM/ch.js"></script>
<div class = "container">
  <div class = "box">  
  </div>
</div>

Спасибо, на самом деле я уже получал/устанавливал матрицу и какое-то время думал, что «аккумулировать» на самом деле делает это, а не просто объединяет строки... разочарован этой функцией.

Eric 14.08.2024 14:30

Другие вопросы по теме