يعد هذا المنشور امتدادًا للجزء الأول ، حيث تم عرض البرنامج النصي "قناع توسيع القصاصة" ووصفه بالتفصيل ماذا وكيف يفعل ، وعلى طول الطريق تم النظر في المبادئ الأساسية لإنشاء مثل هذه البرامج بشكل عام. في هذا الجزء ، سأواصل قصة كيفية إضافة وظائف جديدة إلى البرنامج من أجل الحصول على "المنتج النهائي" من "قطعة العمل". هنا لا يمكنك الاستغناء عن الانغماس بشكل أعمق في مجال الموضوع ، والذي يعد أحد الشروط الضرورية لإنشاء منتج متكامل. لذا ، ابدأ الغوص!
يمكن استخدام أشكال الرسم الأولية التالية كمخطط للقناع في Adobe Illustrator: مخطط بسيط (مسار) ، مخطط تفصيلي مركب (مسار مركب) ، شكل مركب (شكل مركب) ، وكائنات نصية (نقطة نص ونص على المسار). في الوقت الحالي ، يعمل البرنامج النصي فقط مع حدود بسيطة ، كما يمكن رؤيته من الكود أدناه ، حيث PathItem
هو استدعاء لعنصر Path.
var clipGroup = sel[0].pageItems.length; for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'PathItem' && sel[0].pageItems[i].clipping == true) { clipPath = sel[0].pageItems[i]; break; }; };
قبل ذلك ، أعلنا متغير clipPath
، لكننا لم clipPath
له قيمة.
var clipPath;
وهذا يعني أن قيمته لم يتم تحديدها بعد ، أي إنه غير undefined
. إذا حددنا الآن قناعًا سيكون مخططه ، على سبيل المثال ، المسار المركب وتشغيل البرنامج النصي ، فسوف ينتج عن البرنامج خطأ في السطر الأخير من الجزء الوظيفي من البرنامج النصي ،
clipPath.remove();
نظرًا لأن الشرط الموجود في الحلقة لن يتحقق ، clipPath
متغير clipPath
undefined
، ومن المستحيل تطبيق طريقة remove()
على شيء غير محدد. لمنع حدوث هذا الموقف ، سنفعل ما يلي - تعيين clipPath
إلى قيمة null
، والتي ، على عكس undefined
، هي بالفعل شيء أكثر تحديدًا يمكنك التحقق منه على الأقل.
دعونا نفكر في كيفية تحديد ما إذا كان بعض المسار المركب هو الخطوط العريضة لقناعنا. عندما أقول ، "دعونا نفكر" ، فهذا يعني أنني أقترح البحث في الوثائق وإيجاد العقار الذي نحتاجه. عن طريق القياس مع PathItem
نحن نبحث عن خاصية clipping
. اتضح أن كائن CompoundPathItem
لا يحتوي على مثل هذه الخاصية ، ولكن هناك خاصية pathItems
يمكنك من خلالها الوصول إلى معالم PathItem
البسيطة التي تحتوي على خاصية clipping
.
الآن يمكننا تحويل أفكارنا / عمليات البحث إلى كود. بادئ clipPath
، clipPath
أن clipPath
لم يتم تعريفه في التكرار السابق ، ثم نقوم بنسخ كتلة التعليمات البرمجية المكتوبة بالفعل وإجراء تغييرات صغيرة عليها.
if (clipPath == null) { var clipGroup = sel[0].pageItems.length; for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'CompoundPathItem' && sel[0].pageItems[i].pathItems[0].clipping == true) { clipPath = sel[0].pageItems[i]; break; }; }; };
في الواقع ، سوف تؤثر التغييرات على سطر واحد فقط. كما نرى هنا ، تم تغيير "PathItem" إلى "CompoundPathItem" ، وتمت إضافة بنية جديدة ، "pathItems [0]" ، والتي نشير إليها إلى عنصر المسار المركب.
if (sel[0].pageItems[i].typename == 'CompoundPathItem' && sel[0].pageItems[i].pathItems[0].clipping == true) {
فيما يلي الكتلة الوظيفية للرمز الذي تم إنشاؤه حتى الآن.
var clipGroup = sel[0].pageItems.length; for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'PathItem' && sel[0].pageItems[i].clipping == true) { clipPath = sel[0].pageItems[i]; break; }; }; if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'CompoundPathItem' && sel[0].pageItems[i].pathItems[0].clipping == true) { clipPath = sel[0].pageItems[i]; break; }; }; };
"المريض" التالي هو الشكل المركب. هنا يصبح للاهتمام للغاية! في الوثائق لا نجد مثل هذا الشيء على الإطلاق. ما يجب القيام به أولاً ، دعونا نحدد فئة الكائنات التي ينتمي إليها. لمعرفة ذلك ، سنكتب رمزًا مساعدًا صغيرًا ، ثم نرميه. كما هو مذكور في الجزء الأول ، نحن لا نعالج مسألة الأدوات المستخدمة لكتابة / تصحيح الأخطاء. لذلك ، افترض أن هذا ملف منفصل ، ثم ينتقل إلى سلة المهملات. سيكون الكود كما يلي:
var obj = app.activeDocument.selection[0]; alert(obj.typename);
في السطر الأول ، نقوم بإنشاء رابط للكائن المحدد ، في السطر الثاني - نعرض رسالة حول نوعه. حدد مخطط القناع في Adobe Illustrator ، أي نفس كائن الشكل المركب وتشغيل البرنامج النصي. في مربع الرسالة ، نرى أن الشكل المركب هو مكون إضافي. نتخلص من التعليمات البرمجية المساعدة ، ونعود إلى الوثائق مرة أخرى ، لكننا لم نعثر على خاصية لقطة أو مسارات في PluginItem. بشكل عام ، لا شيء من شأنه أن يساعدنا على الإشارة بشكل لا لبس فيه إلى أن هذا الكائن هو مخطط القناع. من البرنامج النصي ، لا يمكنك حتى تحديد نوع المكون الإضافي. بعض الوحدة الخارجية وهذا كل شيء!
هذا كمين! - أنت تصرخ في قلوبكم. ويعمل المخ بشكل محموم ، على أمل حل مشكلة غير قابلة للحل. وبعد ذلك ، بعد الاطلاع على جميع الخيارات الممكنة والمستحيلة ، تضغط بشدة على Del
وتحذف الشكل المركب المكروه. وهنا ، من زاوية عينيك على لوحة Layers
، لاحظت أنه بعد هذا الإجراء ، أصبحت حاوية القناع ، التي كانت Clip Group
، مجرد Group
. ماذا يمكن أن يعني ذلك؟ وحقيقة أن الخاصية clipped
لكائن clipped
عن الحقيقة أصبحت false
. ومن هنا ، حل قد ينجح! بالطبع ، هذا هو إلى حد كبير اختراق ، ولكن ما الفرق الذي يحدثه إذا كان ذلك يساعد على تحديد الدائرة المرغوبة.
ستكون خوارزمية تحديد محيط القناع الممثلة بالكائن المركب بالشكل التالي: تتكرر على كل كائنات القناع في حلقة وعند اكتشاف PluginItem ، احذفها وتحقق مما إذا كانت خاصية القصاصات الخاصة بحاوية القناع قد تغيرت. إذا أصبح false
، فهذه هي دائرتنا. الشيء الوحيد الذي يعمل عليه هذا الاختراق هو تحديث DOM Illustrator بعد حذف الكائن ، والذي يمكن القيام به باستخدام طريقة app.redraw()
. بعد ذلك ، ما زلت بحاجة إلى تذكر إعادة الكائن البعيد ، والذي يتم عن طريق الأسلوب app.undo()
.
يوجد أدناه رمز مسار الشكل المركب:
if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'PluginItem') { sel[0].pageItems[i].remove(); app.redraw(); if (sel[0].clipped == false) { app.undo(); clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; };
الآن ، من بين كل الخيارات الممكنة لنوع الكائنات التي يمكن أن تكون الخطوط العريضة للقناع ، TextFrameItem
النص فقط (أو TextFrameItem
، في مصطلحات مراجع البرمجة النصية في Illustrator ). ننتقل إلى الوثائق مرة أخرى ، ومرة أخرى لا نجد خصائص clipping
هناك. ولكن هذه المرة ، لم نعد قلقين بشأن هذا الأمر TextFrameItem
بهدوء أن TextFrameItem
له خاصية kind
تحدد نوع كائن النص ( TextType
). اكتشفنا أنه يمكن أن يكون هناك ثلاثة أنواع: AREATEXT و POINTTEXT و PATHTEXT. النوع الأول ليس ممتعًا بالنسبة لنا ، نظرًا لأنه لا يمكن استخدامه كمخطط تفصيلي للقناع ، بينما لا يزال النوعان الآخران ممتعين. يبقى فقط العثور على الاختراق الذي سيساعدنا على تحديد الآن ليس المخطط التفصيلي ، ولكن الكائن النصي ، الذي هو مخطط القناع. وسيكون هذا الاختراق هو الفريق ، Convert To Area Type ، الذي سيحول POINTTEXT إلى AREATEXT. كما هو الحال مع الشكل المركب ، يحدث تغيير ضمني في الخاصية clipped
.
وفقًا لذلك ، سيكون رمز TextFrameItem من النوع POINTTEXT كما يلي:
if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'TextFrame' && sel[0].pageItems[i].kind == 'TextType.POINTTEXT') { sel[0].pageItems[i].convertPointObjectToAreaObject(); app.redraw(); if (sel[0].clipped == false) { app.undo(); clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; };
لا يوجد سوى TextFrameItem
النوع PATHTEXT اليسار. لسوء الحظ ، عند تحويل PATHTEXT إلى AREATEXT ، clipped
تتغير الخاصية clipped
. ولكن بما أن هذا هو آخر مرشح محتمل لقب "مخطط القناع" ، فمن الممكن استخدام مثل هذا السلوك. أي ، نحن نتحقق من أنه بعد تنفيذ أمر Convert To Area Type
، تظل الخاصية clipped
true
. أدناه هو رمز TextFrameItem من نوع PATHTEXT.
if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'TextFrame' && sel[0].pageItems[i].kind == 'TextType.PATHTEXT') { sel[0].pageItems[i].convertPointObjectToAreaObject(); app.redraw(); if (sel[0].clipped == true) { clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; };
وبالتالي ، إذا قمنا بتجميع أجزاء من التعليمات البرمجية المكتوبة بشكل متسلسل ، بما في ذلك مجموعة من الاختبارات ، فسوف نحصل على هذه الشفرة ، والتي سيتم تنفيذها ، كما هو مذكور في الجزء الأول من المنشور ، بتنفيذ أمر الأمر Expand Clipping Mask الجديد في Adobe Illustrator.
#target illustrator if (app.documents.length > 0) { var doc = app.activeDocument; var sel = doc.selection; var clipPath = null; if (sel.length > 0) { if (sel[0].typename == 'GroupItem' && sel[0].clipped == true) { var clipGroup = sel[0].pageItems.length; for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'PathItem' && sel[0].pageItems[i].clipping == true) { clipPath = sel[0].pageItems[i]; break; }; }; if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'CompoundPathItem' && sel[0].pageItems[i].pathItems[0].clipping == true) { clipPath = sel[0].pageItems[i]; break; }; }; }; if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'PluginItem') { sel[0].pageItems[i].remove(); app.redraw(); if (sel[0].clipped == false) { app.undo(); clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; }; if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'TextFrame' && sel[0].pageItems[i].kind == 'TextType.POINTTEXT') { sel[0].pageItems[i].convertPointObjectToAreaObject(); app.redraw(); if (sel[0].clipped == false) { app.undo(); clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; }; if (clipPath == null) { for (var i = 0; i < clipGroup; i++) { if (sel[0].pageItems[i].typename == 'TextFrame' && sel[0].pageItems[i].kind == 'TextType.PATHTEXT') { sel[0].pageItems[i].convertPointObjectToAreaObject(); app.redraw(); if (sel[0].clipped == true) { clipPath = sel[0].pageItems[i]; break; } else { app.undo(); } }; }; }; app.executeMenuCommand('releaseMask'); clipPath.remove(); } else { alert (' -!'); }; } else { alert (' !'); }; } else { alert (' !'); };
هنا يمكنك وضع حد ل. لا ، فاصلة منقوطة أفضل.
آمل أنه بفضل هذه المنشورات ، ساعدتني في الاقتراب من هدفك - بدء البرمجة في Adobe Illustrator. شكرا لاهتمامكم!