مقدمهای بر مفاهیم پایه اسکریپت نویسی در افترافکت
سطح آموزش: متوسط
در این آموزش ابتدا مفاهیم پایه و تمرینهای خوب لازم برای شروع نوشتن اسکریپت افترافکت را بررسی میکنیم و سپس به انجام کارهای معمول در افترافکت مثل ایجاد پروژه، ایجاد کامپوزیشن، ایجاد لایه، ایجاد اشکال، اضافه کردن افکت، تغییر مقادیر، عبارات expression، استفاده از نوشته و فونت، اضافه کردن کی فریم، استفاده از کارکردها و بسیاری موارد دیگر میپردازیم.
دانلود فایل پروژه و اسکریپت افترافکت
اسکریپتها از زبان Adobe ExtendScript استفاده میکنند. ExtendScript فرم توسعهداده شدهای از جاوا اسکریپت (JavaScript) است و در تعدادی از برنامههای Adobe مثل فتوشاپ، ایلوستریتور، و ایندیزاین از آن استفاده میشود. ExtendScript روش خوب و پربازدهی برای این است که به هر آنچه که میخواهید در افترافکت دست پیدا کنید.
ایجاد اولین کامپوزیشن
ما با استفاده از متد ()newProject از آبجکت app و قرار دادن آنها بین دو براکت شروع میکنیم. آبجکت app ریشه root همه چیز است. همانطور که در شکل زیر دیده میشود:
دیاگرام سلسله مراتبی آبجکتهای اسکریپتنویسی افترافکت
این شکل را میتوان مثل بقیه مواردی که در اینجا در موردش توضیح میدهم، در راهنمای اسکریپتنویسی Adobe After Effects CS6 یافت.
حالا کامپوزیشن خودمان را با استفاده از آبجکتهای زیردستهی آبجکت app ایجاد میکنیم، که یکی آبجکت زیردستهی project است و شامل پروژه ای است که در خط اول ایجاد کردیم و همینطور آبجکت زیردستهی items که به شما دسترسی به پوشهها و کامپوزیشن هایی میدهد که در پنجره ی Project در افترافکت میبینید.
[code lang=”js”] {// Creating project
app.newProject();
// Creating comp
app.project.items.addComp("Demo", 1280, 720, 1, 10, 24);
}
[/code]
مرتب کردن کد
کدنویسی تمیز و قابل نگهداری خیلی مهم است. ما نمیخواهیم عبارات expression کثیف و عجله ای بنویسیم. از آنجاییکه میخواهیم اسکریپتهایمان بسادگی قابل توسعه باشند، لازم است قراردادهای اهالی جاوا اسکریپت را بپذیریم.
بدین ترتیب ما اطلاعات کلیدی را به متغیر تبدیل میکنیم و آنها را بر اساس محتوایشان نامگذاری میکنیم. از آنجاییکه که ممکن است پروژه یا کامپوزیشنی در فایل افترافکت ما باشد، شروطی را هم ایجاد میکنیم.
[code lang=”js”] {// Creating project
var currentProject = (app.project) ? app.project: app.newProject();
// Creating comp
var compSettings = cs = [1280, 720, 1, 10, 24];
var defaultCompName = "Demo";
var currentComp = (currentProject.activeItem) ? currentProject.activeItem: currentProject.items.addComp(defaultCompName, cs[0], cs[1], cs[2], cs[3], cs[4]);
currentComp.openInViewer();
}
[/code]
کلمه کلیدی var بدین معنی است که متغیر مقابل یک متغیر جدید است. به همین علت در خط ۹ ، از کلمه کلیدی var دیگر استفاده نمیکنیم، چون میخواهیم از مقدار currentComp استفاده کنیم (کامپوزیشنی است که اخیرا ایجاد کردیم).
این هم از توضیحات خط به خط کاری که انجام دادیم:
خط ۳: متغیر جدیدی ایجاد کن currentProject که برابر خواهد بود با app.project اگر app.project تعریف نشده باشد، و در غیراینصورت برابر خواهد بود با ()app.newProject
خط ۶: متغیرهای جدید ایجاد کن compSettings و cs که هر دو برابر با آرایه ای جدید از مقادیر خواهند بود.
خط ۷: متغیر جدید ایجاد کن defaultCompName که مربوط به نامی است که به کامپوزیشن اختصاص میدهیم.
خط ۸: متغیر جدید ایجاد کن currentComp که برابر خواهد بود با activeItem که خصوصیتی از آبجکت currentProject است و در صورتی که تعریف نشده باشد، برابر خواهد بود با متد addComp از زیردستهی items از currentProject که آرایه ای از آرگومانها را ارسال خواهد کرد.
- نام کامپوزیشن
- پهنای کامپوزیشن
- ارتفاع کامپوزیشن
- نسبت پیکسلی کامپوزیشن
- زمان کامپوزیشن (بر حسب ثانیه)
- فریم در ثانیه کامپوزیشن
خط ۹: با استفاده از متد currentComp و با متد openInViewer ، تایملاین برای این کامپوزیشن باز خواهد شد.
در اینجا متد و ویژگیهای زیادی داریم. دوباره اشاره میکنم، لازم هست که در یک زمان مناسبی به راهنمای اسکریپتنویسی در ادوبی افترافکت CS6 نگاهی بیندازید تا بیشتر در مورد آبجکتها و همینطور متدها و ویژگیهای در دسترس بدانید. این راهنما واقعا خوب نوشته شده و یک جستجوی سریع برای عبارت Project Object فورا شما را به اطلاعات صحیح میرساند.
مروری سریع بر مفاهیم جاوا اسکریپت
متغیر (Variable): میتواند یک مقدار، یا آرایهای از مقادیر یک آبجکت را ذخیره کند.
[code lang=”js”] var myVar = "String value";[/code] [code lang=”js”] var myVar = 2;
[/code]
آرایه (Array): شامل چندین مقدار است. آرایهها میتوانند به دو روش اظهار شوند.
[code lang=”js”] var myVar = array("value1", "value2", 3);[/code] [code lang=”js”] var myVar = ["value1", "value2", 3];
[/code]
تابع (Function): بخشی از کد که برای انجام عمل مشخصی طراحی شده است.
[code lang=”js”] function myFunction(argument) {// Do something
}
[/code]
آبجکت (Object): آبجکت پیچیده تر است، اما برای الان لازم است که بدانید آبجکت، شامل متدها و ویژگیهایی است.
ویژگی (Property): مشابه یک متغیر است.
[code lang=”js”] myObject.myProperty = "Value" [/code]متد: مشابه فراخوانی یک تابع است.
[code lang=”js”] myObject.myMethod(argument) [/code]
افزودن Undo Groups
از آنجاییکه محاسبات زیادی در حین اجرای اسکریپت انجام میشود، لازم است مشخص کنید چه اتفاقی بیفتد وقتی که کلیدهای CMD + Z یا CTRL + Z را بروی صفحه کلید میزنید. انجام این کار خیلی ساده است، فقط لازم است کد خود را بین متدهای ()beginUndoGroup و ()endUndoGroup از آبجکت app قرار دهید. این متد ، آرگومان نامی که در منوی Edit > History افترافکت نمایش داده میشود را استفاده میکند.
[code lang=”js”] {app.beginUndoGroup("Demo Script");
// Creating project
var currentProject = (app.project) ? app.project : app.newProject();
// Creating comp
var compSettings = cs = [1280, 720, 1, 10, 24];
var defaultCompName = "Demo"
var currentComp = (currentProject.activeItem) ? currentProject.activeItem : currentProject.items.addComp(defaultCompName, cs[0], cs[1], cs[2], cs[3], cs[4]);
currentComp.openInViewer();
app.endUndoGroup();
}
ایجاد لایه پسزمینه (background)
برای ایجاد لایه پسزمینه، ما از زیردسته ی layers از فراخوانی currentComp متد ()addSolid استفاده میکنیم و این آرگومانها را برای آن ارسال میکنیم:
- رنگ لایه
-
آرایهای از اعداد شناور (بین صفر و یک). برای بدست آوردن این مقدار، لازم است هر یک از مقادیر RGB را بر ۲۵۵ تقسیم کنیم یا از این لینک در وبسایت jsFiddle استفاده کنید تا مقدار آنرا بدست بیاورید.
-
نام لایه
-
پهنای لایه
-
ارتفاع لایه
- نسبت پیکسلی لایه
app.beginUndoGroup("Demo Script");
// Creating project
var currentProject = (app.project) ? app.project : app.newProject();
// Creating comp
var compSettings = cs = [1280, 720, 1, 10, 24];
var defaultCompName = "Demo"
var currentComp = (currentProject.activeItem) ? currentProject.activeItem : currentProject.items.addComp(defaultCompName, cs[0], cs[1], cs[2], cs[3], cs[4]);
currentComp.openInViewer();
// Creating background layer
var backgroundLayer = currentComp.layers.addSolid([93, 5, 2], "Background", cs[0], cs[1], cs[2]);
app.endUndoGroup();
}
[/code]
افزودن افکت شبکه (Grid Effect)
بهترین راه برای ایجاد تقاطع متمرکز، استفاده از افکت Grid Effect بروی لایه پسزمینه است. برای انجام این کار، ما از متغیر backgroundLayer استفاده میکنیم که ارجاع میدهد به
[code lang=”js”] currentComp.layers.byName("backgroundLayer")[/code]
و از ویژگی Effects استفاده میکنیم.
[code lang=”js”] // Adding the grid effectbackgroundLayer.Effects.addProperty("Grid");
backgroundLayer.property("Effects").property("Grid").property("Anchor").setValue([0,0]);
backgroundLayer.property("Effects").property("Grid").property("Corner").expression = "[width/2, height/2]";
backgroundLayer.property("Effects").property("Grid").property("Color").setValue([0,0,0]);
backgroundLayer.property("Effects").property("Grid").property("Blending Mode").setValue(2);
[/code]
در اینجا باید به چند مورد توجه داشته باشید. اول اینکه متد ()property بصورت زنجیروار است که بدین معنی است که میتوانید آن را چندین بار فراخوانی کنید تا به ویژگیهای زیر دستهای که میخواهید برسید.
شفافیت (opacity) لایه:
[code lang=”js”]backgroundLayer.property("Opacity")
[/code]
شفافیت (opacity) افکت Grid:
[code lang=”js”] backgroundLayer.property("Effects").property("Grid").property("Opacity")[/code]
دوم اینکه، ما از متد ()setValue وقتی استفاده میکنیم که میخواهیم یک مقدار را تنظیم کنیم، نه وقتی که میخواهیم عبارت expression را تنظیم کنیم.
ایجاد لایه افکت Wipe
برای افزودن افکت wipe ، یک لایه جدید میسازیم و از افکت Radial Wipe استفاده میکنیم.
[code lang=”js”] // Creating the wipe layervar wipeLayer = currentComp.layers.addSolid([0.1, 0.1, 0.1], "Wipe", cs[0], cs[1], cs[2]);
wipeLayer.Effects.addProperty("Radial Wipe");
wipeLayer.property("Effects").property("Radial Wipe").property("Wipe").setValue(2); // Counterclockwise
wipeLayer.property("Opacity").setValue(50);
// Setting wipe transition animation
wipeLayer.property("Effects").property("Radial Wipe").property("Transition Completion").setValueAtTime(0, 100);
wipeLayer.property("Effects").property("Radial Wipe").property("Transition Completion").setValueAtTime(1, 0);
wipeLayer.property("Effects").property("Radial Wipe").property("Transition Completion").expression = "loopOut(‘Cycle’)";
[/code]
ما از متد ()setValueAtTime استفاده کردیم تا کی فریمها را تنظیم کنیم و همینطور یک (“loopOut(“Cycle تا لوپ loop انیمیشن را ایجاد کنیم.
اضافه کردن لایه نوشته (Text)
کار کردن با text، از آنجاییکه باید ویژگیهای مقدار source text را مستقیما تغییر بدهید، کمی متفاوت است.
[code lang=”js”] // Adding text layervar textLayer = currentComp.layers.addText("Countdown");
var textProperty = textLayer.property("Source Text");
var textPropertyValue = textProperty.value;
// Changing source text settings
textPropertyValue.resetCharStyle();
textPropertyValue.fontSize = 200;
textPropertyValue.fillColor = [0, 0, 0];
textPropertyValue.justification = ParagraphJustification.CENTER_JUSTIFY;
textProperty.setValue(textPropertyValue);
// Adding expression to source text
textProperty.expression = "Math.floor(10-time)";
// Adjusting text layer anchor point
var textLayerHeight = textLayer.sourceRectAtTime(0, false);
textLayer.property("Anchor Point").setValue([0, textLayerHeight.height / 2 * -1]);
[/code]
ما ویژگیهای مقداری text را تغییر دادیم و از ()setValue استفاده کردیم تا آنرا مجددا به لایه text خود ارسال کنیم. همینطور از یک عبارت expression ساده استفاده کردیم تا شمارش معکوس countdown ایجاد کنیم.
[code lang=”js”] Math.floor()[/code]
این یک تابع جاوا اسکریپت است که میتواند بخش اعشاری عدد را حذف کند. بعد از آن، نقطه anchor point را با استفاده از متد ()sourceRectAtTime در مرکز قرار میدهیم.
افزودن بیضیها
برای اضافه کردن بیضیها، ما از متد ()addShape استفاده میکنیم و به آن گروه وکتور و گروه شکل اختصاص میدهیم. همینطور یک تابع ایجاد میکنیم تا از کد تکراری اجتناب کنیم.
[code lang=”js”] // Adding shape layer for the circlesvar shapeLayer = currentComp.layers.addShape();
// Adding circle shapes group
var shapeGroup = shapeLayer.property("Contents").addProperty("ADBE Vector Group");
// Adding circle shapes
createEllipse(shapeGroup, 200);
createEllipse(shapeGroup, 400);
// Adding black stroke to the shapes
var stroke = shapeGroup.property("Contents")
.addProperty("ADBE Vector Graphic – Stroke")
.property("Color").setValue([0, 0, 0]);
function createEllipse(shapeGroup, size) {
var ellipse = shapeGroup.property("Contents").addProperty("ADBE Vector Shape – Ellipse");
var ellipseSize = ellipse.property("Size").setValue([size,size]);
}
[/code]
خط ۵ خیلی مهم است، از آنجاییکه نمیتوانید ویژگی Contents را چه در مستندات documentation یا در محیط کاربری افترافکت پیدا کنید. ما از یک تابع سفارشی کوچک بجای تکثیر تابع ایجاد بیضی استفاده کردیم. شما میتوانید از نوشتن چندین تابع استفاده کنید.
یک قانون سرانگشتی ساده: در صورتی که خطوط کد را کپی پیست میکنید، استفاده از یک تابع را در نظر بگیرید.
در ادامه ما فقط ویژگیهای شکل را تغییر دادیم. لازم است که برای بررسی این ویژگیها به راهنمای اسکریپت نویسی ادوبی افترافکت CS6 مراجعه کنید.
ممکن است با این خط var stroke برخورد کرده باشید که کمی متفاوت با آنچه هست که تا حالا نوشته بودیم. جاوا اسکریپت از زنجیرهای کردن خطوط کد پشتیبانی میکند. در این حالت نتیجه ی مشابهی بدست می آید و راه بد و خوب وجود ندارد. این فقط یک استایل کدنویسی شخصی هست که ممکن است بخواهید از آن استفاده کنید یا استفاده نکنید.
ممکنها برای اسکریپتنویسی بیپایان هستند و وقتی خوب آنرا یاد بگیرید ابزار واقعا قدرتمندی را برایتان در ادوبی افترافکت ایجاد میکنند.
نتیجه نهایی
دیدگاه خود را مطرح کنید