كيفية إنشاء استوديو حركة 2.5D باستخدام Opus 5.5

موجه واحد، ملف HTML واحد، ومُصدِّر من 25 سطرًا فقط: أنشئ استوديو حركة 2.5D يعمل في المتصفح باستخدام Opus 5.5 مع Claude Code، ثم اعرضه بصيغة MP4، واختبر نداء API لقوائم اللقطات الخاصة بـ Opus 5.5 باستخدام Apidog CLI.

Ahmed Waheed

Ahmed Waheed

12 نوفمبر 2026

كيفية إنشاء استوديو حركة 2.5D باستخدام Opus 5.5

Apidog للمؤسسات

النشر على الخوادم المحلية

SSO و RBAC

متوافق مع SOC 2

استكشف Apidog للمؤسسات

يمكنك بناء استوديو حركة 2.5D باستخدام Opus 5.5 في جلسة واحدة من Claude Code: ملف HTML واحد يرصّ طبقات مسطّحة على أعماق مختلفة، وينقل كاميرا ذات إطارات مفتاحية بينها مع منحنيات تخفيف (easing)، وسكربت Playwright من 25 سطرًا يلتقط كل إطار ويمرّره إلى ffmpeg. استغرقت عملية البناء لدينا نحو 20 ثانية لمعالجة فيديو MP4 بدقة 720p ومدة 6 ثوانٍ (180 إطارًا) على حاسوب محمول.

يوضّح هذا الدليل الأوامر التوجيهية (prompts) المستخدمة، والشيفرة التي كتبها الوكيل، والأخطاء التي واجهها، وكيفية التحقق من استدعاءات واجهة Opus 5.5 API خلف ميزة «وصف لقطة» باستخدام Apidog CLI.

ما هو استوديو الحركة 2.5D؟

استوديو الحركة 2.5D هو أداة رسوم متحركة تضع طبقات ثنائية الأبعاد مسطّحة (السماء، التلال، مدينة، بطاقة عنوان، أوراق نباتات في المقدمة) على أعماق مختلفة في فضاء ثلاثي الأبعاد، ثم تُحرّك كاميرا افتراضية بينها. الطبقات الأقرب إلى الكاميرا تتحرك أسرع من البعيدة، مما يُنتج تأثير المنظور المتوازي (parallax) وإحساسًا بالعمق دون أي نماذج ثلاثية الأبعاد.

ثلاثة عناصر تجعله استوديوًا وليس مجرد رسوم متحركة تُستخدم مرة واحدة:

  1. مخطط مشهد (Scene graph): طبقات لها عمق z وحجم وموضع ومحتوى HTML.
  2. خط زمني: إطارات مفتاحية للكاميرا (دوللي، انزلاق جانبي، دوران) ولكل طبقة (الشفافية، التكبير، الموضع)، ولكل منها منحنى تخفيف (easing).
  3. عارض حتمي: دالة renderAt(t) ترسم الإطار الدقيق لأي وقت t، بحيث لا يعتمد التصدير أبدًا على سرعة تشغيل الجهاز.

النقطة الثالثة هي ما تتجاهله معظم الدروس، وهي التي تحدد ما إذا كان ملف MP4 الخاص بك سيظهر بانتقاطات.

إعداد Claude Code على Opus 5.5

Opus 5.5 هو النموذج المناسب للبدء به في هذا النوع من المهام. تصف نظرة Anthropic العامة على النماذج بأنه «مخصص لمهام البرمجة الوكيلية والمعرفية طويلة الأمد»، بنافذة سياق تبلغ مليون رمز (token)، وحد أقصى للمخرجات 128 ألف رمز، وسعر 4 / 20 دولارًا لكل مليون رمز مدخلات / مخرجات.

ثبّت النموذج (pin) حتى لا يغيّره تغيير اسم بديل (alias) في منتصف المشروع:

claude --model claude-opus-5-5 --effort high

يستخدم Opus 5.5 افتراضيًا مستوى الجهد medium، وفقًا لـوثائق مستوى الجهد. ارفعه إلى high في البناء الأول، عندما يتعين على الوكيل ضبط رياضيات الإسقاط بشكل صحيح. ثم عُد إلى medium في التعديلات الصغيرة على الإطارات المفتاحية والألوان. إذا أردت التعرف على خلفية النموذج أولًا، اقرأ ما هو Claude Opus 5.5 وكيف يغيّر تخزين الأوامر التوجيهية مؤقتًا (prompt caching) تكلفتها.

الأمر التوجيهي الذي يبني الاستوديو

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

Build a 2.5D motion studio as one file, studio.html, with no dependencies.
- Scene: 6 layers (sky, moon, hills, city skyline, a title card "Ship it.",
  foreground foliage), each at its own z depth, using CSS perspective and
  preserve-3d.
- Camera: keyframes for x, y, z (dolly) and yaw (orbit around the card).
- Per-layer tracks: opacity, scale, y. Easings: linear, easeInOutCubic,
  easeInOutSine, easeOutBack.
- A timeline bar with keyframe markers, a playhead, click to scrub,
  space to play or pause.
- renderAt(t) must be pure in t. Expose window.__seek(t) that resolves after
  the frame paints, and a ?capture mode that hides the UI.
Then write export.mjs: Playwright opens ?capture, seeks every frame at 30 fps,
screenshots it and pipes PNGs to ffmpeg as H.264.

السطران الأخيران هما الأهم: فهما يجعلان التصدير جزءًا من التصميم، وليس إضافة لاحقة.

الشيفرة التي كتبها الوكيل

يتكوّن الاستوديو من نحو 150 سطرًا. ثلاثة أجزاء هي الأهم.

الإطارات المفتاحية والتخفيف

كل مسار (track) هو قائمة مرتّبة من الإطارات المفتاحية. تبحث sample() عن المفتاحين المحيطين بالوقت t، وتطبّق منحنى تخفيف المفتاح الخارجي، وتُجري الاستيفاء (interpolation) لكل حقل رقمي:

function sample(keys, t) {
  if (t <= keys[0].t) return keys[0];
  for (let i = 0; i < keys.length - 1; i++) {
    const a = keys[i], b = keys[i + 1];
    if (t <= b.t) {
      const p = (easings[a.ease] || easings.linear)((t - a.t) / (b.t - a.t));
      const out = {};
      for (const k in b) if (typeof b[k] === 'number' && k !== 't') out[k] = a[k] + (b[k] - a[k]) * p;
      return out;
    }
  }
  return keys[keys.length - 1];
}

خدعة العمق

الكاميرا لا تتحرك أبدًا؛ العالم هو الذي يتحرك في الاتجاه المعاكس. عندئذٍ تحصل كل طبقة على إزاحة في z مع مقياس تعويضي:

const PERSPECTIVE = 1200; // must match #viewport perspective
world.style.transform =
  `translate3d(${-cam.x}px, ${-cam.y}px, ${cam.z}px) rotateY(${-cam.yaw}deg)`;
const comp = 1 - L.z / PERSPECTIVE;
el.style.transform = `translate(-50%,-50%) ` +
  `translate3d(${x * comp}px, ${y * comp}px, ${L.z}px) scale(${comp * s})`;

مع ضبط perspective في CSS على 1200px، تُعرض الطبقة عند z = -900 بمقياس 1200 / 2100، أي 57% من حجمها. مضاعفة مقياسها وإزاحتها على المحورين x/y بالقيمة 1 + 900/1200 = 1.75 تُلغي ذلك. عندها تظهر كل طبقة بالحجم والموضع اللذين صممتهما عندما تستقر الكاميرا، ولا تزال تتحرك بسرعتها الخاصة عندما تتحرك الكاميرا. هذا هو الخداع بصورة كاملة.

استوديو الحركة 2.5D في المتصفح: بطاقة عنوان أمام قمر وتلال وأفق مدينة، مع خط زمني يعرض إطارات الكاميرا المفتاحية بالأزرق، والإطارات المفتاحية للطبقات بالأصفر، ورأس تشغيل أحمر عند 2.10 ثانية

الخطأ الذي يجدر معرفته

في النسخة الأولى كانت الشيفرة تضبط مقياس كل طبقة دون إزاحتها، فارتفعت التلال لتغطي ثلثي السماء. الحل: ضرب x وy في comp أيضًا. اكتشفنا الخطأ من إطار واحد مُصيَّر، لا من قراءة الشيفرة، لذا اطلب من وكيلك تصيير صور ثابتة في البداية والمنتصف والنهاية قبل أن تثق بأي حركة كاميرا.

تصدير الخط الزمني إلى MP4

التشغيل في الزمن الحقيقي يستخدم requestAnimationFrame، وهي تُسقط إطاراتًا عندما يكون الجهاز مشغولًا. أما التصدير فلا يُسمح له بذلك. لذلك يُشغّل المُصدِّر الوقت من فهرس الإطار وينتظر حتى تُرسم كل طبقة قبل التقاط لقطة شاشة عبر Playwright:

import { chromium } from 'playwright';
import { spawn } from 'node:child_process';
import { pathToFileURL } from 'node:url';

const out = process.argv[2] || 'out.mp4';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 720 } });
await page.goto(pathToFileURL('studio.html').href + '?capture');

const { duration, fps } = await page.evaluate(() => window.__scene);
const ffmpeg = spawn('ffmpeg', ['-y', '-f', 'image2pipe', '-framerate', String(fps),
  '-i', '-', '-c:v', 'libx264', '-pix_fmt', 'yuv420p', '-crf', '18', out],
  { stdio: ['pipe', 'ignore', 'inherit'] });

const frames = Math.round(duration * fps);
for (let i = 0; i < frames; i++) {
  await page.evaluate(t => window.__seek(t), i / fps);
  ffmpeg.stdin.write(await page.screenshot({ type: 'png' }));
}
ffmpeg.stdin.end();
await new Promise(r => ffmpeg.on('close', r));
await browser.close();

تتحقق وعد window.__seek(t) بعد إطارين من إطارات الحركة، بحيث ترى كل لقطة شاشة التحويلات الجديدة. تقرأ image2pipe (انظر وثائق صيغ ffmpeg) صور PNG من الإدخال القياسي (stdin)، ويحافظ yuv420p على قابلية تشغيل الملف في المتصفحات.

نتيجة تشغيلنا: 180 إطارًا، 1280×720، بمعدل 30 إطارًا في الثانية، 6.0 ثوانٍ، ملف MP4 بحجم 420 كيلوبايت، في 20 ثانية من الوقت الفعلي. نفّذ npx playwright install chromium مرة واحدة إذا لم يكن لدى Playwright متصفح بعد.

ثلاثة إطارات من ملف MP4 المُصدَّر عند 0.3 و2.5 و5.9 ثانية: تدفع الكاميرا نحو بطاقة العنوان بينما يتحرك أفق المدينة والتل الأمامي بسرعات مختلفة، ثم تدور بحيث تميل البطاقة

أبراج المدينة تتحرك أقل من التل الأمامي الداكن، الذي يخرج من الكادر بالكامل. هذا هو تأثير المنظور المتوازي (parallax).

إضافة ميزة «وصف لقطة» باستخدام واجهة Opus 5.5 API

الخطوة التالية: اسمح لكاتبٍ بكتابة وصف لقطة والحصول على الإطارات المفتاحية في المقابل. يستدعي الاستوديو واجهة Messages API مباشرة:

curl https://api.anthropic.com/v1/messages \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "anthropic-version: 2026-10-21" \
  -H "content-type: application/json" \
  -d '{
    "model": "claude-opus-5-5",
    "max_tokens": 4096,
    "output_config": { "effort": "low" },
    "system": "Return only JSON: {\"camera\": [{\"t\",\"x\",\"y\",\"z\",\"yaw\",\"ease\"}], \"tracks\": {}}. Times in seconds, 0 to 6.",
    "messages": [{ "role": "user", "content": "Slow push-in, slight orbit right, title fades up in the first second." }]
  }'

تفصيلان من وثائق مستوى الجهد مهمان هنا. output_config.effort هو الموضع الذي يُضبط فيه مستوى الجهد في طلب Messages API. كما أن Opus 5.5 يستخدم دائمًا التفكير التكيّفي (adaptive thinking) (أي طلب يتضمن thinking: {"type": "disabled"} يُرجع الخطأ 400)، لذا تُحتسب رموز التفكير ضمن max_tokens. إذا ضبطته على قيمة منخفضة جدًا، سيُقتطع الـ JSON في منتصف المصفوفة مع stop_reason: "max_tokens". قائمة لقطات هي مهمة صغيرة ومحددة جيدًا، لذا فإن الجهد low هو إعداد منطقي للبداية؛ لكن أجرِ مقارنتك الخاصة قبل الاستقرار عليه.

دع Claude Code يختبر استدعاء الـ API باستخدام Apidog CLI

الرد المقتطع أو المليء بالكلام الزائد يُعطّل sample() وقت التصيير، لذا يحتاج هذا الاستدعاء إلى اختبار عقد (contract test). تستطيع جلسة Claude Code نفسها كتابة هذا الاختبار وتشغيله باستخدام Apidog CLI.

ثبّت الأداة وسجّل الدخول مرة واحدة:

npm install -g apidog-cli@latest
apidog auth login --with-token <YOUR_TOKEN>
apidog skill install

ثم أعطِ الوكيل أمرًا توجيهيًا واحدًا:

In Apidog project <projectId>, create an endpoint for POST /v1/messages and a
test case that sends the "describe a shot" request above with model
claude-opus-5-5. Assert: status 200, body.model is "claude-opus-5-5",
stop_reason is not "max_tokens", and content[0].text parses as JSON with a
non-empty camera array whose t values rise from 0 to 6. Use an environment
with base URL https://api.anthropic.com and the key in a variable. Run it and
summarize failures.

يقرأ الوكيل مخططات الحمولة (payload schemas) بدلًا من تخمينها، ويتحقق من ملفاته، ثم ينشئ كل شيء ويشغّله:

apidog cli-schema get endpoint-create
apidog cli-schema get test-case-create
apidog cli-schema validate test-case-create --file case.json
apidog environment create anthropic --project <projectId> --base-url https://api.anthropic.com
apidog endpoint create --project <projectId> --file endpoint.json
apidog test-case create --project <projectId> --file case.json
apidog run --test-case <caseId> --project <projectId> -e <envId> -r cli,json

مرّر المفتاح وقت التشغيل باستخدام --env-var "api_key=$ANTHROPIC_API_KEY" حتى لا يُخزَّن أبدًا داخل المشروع. أعِد تشغيل حالة الاختبار عند تغيير الأمر التوجيهي للنظام (system prompt) أو مستوى الجهد، لأن كليهما يغيّر ما يُرجَع. الأمر نفسه apidog run مع -r junit يتكامل مع CI؛ انظر دليل Apidog CLI لخطوط CI/CD وApidog CLI في Claude Code. تغطي الخطة المجانية من Apidog ما يصل إلى 4 مستخدمين.

إلى أين تُطوّر الاستوديو لاحقًا

الأسئلة الشائعة

ماذا يعني 2.5D في الرسوم المتحركة؟ يعني وضع أعمال فنية ثنائية الأبعاد مسطّحة على أعماق مختلفة وتصويرها بكاميرا متحركة. تحصل على تأثير المنظور المتوازي وإشارات العمق دون نماذج ثلاثية الأبعاد أو إضاءة أو محرك ثلاثي الأبعاد.

لماذا استخدام Opus 5.5 بدلًا من نموذج أصغر في هذا البناء؟ يجمع البناء الأول بين رياضيات الإسقاط ومحرك إطارات مفتاحية وخط التقاط في مرور واحد. تضع Anthropic نموذج Opus 5.5 للمهام البرمجية الوكيلية طويلة الأمد، وقد أنتجت جلستنا استوديوًا عاملًا من أمر توجيهي واحد وجولة إصلاح واحدة. للتعديلات الصغيرة لاحقًا، يكفي مستوى جهد أدنى.

لماذا لا أسجّل الشاشة بدلًا من التقاط الإطارات؟ تسجيل الشاشة يتبع الزمن الحقيقي، فأي إطار بطيء يصبح إطارًا مُسقطًا أو مكرَّرًا. أما الانتقال إلى i / fps والتقاط كل إطار يجعل الناتج متطابقًا على كل جهاز.

هل يمكنني استخدام ميزة «وصف لقطة» دون مفتاح API؟ لا. تستدعي الميزة واجهة Messages API، التي تتطلب مفتاح Anthropic API الخاص بك. أما بقية الاستوديو وتصدير MP4 فيعملان محليًا دون أي مفتاح.

أي مستوى جهد ينبغي لاستدعاء قائمة اللقطات أن يستخدم؟ ابدأ بـ low، فالمهمة قصيرة ومخطط المخرجات ثابت. ارفعه فقط إذا أظهر اختبار Apidog لديك إطارات مفتاحية مشوّهة أو غير مطابقة للوصف.

ممارسة تصميم API في Apidog

اكتشف طريقة أسهل لبناء واستخدام واجهات برمجة التطبيقات