View Transitions وNext.js: حركات الصفحات بدون مكتبة
View Transitions وNext.js: حركات الصفحات بدون مكتبة
View Transitions API يأخذ تلك الحيلة منك ويعطيها للمتصفح. بدلاً من الاحتفاظ بشجرتي DOM حيّتين وقياسهما، يلتقط المتصفح لقطة للحالة القديمة، يتيح تحديث DOM، يلتقط لقطة للحالة الجديدة، ثم يحرّك بين الصورتين — على المحرّك المركّب.
javascript
function navigate(update) {if (!document.startViewTransition) {update(); // لا دعم: فقط التحديث، بدون حركةreturn;}document.startViewTransition(() => update());}
css
::view-transition /* طبقة التراكب التي تغطي الصفحة بأكملها */::view-transition-group(name) /* تحريك الحجم والموضع */::view-transition-image-pair(name)::view-transition-old(name) /* لقطة "ما قبل" */::view-transition-new(name) /* لقطة "ما بعد" */
ما يفاجئ الجميع: اللقطة صورة فوتوغرافية وليست عنصراً
::view-transition-old ليست عنصرك القديم مُصغَّراً. إنها صورة ثابتة له. يتجمد <video> على إطار واحد. يتوقف مؤشر التحميل عن الدوران. عند 200ms لا يهم ذلك. عند 1000ms يصبح واضحاً.
التسمية: العقد بأكمله
css
.card-image {view-transition-name: hero;}::view-transition-group(hero) {animation-duration: 400ms;animation-timing-function: ease-in-out;}
القاعدة الصارمة: يجب أن يكون view-transition-name فريداً في المستند في أي وقت.
React 19.2 وNext.js 16: مكوّن واحد
tsx
import { ViewTransition } from "react";import Image from "next/image";import Link from "next/link";export function ProjectCard({ project }) {return (<Link href={"/projects/" + project.slug}><ViewTransition name={"project-" + project.slug}><Image src={project.cover} alt={project.title} /></ViewTransition></Link>);}
يجب أن يسافر share وdefault="none" معاً. مع default="none" وبدون خاصية share، يتوقف الزوج المُسمّى بهدوء عن التشكّل.
الاتجاه: أخبر المستخدم إلى أي جهة ذهب
tsx
<Link href="/projects/runvalis" transitionTypes={["nav-forward"]}>Runvalis</Link><ViewTransitionenter={{ "nav-forward": "slide-in", "nav-back": "slide-out", default: "none" }}exit={{ "nav-forward": "slide-out", "nav-back": "slide-in", default: "none" }}default="none"><main>{children}</main></ViewTransition>
النسخة بدون أي إطار عمل
css
@view-transition {navigation: auto;}
المزالق وأفضل الممارسات
- تعامل دائماً مع التحسين التدريجي.
- تصحيح الأخطاء بالحركة البطيئة.
- احترم
prefers-reduced-motion. - طبقة التراكب تستهلك النقرات بشكل افتراضي.
- اللقطات تستهلك الذاكرة.
- ثبّت الترويسة.
- انتقال العرض غير مرئي لتقنيات المساعدة.
خلاصة
View Transitions هي نفس الحجة المطبّقة على التنقل: بدلاً من تشغيل FLIP يدوياً، تُعلن ما يربط حالتين وتترك المتصفح يرسم الاتصال من صورتين.