Tôi đã sử dụng cùng một mẫu hoạt ảnh trong các dự án của mình được một thời gian để tạo hiệu ứng cho các phần tử trên màn hình. Ở dạng đơn giản nhất, bạn sẽ có một phần tử được tạo kiểu với độ mờ bằng 0, sau đó thay đổi kiểu để có độ mờ bằng một với chuyển tiếp CSS trong một giây.
Chúng tôi có thể xây dựng dựa trên điều đó bằng cách thêm các thuộc tính khác chuyển tiếp, thay đổi thời lượng, thêm độ trễ hoặc cài đặt mức giảm tùy chỉnh.
<AnimateIn/> là một thành phần React có thể tái sử dụng mà tôi đã tạo để sử dụng bất cứ khi nào tôi muốn nhanh chóng thêm một số hiệu ứng hoạt hình vào dự án của mình. Là một thành phần tiện ích đơn giản, nó kết hợp CSS Animation với các lớp Tailwind để tạo ra các hình ảnh động mượt mà, bắt mắt mà không tốn nhiều công sức.
Chúng ta hãy xem nó được sử dụng như thế nào. Sau khi nhập thành phần, hãy xác định các trạng thái from
và to
bằng các lớp Tailwind. Bao bọc phần tử mục tiêu trong <AnimateIn/> để xem hoạt ảnh trở nên sống động.
import AnimateIn from '../animation/AnimateIn'; <AnimateIn from="opacity-0 scale-90" to="opacity-100 scale-100" duration={500} > <YourComponent /> </AnimateIn>
Đây là một ví dụ phức tạp hơn một chút, sử dụng nhiều thuộc tính hơn để tạo hiệu ứng động trong dòng tiêu đề và phụ đề.
import AnimateIn from '../animation/AnimateIn'; <header> <AnimateIn as="h1" from="opacity-0 translate-y-32" to="opacity-100 translate-y-0" delay={500} duration={300} className="text-4xl" style={{transitionTimingFunction:"cubic-bezier(0.25, 0.4, 0.55, 1.4)"}} > My Big Headline </AnimateIn> <AnimateIn as="h2" from="opacity-0 scale-0" to="opacity-100 scale-100" delay={800} duration={500} className="text-lg" > This is a subtitle below the headline </AnimateIn> </header>
Trong ví dụ về dòng tiêu đề, <AnimateIn/> được sử dụng để tạo hiệu ứng trượt kết hợp với hiệu ứng mờ dần. Đây là cách mỗi thuộc tính đóng góp vào hoạt ảnh:
as
property: Bằng cách đặt as="h1"
, chúng ta yêu cầu AnimateIn hiển thị hoạt ảnh dưới dạng phần tử <h1>
.
from
và to
: Thuộc tính from
bắt đầu dòng tiêu đề ngoài màn hình ( translate-y-32
, di chuyển nó xuống 32 đơn vị) và ẩn ( opacity-0
). Sau đó, to
tính to sẽ đưa dòng tiêu đề về vị trí cuối cùng của nó (quay lại translate-y-0
) và làm cho nó hiển thị đầy đủ ( opacity-100
).
duration
: Hoạt ảnh được đặt để bắt đầu ngay lập tức mà không có độ trễ và chạy nhanh trong 300 mili giây.
className
: className="text-4xl"
áp dụng lớp tiện ích của Tailwind để đặt kích thước phông chữ, làm cho dòng tiêu đề nổi bật.
style
: transitionTimingFunction
tùy chỉnh ( cubic-bezier(0.25, 0.4, 0.55, 1.4)
) thêm sự dễ dàng độc đáo cho hoạt ảnh, tạo cho nó hiệu ứng giống như bật lên.
Phụ đề sử dụng một loạt hoạt ảnh khác để bổ sung cho dòng tiêu đề, tạo ra luồng hình ảnh gắn kết.
as
property: Ở đây, as="h2"
hiển thị thành phần dưới dạng phần tử <h2>
, phù hợp với phụ đề.
from
và to
: Phụ đề bắt đầu được thu nhỏ xuống 0 ( scale-0
) và ẩn ( opacity-0
), sau đó tăng tỷ lệ lên kích thước tự nhiên ( scale-100
) và hiển thị hoàn toàn ( opacity-100
). Hiệu ứng chia tỷ lệ này, kết hợp với hiệu ứng làm mờ dần, sẽ tăng thêm chiều sâu cho hoạt ảnh.
delay
và duration
: Phụ đề cũng bắt đầu sau độ trễ 800 mili giây để bắt đầu sau khi dòng tiêu đề có hoạt ảnh hoàn toàn. Cách tiếp cận so le này đảm bảo rằng mỗi yếu tố đều có được thời điểm tập trung.
className
: className="text-lg"
đặt kích thước phông chữ của phụ đề, làm cho nó nhỏ hơn dòng tiêu đề nhưng vẫn có ý nghĩa.
Để hiểu rõ hơn điều gì đang xảy ra, hãy xem mã nguồn của <AnimateIn/> trên Github :
<AnimateIn/> sử dụng hook useState
để khởi tạo trạng thái hoạt ảnh với thuộc tính from
, thuộc tính này phải là một hoặc nhiều lớp tiện ích Tailwind, thiết lập giai đoạn cho điểm bắt đầu của hoạt ảnh trước khi bất kỳ hoạt ảnh nào diễn ra.
hook useEffect
đầu tiên trong thành phần này nhằm tôn trọng sở thích của người dùng để giảm chuyển động. Bằng cách lắng nghe truy vấn phương tiện (prefers-reduced-motion: reduce)
, hành vi hoạt ảnh dựa trên cài đặt hệ thống của người dùng. Nếu ưu tiên chuyển động giảm, hoạt ảnh sẽ bị bỏ qua hoàn toàn, trực tiếp đặt trạng thái hoạt ảnh thành to
tính to, cho phép trải nghiệm có thể truy cập được.
hook useEffect
thứ hai là nơi chứa logic hoạt ảnh. Nếu người dùng chưa chỉ ra tùy chọn giảm chuyển động, thành phần sẽ đặt bộ hẹn giờ thay đổi trạng thái hoạt ảnh from
giá trị ban đầu đến giá trị cuối cùng to
giá trị sau độ trễ được chỉ định. Quá trình chuyển đổi này tạo ra hiệu ứng hình ảnh của hoạt ảnh.
Chức năng dọn dẹp của hook này (câu lệnh return) sẽ xóa bộ đếm thời gian, ngăn ngừa rò rỉ bộ nhớ tiềm ẩn, chẳng hạn như nếu thành phần ngắt kết nối trước khi hoạt ảnh hoàn tất.
Lệnh gọi hàm React.createElement
là cơ chế kết xuất của thành phần. Nó tự động tạo một phần tử HTML dựa trên as
prop, cho phép sử dụng thành phần này trên các phần tử HTML khác nhau. className
được xây dựng bằng cách sử dụng hàm cn
phổ biến bởi shadcn , kết hợp các lớp tiện ích của Tailwind, className
tùy chỉnh được truyền dưới dạng chỗ dựa và trạng thái hoạt ảnh hiện tại. Việc gán lớp động này là thứ áp dụng các kiểu và chuyển tiếp mong muốn cho phần tử.
Ngoài ra, có một thuộc tính style
có thể được chuyển vào để đặt trực tiếp các thuộc tính kiểu dáng trên vùng chứa hoạt ảnh. transitionDuration
được đặt dựa trên thuộc duration
, nhưng nó sẽ chuyển sang 0ms
một cách thông minh nếu người dùng muốn giảm chuyển động, vô hiệu hóa hoạt ảnh một cách hiệu quả trong khi vẫn duy trì chức năng của thành phần.
Nếu bạn muốn sử dụng <AnimateIn/> trong dự án của riêng mình và nó đã sử dụng shadcn thì bạn đã có mọi thứ mình cần, chỉ cần tải xuống AnimateIn.tsx và thêm nó vào các thành phần của bạn.
Nếu không, bạn sẽ muốn cài đặt Tailwind cũng như mxcn
tiện ích hữu ích để hợp nhất các lớp tailwind.
Giống như shadcn, <AnimateIn/> được coi là một thành phần có thể tái sử dụng mà bạn có thể sao chép và dán vào ứng dụng của mình cũng như tùy chỉnh theo nhu cầu của mình. Mã này là của bạn.
Ngoài ra, tôi đã tập hợp một trang demo thú vị để thử tạo các hoạt ảnh khác nhau với <AnimateIn/> tại animate-in.vercel.app .
Cũng được xuất bản ở đây