Однажды меня спросили, как добиться следующих эффектов анимации:
Несколько карт элементов располагаются сверху вниз. При добавлении или удалении карты остальные карты будутtransition
Анимированные формы перемещаются на место, а не мерцают неподвижно.
я случайно увиделVue
встроенные компоненты вtransition
реализации, понимая, что можно использоватьtransition
Часть принципа компонента для достижения этого эффекта, но поскольку я не исследовал, почему это так, он остается только на поверхности, я знаю это, но не знаю почему, поэтому, хотя я знаю, как достичь этот эффект, трудно объяснить, почему это так, язык сложнее организовать
Потом наткнулся на статьюИзменения, внесенные технологией FLIP в веб-верстку, я вдруг понял, что эта штука называетсяFLIP
FLIP
FLIPдаFirst
,Last
,Invert
а такжеPlay
аббревиатура инициалов из четырех слов
First
, относится к записи положения и размера текущего элемента до того, как что-либо произойдет (до перехода), то есть информацию о положении и размере элемента в момент до начала анимации, вы можете использоватьgetBoundingClientRect()
этоAPI
иметь дело (в большинстве случаев на самом делеoffsetLeft
а такжеoffsetTop
это тоже нормально)
Last
: выполнить фрагмент кода, чтобы элемент изменился соответствующим образом, и записать положение и размер элемента в конечном состоянии анимации, то есть информацию о положении и размере элемента в момент после окончания анимации.
Invert
: вычисляет первую позицию элемента (First
) и последняя позиция (Last
) (и, при необходимости, изменение размера между двумя состояниями), а затем использовать эти числа для выполнения определенных вычислений для перемещения элемента (черезtransform
изменить положение и размер элемента), тем самым создавая иллюзию того, что он находится в первой позиции (исходной позиции)
То есть, как только вы подойдете, пусть элемент будет в конечном состоянии анимации, а затем используйтеtransform
инвертирует элемент обратно в начальное состояние анимации (информация об этом состоянии находится вFirst
получить шаги)
Play
: инвертировать элемент (представить, что он находится вfirst
положение), можно положитьtransform
Установить какnone
, потому что потерялtransform
Ограничение , поэтому элемент обязательно переместится в положение, где он должен быть (то есть состояние в конце анимации), то естьlast
позиция, если вы добавите к элементуtransition
свойства, то этот процесс естественно происходит в виде анимации
Насколько я понимаю, это количественная оценка начального и конечного состояний элементов анимации, выраженная в формуле. Большинство непрерывных анимаций можно выполнить, применив эту формулу для повышения эффективности разработки анимации. Для получения более подробной информации, пожалуйста обратитесь к своим.Изменения, внесенные технологией FLIP в веб-верстку
Реализовать анимацию добавления и удаления карт
понялFLIP
После этой концепции на самом деле очень просто реализовать анимационный эффект, упомянутый в начале.
First
Запишите информацию о положении и размере каждой карты до начала анимации.Поскольку размер карты не изменится в процессе анимации, вы можете пропустить этот шаг и записать только информацию о положении карты.
Кроме того, если все карты имеют одинаковый размер, то нет необходимости записывать информацию о положении всех карт, потому что при вставке или удалении карт будут затронуты только те карты, координаты положения которых находятся за измененными координатами карты. предыдущий не изменится
// First
activeList.forEach((itemEle, index) => {
rectInfo = itemEle.getBoundingClientRect()
transArr[index + stepIndex][0] = rectInfo.left
transArr[index + stepIndex][1] = rectInfo.top
})
Last
Конечным состоянием анимации на самом деле является состояние оставшихся карточек после добавления или удаления карточек:
if (updateStatus === 0) {
// 增加卡片
newListData = this.state.listData.slice(0, activeIndex).concat({
index: cardIndex++
}, this.state.listData.slice(activeIndex))
} else {
// 删除卡片
newListData = this.state.listData.filter((value, index) => index !== activeIndex)
}
Потому что я не добавил карту в это времяtransition
атрибут, поэтому процесс обновления количества карточек на самом деле является мгновенной вещью.Человеческий глаз не может обнаружить никаких изменений, но элементы на странице действительно изменились, и тогда информация о положении карточек измеряется в это время, что являетсяLast
Необходимые данные
Invert
Получив информацию о расположении затронутых карт в начале анимации, вы можете пройтиtransform
Атрибут меняет положение элемента
// Last + Invert
const stepIndex = updateStatus === 0 ? 1 : 0
activeList.forEach((itemEle, index) => {
rectInfo = itemEle.getBoundingClientRect()
transArr[index + stepIndex][0] = transArr[index + stepIndex][0] - rectInfo.left
transArr[index + stepIndex][1] = transArr[index + stepIndex][1] - rectInfo.top
}
Play
Этап подготовки готов, можно переходить к завершающему шагуPlay
Вставай, ключ к этому шагу — добавить элементы вtransition
атрибут и удалитьtransform
Изменение позиции привело к элементу:
// Play
// 重置
transArr = getArrByLen(this.state.listData.length)
setTimeout(() => {
this.setState({
animateStatus: 3
})
}, 0)
потому что браузер будетDOM
Изменения объединяются и оптимизируются, поэтому, чтобы визуально представить желаемый эффект анимации, эту оптимизацию здесь необходимо прервать.setTimeout
это очень распространенный способ
На данный момент анимационный эффект в начале статьи выполнен.Live Demo, если вам интересно, вы можете попробовать сами, а код также можно загрузить наGithub
Реализовать увеличение/восстановление анимации изображения
Когда вы нажимаете на изображение предварительного просмотра в интерфейсе чата приложения WeChat, процесс изображения из диалогового окна в полноэкранный предварительный просмотр использует анимацию перехода, чтобы показать весь процесс изображения от маленького изображения к большому изображению и от большого изображения к маленькому Процесс масштабирования Аналогично следующему:
Это тоже непрерывная анимация, конечно тоже можно пройтиFLIP
сделать это легко
First
Это включает в себя изменение положения и размера изображения, изображение изFirst
Исходное положение эскиза и размер эскиза становятсяLast
Положение большого изображения и размер большого изображения в состоянии, поэтому необходимо получить эти два данных одновременно, по сути его можно вызвать одним вызовомgetBoundingClientRect
Заканчивать
Last
Получите информацию о размере и положении изображения уже в состоянии предварительного просмотра, также используйтеgetBoundingClientRect
Заканчивать
Кроме того, для более эффективного использованияtransform
Анимация, здесь я трансформирую изменение размера картинки в двух состояниях вscale
изменение стоимости,First
а такжеLast
Соотношение ширины или высоты в состоянии этоscale
должно принимать значение (без изменения соотношения сторон изображения)
scaleValue = rectInfo.width / lastRectInfo.width
Invert
использоватьtransform
положение и размер (т.е. изменениеscale
значение) инверсия
Здесь следует отметить, что, посколькуtransform
анимация по умолчаниюtransform-origin
является центром элемента, т.е.50% 50%
, но рассчитанныйleft
а такжеtop
Но это относительно немасштабированного изображения, поэтому, когдаscale
Если значение не уникально, анимация изображенияFirst
состояние будет отклоняться, и необходимоtransform
установить как0 0
устранить это предубеждение
Play
добавить к изображениюtransition
атрибут и удалить связанныйtransform
свойство для запуска анимации
Как видите, применяетсяFLIP
После этого анимация, которая изначально казалась сложной, была легко смоделирована и реализована.
Что касается стадии восстановления увеличенной картинки до маленькой, то ее можно рассматривать как еще однуFLIP
Анимация, продолжайте применять, но эта анимация обратна предыдущей анимации увеличения, получена необходимая информация о размере и положении, вы можете сохранить вызовgetBoundingClientRect
процесс
сделал то же самоеLive Demo, если вам интересно, вы можете попробовать сами, а код также можно загрузить наGithub
Зачем использовать ФЛИП
Некоторые люди могут быть более сбиты с толку, если вы хотите получить анимацию напрямую.transform
Это нормально, зачем это делать?FLIP
концепция вышла?
У меня тоже сначала были такие сомнения, но когда я действительно реализовал анимацию, такую как анимация карты в начале, на этот вопрос сразу же был дан ответ.
Для некоторых анимаций вы явно знаете их начальное состояние (First
) и конечное состояние (Last
), например, вы хотите сделать элемент изleft:10px;
перейти кleft:100px;
, то вы сразуtransform
Все в порядке, это совсем не обязательноFLIP
, но использовать его лишнее;
Но кроме того, есть некоторые начальные состояния, которые нельзя указать (First
) или конечное состояние (Last
) анимация, такая как анимация карты в начале, если вы не ограничите размер каждой карты и размер всей страницы, вы не сможете понять, где должны быть другие карты после того, как вы произвольно вставите или удалите карту.
Например, под вашим браузером ширина и высота каждой карточки 100, а ширина страницы браузера 1380, поэтому в каждом столбце можно расположить 13 карточек, но это только в вашем браузере, на странице браузера пользователя Ширина может быть 1280 или 1980, количество карточек в каждой колонке может быть 12 или 19 и так далее, причем можно даже произвольноresize
Размер страницы, то в это время, как вы определяете все карты в каждый моментlast
информация о состоянии?
Вы можете сказать, конечно, я не знаю, но я могу использовать браузерAPI
Проведите измерения.
извините, это именно то, чтоFLIP
Одна из вещей, которую нужно сделать, вы все еще используете эту вещь неосознанно, но по сравнению с той, которая была обобщена и оптимизирована предшественниками.FLIP
Другими словами, ваше общее использование может быть более фрагментированным и нестандартным.
Как говорится в названии,让动画变得更简单
, можно и не использовать, но если умеешь пользоваться, то анимация - это формула для тебя, и не толькоeasy
.
резюме
Многие фронтендеры как будто не особо заботятся об анимации, думая, что это всего лишь вспомогательная способность, главное бизнес-логика, а все остальное остается позади.Даже если есть время, все зависит от настроения перед решить, делать это или нет.
Мое мнение таково, что бизнес-логике, конечно, следует уделять первостепенное внимание, но также не стоит недооценивать остальные мелочи, такие как анимация, хорошая анимация опыта может полностью привлечь пользователей, чтобы они оставались дольше, в целом улучшить эффект конверсии бизнеса со стороны. В некоторых конкретных сценариях его роль может даже идти в ногу с бизнес-целями.