アニメーションをよりシンプルにするFLIPテクノロジー
6919 ワード
あるとき、次のアニメーション効果をどのように実現するかを尋ねられました.
いくつかの要素カードが上から下に並べられ、あるカードを追加または削除すると、残りのカードは
当時私はちょうど
それから私は何気なく1篇の文章FLIP技術がWebレイアウトにもたらした変化を見て、すぐにはっと悟って、もとはこれはFLIPと呼ばれています
FLIP
FLIPは、
すなわち、要素を直接アニメーションの終了状態にし、
私の理解によって、アニメーションの要素に対して状態の1つの量子化を始めて、1つの公式に量子化して、ほとんどの連続するアニメーションはすべてこの公式を套用することによって完成することができて、アニメーションの開発の効率を高めて、更に詳しいのは自分でFLIP技術を参照してWebのレイアウトに持ってくる変化
カードカードカードの削除を実現
First
アニメーション開始前の各カードの位置とサイズ情報を記録します.ここでは、カードのサイズはアニメーション中に実際には変化しないので、このステップを省略して、カードの位置情報のみを記録することができます.
また、全てのカードのサイズが同一であれば、全てのカードの位置情報を記録する必要はない.カード挿入や削除にかかわらず、位置座標が変化するカード座標の後ろに位置するカードのみが影響を受け、前のカードは変化しない
Last
アニメーションの終了状態は、カードを追加または削除した後、残りのカードの状態です.
この時点でカードに
Invert
アニメーションの開始段階で影響を受けるカードの位置情報を取得すると、
Play
準備フェーズが完了すると、最後のステップ
ブラウザはページの
ここまでで、冒頭のアニメ効果が完成したので、Live Demoを作りました.興味があれば自分で試してみてください.また、コードもGithubにアップロードできます.
画像の拡大/復元を実現
微信appのチャットインタフェースでプレビュー画像をクリックすると、画像がダイアログボックスから全画面にプレビューされるこの過程は、移行したアニメーションを使って、画像が小さい図から大きい図へと回復し、大きい図から小さい図へと回復する全過程を示しています.スケーリング過程は以下のように似ています.
これも連続動画ですが、もちろん
First
ここでは、画像の位置とサイズの変化に関し、画像は
Last
画像がプレビューされた状態のサイズと位置情報を取得し、
また、
Invert
ここで注意すべき点は、
Play
画像に
拡大した画像が小図に戻る段階については、別の
同じLive Demoを作ったので、興味があれば自分で試してみてください.また、コードもGithubにアップロードできます.
小結
多くの前端の学友はアニメーションをあまり気にかけないようで、これはただ1つの補助能力だと思って、業務のロジックは最も重要で、その他はすべて後ろの駅に頼って、たとえ時間があっても気持ちを見てからやるかどうかを決めます
私の見方は、ビジネスロジックはもちろんトップに置かなければならないが、他の枝葉末節を軽視してはいけない.例えば、アニメーション、体験の良い動効はユーザーのより多くの滞在を引き付けることができ、共通の方法で側面からビジネスの転化効果を向上させ、特定のシーンでは、その役割は、ビジネスの目標と並ぶこともできます.
いくつかの要素カードが上から下に並べられ、あるカードを追加または削除すると、残りのカードは
transition
アニメーションの形で適切な位置に移動し、硬く現れるのではなく、適切な位置に移動します.当時私はちょうど
Vue
の中の内蔵コンポーネントtransition
の実現を見たことがあり、transition
コンポーネントの一部の原理でこの効果を完全に達成できることに気づいたが、なぜそうなのか深く探究したことがなく、表面にとどまっているだけで、それを知っているがなぜか分からないので、私はこの効果をどのように実現するか知っているが、なぜそうなのか説明するのは難しい.言語組織が比較的困難であるそれから私は何気なく1篇の文章FLIP技術がWebレイアウトにもたらした変化を見て、すぐにはっと悟って、もとはこれはFLIPと呼ばれています
FLIP
FLIPは、
First
、Last
、Invert
、Play
の4つの単語の頭文字の略であるFirst
とは、何かが起こる前に(移行する前に)、現在の要素の位置とサイズ、すなわちアニメーションが始まる前の要素の位置とサイズ情報を記録することを意味し、getBoundingClientRect()
というAPI
を使用して処理することができる(ほとんどの場合、実際にはoffsetLeft
とoffsetTop
も可能である)Last
:エレメントが変化するようにコードを実行し、アニメーションの最後の状態におけるエレメントの位置と寸法、すなわちアニメーションが終了した後のエレメントの位置と寸法情報を記録するInvert
:要素の最初の位置(First
)と最後の位置(Last
)との間の位置変化(必要に応じて2つの状態間の寸法の大きさの変化も計算できる)を計算し、これらの数字を用いて一定の計算を行い、要素を移動させる(transform
によって要素の位置と寸法を変更する)、最初の位置(初期位置)にある錯覚を作成しますすなわち、要素を直接アニメーションの終了状態にし、
transform
属性を使用して要素をアニメーションの開始状態に戻す(この状態の情報はFirst
ステップで取得される)Play
:要素を反転(first
の位置を装う)、transform
をnone
に設定することができます.transform
の制約を失ったため、要素は必ずこの位置(つまりアニメーションの終了時の状態)に移動します.つまりlast
の位置です.要素にtransition
の属性を加えると、この過程は自然にアニメーションの形で起こります私の理解によって、アニメーションの要素に対して状態の1つの量子化を始めて、1つの公式に量子化して、ほとんどの連続するアニメーションはすべてこの公式を套用することによって完成することができて、アニメーションの開発の効率を高めて、更に詳しいのは自分でFLIP技術を参照してWebのレイアウトに持ってくる変化
カードカードカードの削除を実現
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にアップロードできます.
画像の拡大/復元を実現
微信appのチャットインタフェースでプレビュー画像をクリックすると、画像がダイアログボックスから全画面にプレビューされるこの過程は、移行したアニメーションを使って、画像が小さい図から大きい図へと回復し、大きい図から小さい図へと回復する全過程を示しています.スケーリング過程は以下のように似ています.
これも連続動画ですが、もちろん
FLIP
で簡単に実現できますFirst
ここでは、画像の位置とサイズの変化に関し、画像は
First
の小図原位置と小図サイズから、Last
の状態における大図位置と大図サイズとなっているので、この2つのデータを同時に取得する必要があるが、いずれも一度にgetBoundingClientRect
を呼び出すことで完了することができるLast
画像がプレビューされた状態のサイズと位置情報を取得し、
getBoundingClientRect
を使用して完了します.また、
transform
のアニメーションをよりよく利用するために、ここでは、ピクチャの2つの状態における寸法変化を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にアップロードできます.
小結
多くの前端の学友はアニメーションをあまり気にかけないようで、これはただ1つの補助能力だと思って、業務のロジックは最も重要で、その他はすべて後ろの駅に頼って、たとえ時間があっても気持ちを見てからやるかどうかを決めます
私の見方は、ビジネスロジックはもちろんトップに置かなければならないが、他の枝葉末節を軽視してはいけない.例えば、アニメーション、体験の良い動効はユーザーのより多くの滞在を引き付けることができ、共通の方法で側面からビジネスの転化効果を向上させ、特定のシーンでは、その役割は、ビジネスの目標と並ぶこともできます.