《零基礎的 PhotoShop CEP 6 開發(fā)教程》系列目錄
「 0 」目錄
「 1 」配置開發(fā)環(huán)境
「 2 」CEP 文件結構
「 3 」CEP 的運行機制
「 4 」Hello World 亿扁!
「 5 」事件(EVENTS)
「 6 」調用 JSX 并傳遞信息
「 7 」UI - HTML 開發(fā)的一些細節(jié)
「 8 」API - 文件讀寫與二進制數據
「 9 」簽名打包與 ZXPSignCmd
「 X 」CEP 更新到 6.1版了
CEP 擴展通過事件(Event)來捕獲 PhotoShop 的各種操作和狀態(tài)的變化,同時也可作為 JAX 和 CEP JavaScript 之間傳遞信息的工具。
事件機制
當宿主應用(如 PhotoShop) 進行各種操作和狀態(tài)的變化時就會發(fā)送事件,在 CEP 的 JavaScript 中通過監(jiān)聽器把方法和事件類型綁定,每當事件發(fā)生鉴分,就會執(zhí)行綁定的方法。
同時也可以發(fā)送自定義的事件,而且在 JSX 中也可以發(fā)送事件仿吞,這就可以在 JAX 與 CEP 的 JavaScript 間傳遞信息和數據了。
事件屬性
事件(Event)作為一個對象捡偏,有以下屬性:
屬性 | 名稱 | 作用 |
---|---|---|
type |
類型 | 用來識別事件的名稱 |
scope |
作用范圍 | 可設置為"APPLICATION" (當前宿主應用)或者 "GLOBAL" (全局) |
appId |
應用 ID | 生成事件的宿主應用的識別名稱唤冈。可選 |
extensionId |
擴展 ID | 生成事件的擴展的識別名稱银伟∧愫纾可選 |
data |
數據 | 事件攜帶的數據,用來傳遞信息 |
事件分為 2 種:
CEP 事件
宿主程序事件
PhotoShop 啟動彤避、打開文檔等會產生的這類事件傅物,
這種事件有自己的類型(type),例如:
applicationActivate
忠藤、documentAfterActivate
挟伙。自定義事件
用戶自己創(chuàng)建并發(fā)送的 CEP 事件。ExtendScript 事件
也是宿主活動產生的事件,但與前 1 種并不一樣尖阔,你不能從某個類型(type)來識別和捕獲這種事件贮缅,而必須注冊要監(jiān)聽的事件,并通過com.adobe.PhotoshopJSONCallback
事件集中監(jiān)聽 ExtendScript 事件介却,并自己通過 eventID 判斷接受到的是何種事件谴供。
可以說 ExtendScript 事件是另一套事件系統(tǒng),而它實際上通過 CEP 事件來傳遞齿坷。
監(jiān)聽事件
監(jiān)聽事件需要 csInterface.js
前幾期已經提到過了桂肌,不在繁述。
通過csInterface.js
提供的 addEventListener(type,function)
把一個方法綁定給一種事件永淌,每當這種事件發(fā)生崎场,就調用這個方法,并傳遞此次事件的 Event 對象遂蛀。
Event 對象的屬性在前面已經說過了谭跨, event.data
屬性中會有事件的信息,如果是宿主程序事件一般是 XML 字符串李滴,而 ExtendScript 事件是 JSON 字符串螃宙。
下面這個示例把方法 PSCallback()
綁定給了 documentAfterActivate
(文檔被激活)事件,當 PhotoShop 中切換到某個文檔時就會收到調用PSCallback()
所坯,并且傳遞事件對象谆扎,通過訪問事件對象的 .data
屬性會得到類似這樣的數據:"<documentAfterActivate><name>2個VM差別</name><url>file:///E:/工作/Adobe 擴展開發(fā)/2 個 VM 差別.psd</url></documentAfterActivate>"
var cs = new CSInterface();
cs.addEventListener("documentAfterActivate" , PSCallback); //applicationActivate : 文檔被激活
function PSCallback(event) //處理事件的函數,會接受到一個 Event 對象
{
alert(event.data);/*** <documentAfterActivate><name>2個VM差別</name><url>file:///E:/工作/Adobe 擴展開發(fā)/2 個 VM 差別.psd</url></documentAfterActivate> ***/
}
另外 addEventListener()
也支持匿名函數芹助,上面的例子可以簡化為
new CSInterface().addEventListener(
"documentAfterActivate", function (event){ alert(event.data) ;}
)
取消監(jiān)聽
通過 removeEventListener( )
可以取消監(jiān)聽綁定
var cs = new CSInterface();
cs.removeEventListener("documentAfterActivate" , PSCallback);
發(fā)送事件
除了監(jiān)聽宿主應用的事件堂湖,我們自己也可以發(fā)送事件
CEP JavaScript 端
通過創(chuàng)建一個 Event 對象再使用 CSInterface 的 dispatchEvent()
方法,就可以發(fā)送一個事件:
var cs = new CSInterface();
var event = new CSEvent(); // 創(chuàng)建一個事件對象
event.type = "com.nullice.event.test"; //設定一個類型名稱
event.scope = "APPLICATION";// 限定在宿主應用范圍內
event.data = " good bye! @whitesincerely "; // 事件要傳遞的信息
cs.dispatchEvent(event); // GO ! 發(fā)送事件
這樣發(fā)送的信息根據事件 type 就能簡單的捕獲状土。
JAX 端
在 JAX 端苗缩,由于 ExtendScript 默認沒有支持事件處理,需要手動載入一個庫:new ExternalObject("lib:\PlugPlugExternalObject")
声诸,載入后就可以通過創(chuàng)建 CSXSEvent() 對象來創(chuàng)建并發(fā)送事件了:
try {
var loadSuccess = new ExternalObject("lib:\PlugPlugExternalObject"); //載入所需對象酱讶,loadSuccess 記錄是否成功載入
} catch (e) {
alert(e);// 如果載入失敗,輸出錯誤信息
}
if (loadSuccess) {
var eventJAX = new CSXSEvent(); //創(chuàng)建事件對象
eventJAX.type = "com.nullice.event.test"; //設定一個類型名稱
eventJAX.data = " (?﹏?) !!!"; // 事件要傳遞的信息
eventJAX.dispatch(); // GO ! 發(fā)送事件
}
以上事件都可以在 CEP 的 JavaScript 中通過下面這個示例代碼監(jiān)聽:
cs.addEventListener("com.nullice.event.test2",
function (Event)
{
alert(Event.type +" : " + Event.data);
}
);
ExtendScript 事件監(jiān)聽
在 PhotoShop 中創(chuàng)建彼乌、移動一個圖層泻肯、復制、粘貼內容等操作產生的事件就屬于 ExtendScript 事件慰照,ExtendScript 事件與不同其他事件灶挟,不能簡單通過事件的 type 來捕捉,而需要注冊想要捕捉的事件后統(tǒng)一捕捉并處理毒租。
ExtendScript eventID
每種 ExtendScript 事件有不同 eventID ,比如創(chuàng)建圖層是 1298866208
, 復制是 1668247673
稚铣。
在 JSX 中有個方法 charIDToTypeID( )
可以把事件名轉換成 eventID ,
charIDToTypeID( "copy" ) // 返回 1668247673
事件名可以在 Adobe 官方文檔:《ADOBE PHOTOSHOP CC 2014 JAVASCRIPT SCRIPTING REFERENCE》
的附錄中找到。
不過我推薦這些事件名和 eventID 的對照表。:
Photoshop Events (CC2015 ver.16)
Photoshop Constants Rosetta Stone
注冊想要監(jiān)聽的 ExtendScript 事件
監(jiān)聽 ExtendScript 事件得先發(fā)送一個com.adobe.PhotoshopRegisterEvent
類型的 CEP 事件惕医,來告訴宿主你要監(jiān)聽的 ExtendScript 事件耕漱。這個 “注冊事件” 的 .data
就填寫你要監(jiān)聽的 ExtendScript 事件的 eventID :
var cs= new CSInterface();
var event = new CSEvent("com.adobe.PhotoshopRegisterEvent", "APPLICATION"); //創(chuàng)建一個“注冊事件”
event.extensionId = cs.getExtensionID(); //設置“注冊事件” extensionId 為你擴展的擴展ID
event.data = "1298866208"; // 想要監(jiān)聽的 ExtendScript 事件 eventID , 這里是創(chuàng)建圖層對象事件: "Mk "=1298866208
cs.dispatchEvent(event); //發(fā)送“注冊事件”,完成注冊
事件綁定 開始監(jiān)聽
注冊完事件抬伺,就可以綁定方法了螟够,通過 cs.addEventListener()
,監(jiān)聽一個 type 為 "com.adobe.PhotoshopJSONCallback + 你的擴展ID"
的事件峡钓,就能接收到 ExtendScript 事件了:
var cs= new CSInterface();
cs.addEventListener("com.adobe.PhotoshopJSONCallback" + cs.getExtensionID(), PSCallback);
可以看到妓笙,所有 ExtendScript 事件都通過這個 "com.adobe.PhotoshopJSONCallback + 你的擴展ID"
的 CEP 事件來接收,ExtendScript 事件對象 JSON 化的字符串被放在 "com.adobe.PhotoshopJSONCallback + 你的擴展ID"
的 .data
中
下面是上面示例代碼中接收的事件的 .data
(為了展示已經格式化能岩,原本沒有換行):
ver1, {
"eventID": 1298866208, "eventData": {
"layerID": 16, "null": {"_ref": "contentLayer"}, "using": {
"_obj": "contentLayer", "shape": {
"_obj": "customShape", "bottom": {"_unit": "distanceUnit", "_value": 73.9907},
"left": {"_unit": "distanceUnit", "_value": 54.9931}, "name": "箭頭 5",
"right": {"_unit": "distanceUnit", "_value": 107.986},
"top": {"_unit": "distanceUnit", "_value": 34.9956}
}, "strokeStyle": {
"_obj": "strokeStyle", "fillEnabled": true, "strokeEnabled": false,
"strokeStyleBlendMode": {"_enum": "blendMode", "_value": "normal"},
"strokeStyleContent": {"_obj": "solidColorLayer", "color": {"_obj": "grayscale", "gray": 0}},
"strokeStyleLineAlignment": {"_enum": "strokeStyleLineAlignment", "_value": "strokeStyleAlignInside"},
"strokeStyleLineCapType": {"_enum": "strokeStyleLineCapType", "_value": "strokeStyleButtCap"},
"strokeStyleLineDashOffset": {"_unit": "pointsUnit", "_value": 0}, "strokeStyleLineDashSet": [],
"strokeStyleLineJoinType": {"_enum": "strokeStyleLineJoinType", "_value": "strokeStyleMiterJoin"},
"strokeStyleLineWidth": {"_unit": "pointsUnit", "_value": 4}, "strokeStyleMiterLimit": 100,
"strokeStyleOpacity": {"_unit": "percentUnit", "_value": 100}, "strokeStyleResolution": 72.009,
"strokeStyleScaleLock": false, "strokeStyleStrokeAdjust": false, "strokeStyleVersion": 2
}, "type": {"_obj": "solidColorLayer", "color": {"_obj": "grayscale", "gray": 33.8823}}
}
}
}
可以看到我們綁定給 "com.adobe.PhotoshopJSONCallback + 你的擴展ID"
事件的方法(例子中的 PSCallback()
)寞宫,需要解析得到的 CEP 事件的 .data
中 JSON 來獲得 ExtendScript 事件,并自己判斷得到的 ExtendScript 事件類型:
function PSCallbackevent)
{
event.data = event.data.replace("ver1,{", "{"); //去掉前綴 “ver1,”
var esEvent = JSON.parse(event.data); //把 JSON 字符串轉換成對象
alert(esEvent.eventID + "\n" + esEvent.eventData); //使用 eventID 屬性判斷事件類型拉鹃,eventData 為事件數據
}
取消監(jiān)聽
要取消一個 ExtendScript 事件的監(jiān)聽淆九,就是要取消其注冊。與注冊基本一樣毛俏,只是這次發(fā)送的是 com.adobe.PhotoshopUnRegisterEvent
類型的消息:
var cs= new CSInterface();
var event = new CSEvent("com.adobe.PhotoshopUnRegisterEvent", "APPLICATION"); //創(chuàng)建一個“取消注冊事件”
event.extensionId = cs.getExtensionID(); //設置“取消注冊事件” extensionId 為你擴展的擴展ID
event.data = "1298866208"; // 要取消注冊事件的 id
cs.dispatchEvent(event); //發(fā)送“取消注冊事件”,取消注冊
至此 CEP 的事件(EVENTS)及其用法已經介紹完了饲窿,接下來會介紹從 JSX 與 CEP JavaScript 之間調用和傳遞數據的各種方法