Fluth|商品券付加3 Dインタラクション
25764 ワード
ギフト券
トス商品券を購入するページに面白いインタラクションがあります.
購入数を変更するたびに3 Dアニメーション効果が発生します.
ソース:https://blog.toss.im/article/ux-engineer-interview
📌 このページでは、重要なインタラクティブな部分を真似します.
1▼▼▼▼▼選択数ページ初期勾配変化アニメーション
2▼▼▼▼▼ボタン数を変更した場合、ボタンの大きさをアニメーション化
3▼▼▼数を変更した場合、カードを追加する動画
Flutter Rendering
まず、Flutterレンダリングについて説明します.
私たちが見た部分は2 Dのように見えますが、Flutterはもともと3 Dレンダリングされていました.
Googleの説明でも、性能が非常に悪いスマートフォンのほか、ほとんどのスマートフォンには3 Dグラフィックスを最適化する高速GPUが含まれていると述べています.つまり、3 Dグラフィックスのレンダリング速度が非常に速いため、Flutterも3 Dレンダリングを使用しています.
🔥 そのため、3 Dアニメーション効果、3 D画像モデリング、ゲーム制作をFluterで行うことができます.
カード読み込みインタラクション
初めてページに入ったとき、カードは水平で、ゆっくりと傾いていました.
これを実現するために、AnimationControllerとTransform.rotate部品で実現しました.
Transform.rotate
✅ Transform.rotateは回転を中心として、回転を使用してサブアセンブリを作成します.
✅ Transform.rotateの角度パラメータはnullではなく、角度値は時計回りの弧度単位の回転を提供します.
アニメーション効果を制御できるアニメーションコントローラが生成されます.
AnimationControllerが受信した値を使用して傾斜を調整します.
// 카드 애니메이션.
late AnimationController _cardRotateController = AnimationController(
vsync: this,
duration: const Duration(seconds: 1),
)..addListener(() => setState(() {}));
void initState() {
super.initState();
_cardRotateController.forward();
}
」」」」」」」」」」」このエラーは、TickerProviderを割り当てることができないためのエラーであり、TickerProviderを割り当てると簡単に解決できます.
class _GiftCardPageState extends State<GiftCardPage> with TickerProviderStateMixin {}
上で生成したアニメーションコントローラで回転値を指定します.これは、AnimationControllerの初期値が0.0で、アニメーションの順方向が1.0に変更された点です.
Transform.rotate(
angle: _cardRotateController.value * (-math.pi / 30),
child: _giftCard...
)
ボタンをクリックして操作
ボタンをクリックすると、ボタンのサイズが大きくなり、元のサイズに戻ります.
このアニメーション効果を与えるためにTransformscaleを用いて大きさの変化の効果を生じた.
Transform.scale
892 D平面に沿ってサブアセンブリのサイズを調整できるコンポーネントを作成します.
2989 scaleXパラメータはx軸に乗じたスカラーを提供し、scaleYパラメータはy軸に乗じたスカラーを提供します.どちらも省略できますが、この場合、軸のデフォルト値は1.0です.
scaleXとscaleYを指定することなく、scaleパラメータを使用してサブアイテムのサイズを統一できます.
少なくとも1つはnullではない必要があります.scaleが提供された後、他の2つはnullでなければなりません.同様に、提供されていない場合は、別のものを提供する必要があります.
[位置合わせ](Align)は、メッシュの原点を制御します.既定では、これはボックスの中心です.
増加ボタンとボトムボタンの大きさはそれぞれ変化するので、AnimationContollerも1つずつ生成します.
AnimationControllerの生成時には、低Boundと高Boundの値も指定されます.
📌 upper bound:
vsync: this
で得られた最大値.📌 LowerBound:
The argument type '_GiftCardPageState' can't be assigned to the parameter type 'TickerProvider'
で得られた最小値.// 증감 버튼 크기 애니메이션.
late AnimationController _decreaseButtonScaleController;
late AnimationController _increaseButtonScaleController;
// 바운스 애니메이션.
final Duration _bounceAnimationDuration = const Duration(milliseconds: 100);
// 버튼 크기 애니메이션 설정.
void _setButtonScaleAnimation() {
// 감소 버튼 애니메이션.
_decreaseButtonScaleController = AnimationController(
vsync: this,
duration: _bounceAnimationDuration,
lowerBound: 0.0,
upperBound: 0.6,
)..addListener(() => setState(() {}));
// 증가 버튼 애니메이션.
_increaseButtonScaleController = AnimationController(
vsync: this,
duration: _bounceAnimationDuration,
lowerBound: 0.0,
upperBound: 0.6,
)..addListener(() => setState(() {}));
}
void initState() {
super.initState();
...
_setButtonScaleAnimation();
}
商品券の数を増やしてボタンを減らすと、animationControllerへ進む
controller.value
手法を実現した.放送終了後、後方に進む
controller.value
が放送された.[アニメーションコントローラ](Animation Controller)は、前後に、毎回アニメーションコントローラを使用します.value値は、上記で指定した0.0および0.6になります.
CupertinoButton(
onPressed: () {
// 애니메이션 효과.
animationController.forward();
Future.delayed(_bounceAnimationDuration, () {
animationController.reverse();
});
// 값 변경.
...
// 카드 바운스 애니메이션.
...
},
child: Transform.scale(
scale: 1 + animationController.value,
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
shape: BoxShape.circle,
color: Colors.grey.withOpacity(0.2),
),
child: Icon(
iconData,
size: 36,
color: Colors.white,
),
),
),
)
カードインタラクションの追加
カードの数が変わるたびに、カードが一枚ずつ積み重なっていきます.
そして、積み重ねるごとにカード全体が弾かれるアニメーションもあります.
カードと3 Dアニメーションを追加するにはTransformコンポーネントを使用します.
Transform
サブアイテムを描画する前に、フォーマットのコピーを適用するコンポーネント.
このオブジェクトは、テクスチャレイアウトの前に回転を適用するRotatedBoxとは異なり、塗りつぶしの前に変形を適用します.
カードの追加
Stack部品で数量を変更するたびに、Stackサブアイテムも変更方法を使用します.
そして、最初のカードはいつも上に積まれているので、Stackの子供たちを逆順に並べます.
最初のカードはいつも上が見えます.
Stack(
children: List.generate(
_animationCardQuantity,
(index) {
return _giftCard(index: index),
);
},
).reversed.toList(),
)
▼しかし、このように積むと同じ位置に積まれるので、実際には同じように見えます.そのため、カードごとに位置が異なります.3 D効果を与えるために、カードの位置と回転の変化を与えます.
カードの位置をX軸とY軸に移動します.
2
return Transform(
transform: Matrix4.identity()
// 이동.
..setEntry(0, 3, -1.5 * _index)
..setEntry(1, 3, -2.0 * _index)
// 회전.
..rotateX(-0.075 * _index)
..rotateY(0.07 * _index),
child: _giftCard(index: index),
);
カード3 D弾き動画
カードが1枚増えるごとに、1枚落ちるごとに3 D効果が変化し、カード全体が跳ね返る効果があります.
イジェクトは2 Dではなく3 Dなので、ボタンをクリックしたアニメーションとは異なるはずです.
3 Dアニメーションを与えるために、回転機能で弾きます.
late AnimationController _cardBounceController;
// 카드 바운스 애니메이션.
_cardBounceController = AnimationController(
vsync: this,
duration: _bounceAnimationDuration,
lowerBound: 0.0,
upperBound: 10.0,
)..addListener(() => setState(() {}));
// 카드.
Transform(
alignment: Alignment.topLeft,
transform: Matrix4.identity()
// 회전.
..rotateX(_cardBounceController.value * (-math.pi / 400))
..rotateY(_cardBounceController.value * (math.pi / 400)),
child: Stack(
children: ...
).reversed.toList(),
),
アニメーション効果の進行と後退は、他のアニメーションと同じです.// 증감 버튼.
CupertinoButton(
onPressed: () {
// 버튼 크기 애니메이션 효과.
...
// 값 변경.
...
// 카드 바운스 애니메이션.
_cardBounceController.forward();
Future.delayed(_bounceAnimationDuration, () {
_cardBounceController.reverse();
});
},
child: 증감 버튼... ,
)
Github
https://github.com/CHOI-YOOBIN/toss_gift_card_interaction
Reference
この問題について(Fluth|商品券付加3 Dインタラクション), 我々は、より多くの情報をここで見つけました https://velog.io/@cyb9701/토스-상품권-3D-인터랙션テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol