[React Native] Guide - Phần 2 - Animations Part 1
Bài đăng này đã không được cập nhật trong 7 năm
Ở phần trước chúng ta đã tìm hiểu về cách điều khiển các sự kiện chạm trên màn hình. Trong phần này chúng ta sẽ tìm hiểu về một thành phần được ứng dụng khá nhiều trong hầu hết các ứng dụng đó là Animations
Part 1
Animations
Animations là một thành phần rất quan trọng để tạo nên sự tuyệt vời trong trải nghiệm người dùng. Ví như các vật thể cố định phải vượt qua quán tính đứng yên để bắt đầu di chuyển. Các đối tượng chuyển động có đà và hiếm khi dừng ngay lập tức. Animations cho phép bạn chuyển tải các chuyển động tương tự các vật thể trong giao diện của ứng dụng.
React Native cung cấp hai hệ thống animation: Animation để kiểm soát chi tiết và tương tác với các giá trị cụ thể và LayoutAnimation để di chuyển giao diện tổng thể.
Animated API
Animated API được thiết kế để làm cho nó rất dễ dàng để thể hiện một loạt các hình animation và interaction patterns bằng một cách rất hiệu quả. Animated tập trung vào các mối quan hệ khai báo inputs và outputs, với các phép biến đổi có thể cài đặt ở giữa và các quá trình start/stop để kiểm soát việc thực hiện animation dựa trên thời gian chạy.
Animated
đưa ra dành cho 4 thành phần gồm có View
, Text
, Image
và ScrollView
, nhưng bạn hoàn toàn có thể tạo ra những animation của riêng bạn để sử dụng.
Ví dụ dưới đây, một container view sẽ được hiển thị kiểu fade hi nó được xuất hiện lên trên màn hình:
// FadeInView.js
import React, { Component } from 'react';
import {
Animated,
} from 'react-native';
class FadeInView extends Component {
constructor(props) {
super(props);
this.state = {
fadeAnim: new Animated.Value(0), // Initial value for opacity: 0
};
}
componentDidMount() {
Animated.timing( // Animate over time
this.state.fadeAnim, // The animated value to drive
{
toValue: 1, // Animate to opacity: 1, or fully opaque
}
).start(); // Starts the animation
}
render() {
return (
<Animated.View // Special animatable View
style={{
...this.props.style,
opacity: this.state.fadeAnim, // Bind opacity to animated value
}}
>
{this.props.children}
</Animated.View>
);
}
}
module.exports = FadeInView;
Bạn có thể sử dụng FadeInView
tại nơi bạn đặt một View
trong các thành phần giao diện, tương tự như dưới đây:
render() {
return (
<FadeInView style={{width: 250, height: 50, backgroundColor: 'powderblue'}}>
<Text style={{fontSize: 28, textAlign: 'center', margin: 10}}>Fading in</Text>
</FadeInView>
)
}
Bây giờ chúng ta sẽ tách nhỏ từng phần ra để phân tích có những gì ở đây. Trong hàm tạo của FadeInView
, khởi tạo một Animated.Value
được gọi trong fadeAnim
như là một phần của state
. Thuộc tính độ trong suốt của View
được liên kết với giá trị của animated này. Bắt đầu khởi chạy, giá trị số này được định nghĩa chính xác và được sử dụng để cài đặt độ trong suốt.
Khi thành phần được khởi chạy, độ trong suốt được cài đặt bằng 0. Sau đó, một animation đơn giản sẽ được khởi chạy trong fadeAnim
. Trong khi đó, nó sẽ chạy tất cả những thành phần có liên quan (trong trường hợp này thì chỉ có độ trong suốt của View) trên mỗi frame như là giá trị của animation và kết thúc sẽ là giá trị 1.
Cách cài đặt này là một cách làm đơn giản và nhanh hơn so với cách gọi setState
và thực hiện render lại. Bởi vì toàn bộ config đã được định nghĩa, chúng ta sẽ có thể thực hiện tối ưu hoá và chạy animation trên một thread có độ ưu tiên cao.
Cấu hình animations
Animation có nhiều hình thức để cấu hình. Tùy chỉnh và các chức năng nới lỏng được xác định trước, delays, durations, decay factors, spring constants, và nhiều thứ khác có thể được tinh chỉnh tùy thuộc vào loại animation.
Animated cung cấp một số loại hình animation, một trong những loại animation thường được sử dụng nhất là Animated.timing()
. Nó hỗ trợ cài đặt các giá trị một cách đơn giản hoặc bạn cũng có thể cấu hình cho riêng mình theo cách của bạn.
Mặc định, timing
sẽ sử dùng đường cong easeInOut để thực hiện chuyển động từng bước một từ thấp nhất đến tốc độ cao nhất cho tới khi dừng lại. Bạn có thể định nghĩa cụ thể các hành động khác một cách dễ dàng bằng cách implement tham số easing
. Tùy chỉnh lại duration
hoặc delay
trước khi animation được start, đó là những tham số đã được hỗ trợ.
Ví dụ, nếu như bạn muốn chạy một animation trong khoảng thời gian 2 giây cho một đối tượng nhỏ trước khi nó di chuyển đến vị trí cuối cùng, bạn có thể cài đặt như đoạn code dưới đây:
Animated.timing(
this.state.xPosition,
{
toValue: 100,
easing: Easing.back,
duration: 2000,
}
).start();
Hãy tìm kiếm thêm các cài đặt ở đây Configuring animation của Animated API
để có thể học thêm về rất nhiều các tham số khác để cấu hình cho một animation.
Tự tạo các animation
Animation có thể được biên dịch và chạy trong hàng đợi hoặc chạy song song với nhau. Hàng đợi animation có thể chạy các animation tiếp theo sau khi animation trước vừa kết thúc. Hoặc cũng có thể cài đặt để animation sau chạy với một khoảng thời gian chờ đợi sau khi animation trước kết thúc. Animated API
cung cấp các phương thức như sequence()
và delay()
, mỗi một animation sẽ được nhận như một mảng và được thực hiện một cách tự động bằng cách gọi đến start()/stop()
như là một điều bắt buộc.
Ví dụ:
Animated.sequence([ // decay, then spring to start and twirl
Animated.decay(position, { // coast to a stop
velocity: {x: gestureState.vx, y: gestureState.vy}, // velocity from gesture release
deceleration: 0.997,
}),
Animated.parallel([ // after decay, in parallel:
Animated.spring(position, {
toValue: {x: 0, y: 0} // return to start
}),
Animated.timing(twirl, { // and twirl
toValue: 360,
}),
]),
]).start(); // start the sequence group
Nếu như một animation bị dừng đột ngột, thì tất cả các animation phía sau của nó cũng sẽ bị dừng lại. Animated.parallel
có một tùy chọn là stopTogether
và có thể cài đặt giá trị thành false
để tắt bỏ tính năng này.
Bạn có thể thể tìm được đầy đủ các phương thức kết hợp trong Composing animations
Kết hợp các giá trị của animation
Bạn có thể kết hợp các giá trị của animation bằng cách thêm vào, nhân bản, phân chia, để tạo ra các giá trị mới của animation
Có một vài trường hợp khi một animation cần phụ thuộc vào giá trị của một animation khác để tính toán. Ví dụ như tham số phụ thuộc vào độ co giãn thì chúng ta có thể cài đặt như dưới đây:
const a = Animated.Value(1);
const b = Animated.divide(1, a);
Animated.spring(a, {
toValue: 2,
}).start();
(Kết thúc phần 1)
Nguồn Animations
All rights reserved