我想立即警告您,本系列文章不适合经验丰富的程序员,甚至根本不适合程序员。 我了解到,考虑到资源的IT主题,这听起来非常挑衅,但仍然让我解释一下……作为一个听众,我看到普通的设计师想开始使用Adobe进行编程,但是出于某种原因(因为担心)。未知,对自己的能力缺乏信心或缺乏语言知识)无法朝这个方向迈出第一步。 在帮助他们理解“不是烧锅的神灵”方面,我看到了我微不足道的任务,任何有足够动力的人都可以学习编写工作程序代码。 他们中的某些人可能会被这款游戏所吸引,以至于他们决定成为真正的开发者。 什么代码不是在开玩笑?
这篇文章将讨论如何编写自己的小工具(JavaScript中的脚本)以在Adobe Illustrator中创建自己的独特工具,这不仅可以减少您的时间,而且可以改善与该出色的图形编辑器的交互。 首先,我将阐述问题,然后展示解决该问题的代码,然后再详细介绍它的创建方式。 它不会讨论Javascript的基础知识, Illustrator对象模型的功能或用于编写/调试代码的各种编辑器。 您可以根据需要自己找到此信息。 我认为最主要的是对编写程序的基本原理的理解,这是本文的重点。 如果您准备跳到头顶上方,欢迎切入!
Adobe Illustrator有一个剪贴蒙版工具,可与剪贴蒙版一起使用。 剪贴蒙版包含三个命令:“制作”,“释放”和“编辑蒙版”。 第一个创建掩码,第二个-解析,第三个-允许您编辑。 我们对第二个命令感兴趣,该命令将“剪切蒙版”对象拆分为轮廓和蒙版的内容。 很多时候,不仅需要拆卸面罩,而且要去除面罩的轮廓,只留下内装物。 常规的Release Clipping Mask命令不会执行此操作,因此在应用它之后,您需要再执行三个步骤:
- 从对象中删除选择
- 仅选择蒙版轮廓
- 去除面膜轮廓
如果您白天必须经常执行此顺序操作,则会出现问题:是否不可能以某种方式减少这些操作的数量以获得相同的结果? 这里的要点根本不是懒惰,而是缺少必要的工具。 现在想象一下您拥有这样的工具。
在这里,您会暂时不专心工作,并陷入沉思,如果Adobe Illustrator兵工厂拥有像Expand Clipping Mask这样的团队来为您执行所有这些操作,那会多么酷。 好主意! 您认为,您需要为Adobe编写技术支持。 有以下想法:突然之间,他们被写了这么多次了? 如果有一天,也许他们会添加这样的工具,那么这对您有什么帮助? 此刻需要这个团队!
关键时刻到了-您可以自己编写脚本!
快说不做!
1 #target illustrator 2 if (app.documents.length > 0) { 3 var doc = app.activeDocument; 4 var sel = doc.selection; 5 var clipPath; 6 if (sel.length > 0) { 7 if (sel[0].typename == 'GroupItem' && sel[0].clipped == true) { 8 var clipGroup = sel[0].pageItems.length; 9 for (var i = 0; i < clipGroup; i++) { 10 if (sel[0].pageItems[i].typename == 'PathItem' && sel[0].pageItems[i].clipping == true) { 11 clipPath = sel[0].pageItems[i]; 12 break; 13 }; 14 }; 15 app.executeMenuCommand('releaseMask'); 16 clipPath.remove(); 17 } 18 else { 19 alert (' -!'); 20 }; 21 } 22 else { 23 alert (' !'); 24 }; 25 } 26 else { 27 alert (' !'); 28 };
这是一个很小的代码,可以帮助解决此问题。 您只需要做一件事即可运行无聊操作,而不必执行几个操作-运行Expand Clipping Mask脚本。 现在,您拥有了一个方便的工具,可以使用由自己动手制作的口罩。
当然,我这里有点不屑一顾。 首先,脚本不是由您编写的,其次-它不是我们想要的通用。 但是,如果您对它的工作方式感兴趣,最重要的是,您对如何自己学习编写此类程序感兴趣,那么我将很高兴向您介绍有关此问题的顺序和详细注释。
首先,任何脚本(脚本/程序/ JavaScript代码)都包含几个主要代码块:变量的声明(初始化),基本检查(条件),例如“程序引擎”-实现主要工作功能的代码脚本。 当然,这种划分是非常任意的,因为功能部分也具有检查功能,但是结构原理就是这样。 自然,程序越大,将其划分为相似块的难度就越大。 但就我们而言,这是可能的。 第8至16行是脚本引擎,其余的行是变量声明以及对其处理的各种基本检查。 如果进行计数,结果表明检查块中的行数大于功能块中的行数。 这些检查真的重要吗?
为什么我们需要检查?
认真的程序员会理解我的知识,这对初学者来说非常有用。 需要进行检查以确保程序功能部分的正常运行。 如果您不编写它们,那么在脚本执行过程中的任何错误都将导致软件故障。 这不好。
当然,上述认真的同志出于这种目的使用了try / catch构造,但我认为通常的if / else将是简洁的和更易于理解的构造。 特别是对于新手脚本作者。
让我们详细检查这些行的作用。 第一行是这样的事实,即使脚本不是从Adobe Illustrator运行的,也将在其中执行。 因此,如果您从Illustrator运行脚本,则可以省略此行。
#target illustrator
接下来,它在脚本运行时检查Adobe Illustrator中打开的文档。 这些行应如下所示:如果应用程序( app
)中的( if
)文档数( documents.length
)大于零(> 0),则应执行{...}中包含的代码。 否则( else
),显示消息( alert
)“没有打开的文档!” 并完成脚本。
if (app.documents.length > 0) { ... ... } else { alert (' !'); };
以下代码块检查文档中的选择。
if (sel.length > 0) { ... ... } else { alert (' !'); };
应该注意的是,如果在前面的示例中我们使用保留名称(例如app
或documents
),那么这里我们使用sel变量,我们自己在第3行和第4行中确定了该变量
var doc = app.activeDocument; var sel = doc.selection;
其中doc
是指向活动Illustrator文档的链接,而sel
是指向活动文档中所选对象的链接。
引用(或引用)是指向特定对象的指针。 当然,我很清楚,完全无害的俄语单词“ pointer”可以将任何不熟悉OOP(面向对象编程)的人引入木马。 但简单地说,一切并不像看起来那样复杂。 链接存储在变量中,用于访问对象。 在doc
变量中,我们保存(使用赋值运算符=
为其赋值)指向应用程序(app)的活动文档(activeDocument)的指针,在sel
变量中,我们将指向选择(selection)的指针保存在应用程序(app)的活动文档(activeDocument)中。 为了避免再次编写app.activeDocument,我们改用doc
变量,该变量已包含此代码。 这就是链接看起来像sel = doc.selection
。 我希望我能清楚地解释。
因此,在这种情况下, if (sel.length > 0)
则检查活动文档中是否存在选定的对象,如果没有,则显示消息:“没有选定的对象!”
以下几行会同时检查两种情况的准确性,为双关语表示歉意。 第一个是所选对象是一个组( GroupItem
),第二个是该组实际上是一个剪GroupItem
版(此对象的clipped
属性为true
)。
if (sel[0].typename == 'GroupItem' && sel[0].clipped == true) { ... ... } else { alert (' -!'); };
在这里我们需要一些解释。
什么是遮罩对象? 这是一个团体,但不是普通的团体。 常规组是从属于“主”或“父”对象的不同对象的集合。 对于蒙版对象,这也是一个组,但是与通常的对象不同,它由两部分组成-蒙版的轮廓及其内容。 因此,要从脚本中确定在您前面是常规组还是遮罩组,则其clipped
属性允许。 如果clipped属性的值为false
(false),则这是一个普通组;如果为true
(true),则这是一个裁剪组。
询问者会注意到,使用了sel[0]
构造,而不是我们之前定义的sel
变量。 从脚本的角度来看,这可以解释为一个事实,即选择是元素的集合(集合),而不是特定的对象(即使仅选择了一个对象)。 为了检查此对象的类型( typename
)是否与所选集合元素的类型匹配,使用了sel[0]
构造,它指向集合的第一个[0]
元素,在本例中为所选组。
结果,如果所选对象既是组又是蒙版,则执行其他代码,否则显示消息:“选择不是蒙版对象!”
有支票-就是这样。 来吧
主要代码是如何创建的?
在本文的这一部分中,我将不仅尝试评论代码的工作方式,而且还将描述其创建过程。 如果不是整个过程,那么至少要有一些重点。 让我们开始吧!
以前,描述了必须执行的三个动作来解决“拆卸”剪贴蒙版以及随后移除蒙版轮廓的任务。 他们将通过另一个操作(发布命令)得到补充,我们的算法将从该操作开始。 我将在这里重复它们以刷新上下文。
- 运行“释放剪贴蒙版”命令
- 从对象中删除选择
- 仅选择蒙版轮廓
- 去除面膜轮廓
如果严格按照列表执行此操作序列,则可以通过调用executeMenuCommand()
方法轻松解决前两点。 但是,到了第三点,我们将面临一个无法解决的问题。 如果在执行第一个操作(“释放剪贴蒙版”)之后不再有蒙版,而只有一组选定对象,那么如何获得到蒙版轮廓的链接? 是的,他在结构上与执行此操作之前不同。
通常,该逻辑建议首先需要创建到蒙版轮廓对象的链接(参考)。 在考虑了什么PathItem
遮罩轮廓与常规轮廓相比如此独特之后,我们将发现PathItem
类的clipping
属性。 现在,我们只需要PathItem
(for)循环中mask组的所有对象,并找到具有clipping = true
属性的PathItem
。 这将是所需的电路。 执行此代码的结果是,我们将获得一个指向遮罩轮廓对象的链接,并将其保存在clipPath
变量中。
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; }; };
接下来是什么? 让我们回到算法并为项目1编写代码。此行执行Release Clipping Mask命令,但不是通过用户界面而是从脚本执行。 是的,很简单!
app.executeMenuCommand('releaseMask');
我们跳过步骤2和3(因为我们已经有了遮罩轮廓,或者更确切地说是指向clipPath对象的链接),然后直接转到步骤4。在这里,我们调用clipPath
对象的remove()
方法。 此方法删除蒙版的轮廓。
clipPath.remove();
现在就这些了。 感谢您的关注!
希望您现在了解,开始使用Adobe Illustrator编程并不像乍看起来那样困难。
PS当然,生成的脚本远非理想。 它不适用于其轮廓由CompoundPath
, CompoundShape
或TextFrame
表示的蒙版。 在第二部分中,阅读如何修改脚本,使其真正成为一个成熟的工具。