تحكمات الكاميرا

Starter pack

لتحديد موضع وتحريك الكاميرا في مشهد ثلاثي الأبعاد، اكتشفنا بعض الطرق للقيام بذلك:

  • تحديد موقع الكاميرا ودوارنها يدويًا.
  • استخدام أنواع مختلفة من التحكمات، مثل OrbitControls.

لكن في بعض الأحيان، نحتاج إلى المزيد من التحكم في الكاميرا، ويتطلب ذلك الكثير من الكود والحسابات للحصول عليه بشكل صحيح. لحسن الحظ، هناك مكتبات يمكنها مساعدتنا في ذلك.

المكتبة التي سنستخدمها تسمى camera-controls. إنها مكتبة صغيرة تسمح لنا بتنفيذ مجموعة متنوعة من حركات ورسوم الكاميرا بسهولة كبيرة.

لحسن الحظ، Drei تحتوي على غلاف لهذه المكتبة، لذلك يمكننا استخدامها ببضع سطور من الكود.

مشروع البداية

لاكتشاف الميزات المختلفة لهذه المكتبة، سنقوم بإنشاء سلايدر ثلاثي الأبعاد جميل لعرض iPhone 15 Pro Max Black الجديد.

يرجى الاتصال بي عند إصدار iPhone 16 حتى أتمكن من تحديث هذا الدرس 🤭

يحتوي مشروع البداية على:

iPhone 15 Pro Max Black

في الوقت الحالي يمكننا فقط رؤية نموذج iPhone

لنبدأ بتجربة تحكمات الكاميرا.

التحكمات

لتمكين التحكم في الكاميرا، نحتاج إلى استبدال OrbitControls الموجود بالفعل في مشروع البداية بمكون CameraControls من Drei.

سنضيف أيضًا مرجعًا للتحكم حتى نتمكن من الوصول إليه لاحقًا واستخدام أساليبه.

Experience.jsx:

// ...
import { CameraControls } from "@react-three/drei";
import { useRef } from "react";

export const Experience = () => {
  const controls = useRef();
  return (
    <>
      <CameraControls ref={controls} />
      {/* ... */}
    </>
  );
};

بدلاً من استخدام مرجع، يمكنك الآن الوصول إلى مكون CameraControls مع الخطاف useThree من react-three-fiber. المزيد من المعلومات في التوثيق.

من خلال القيام بذلك، لن نلاحظ أي اختلاف كبير مع OrbitControls. لا يزال بإمكاننا تدوير و تحريك و تكبير وتصغير الكاميرا.

أيضًا تحتوي API على العديد من التحكمات المشتركة مثل distance, zoom, polarAngle, azimuthAngle, ...

أين يتألق مكون CameraControls هو عندما نريد تحريك الكاميرا.

لن نتناول جميع التحكمات المتاحة، لكن سنرى الأكثر شيوعًا منها. يمكنك العثور على القائمة الكاملة في توثيق التحكمات الكاميرا.

الحركة الدائرية للأمام والخلف (Dolly)

تسمح لنا خاصية الحركة الدائرية للأمام والخلف dolly بتحريك الكاميرا للأمام والخلف.

لنستخدم Leva لإضافة أزرار لتحريك الكاميرا للأمام والخلف:

// ...
import { button, useControls } from "leva";

export const Experience = () => {
  // ...

  useControls("dolly", {
    in: button(() => {
      controls.current.dolly(1, true);
    }),
    out: button(() => {
      controls.current.dolly(-1, true);
    }),
  });
  // ...
};

الوسيطة الأولى في دالة dolly هي المسافة التي نريد تحريك الكاميرا بها. الوسيطة الثانية هي قيمة منطقية تشير إلى ما إذا كنا نريد تحريك الحركة بشكل متحرك أم لا.

الآن يمكن لكاميرتنا التحرك للأمام والخلف

إذا أردنا تحقيق نفس النتيجة مع OrbitControls، فسيكون علينا حساب الموقع الجديد للكاميرا والهدف. ثم سيكون علينا تحريك الكاميرا والهدف إلى مواقعهما الجديدة.

التحكم في الـ Truck

يتيح لنا التحكم بـ truck تحريك الكاميرا لأعلى ولأسفل ولليسار ولليمين دون تغيير اتجاه الكاميرا.

كما فعلنا مع التحكم بـ dolly، دعونا نضيف أزرار لتجربة التحكم بـ truck:

// ...

export const Experience = () => {
  // ...
  useControls("truck", {
    up: button(() => {
      controls.current.truck(0, -0.5, true);
    }),
    left: button(() => {
      controls.current.truck(-0.5, 0, true);
    }),
    down: button(() => {
      controls.current.truck(0, 0.5, true);
    }),
    right: button(() => {
      controls.current.truck(0.5, 0, true);
    }),
  });
  // ...
};

المعاملان الأول والثاني من دالة truck هما المسافات الأفقية و العمودية التي نريد تحريك الكاميرا بها. أما المعامل الثالث فهو عبارة عن قيمة منطقية تشير إلى ما إذا كنا نريد تحريك الكاميرا مع حركة متحركة أم لا.

يمكنك استخدام قيم مختلفة للمسافات الأفقية و العمودية لتحريك الكاميرا بشكل قطري.

التدوير

توفر Camera Controls طريقة لتدوير الكاميرا برمجيًا حول الهدف، مثل الحركة التي نقوم بها عند سحب الماوس باستخدام OrbitControls.

مخطط دوران المدار

لنقم بإضافة أزرار لتدوير الكاميرا حول هدفها:

// ...

export const Experience = () => {
  // ...
  useControls("rotate", {
    up: button(() => {
      controls.current.rotate(0, -0.5, true);
    }),
    down: button(() => {
      controls.current.rotate(0, 0.5, true);
    }),
    left: button(() => {
      controls.current.rotate(-0.5, 0, true);
    }),
    right: button(() => {
      controls.current.rotate(0.5, 0, true);
    }),
  });
  // ...
};

المعطيات الخاصة بطريقة rotate هي:

  • azimuthAngle: الزاوية الأفقية بوحدة الراديان.
  • polarAngle: الزاوية العمودية بوحدة الراديان.
  • enableTransition: قيمة منطقية تشير إلى ما إذا كنا نريد تحريك الحركة أم لا.

الوقت السلس

للتحكم في وقت الحركة عند استخدام الحجة enableTransition، يمكننا استخدام خاصية smoothTime.

Three.js logoReact logo

React Three Fiber: The Ultimate Guide to 3D Web Development

✨ You have reached the end of the preview ✨

Go to the next level with Three.js and React Three Fiber!

Get full access to this lesson and the complete course when you enroll:

  • 🔓 Full lesson videos with no limits
  • 💻 Access to the final source code
  • 🎓 Course progress tracking & completion
  • 💬 Invite to our private Discord community
Unlock the Full Course – Just $85

One-time payment. Lifetime updates included.