零基礎的 PhotoShop CEP 6 開發(fā)教程 「 5 」事件(EVENTS)監(jiān)聽/發(fā)起

《零基礎的 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);
        }
    );
在 Adobe ExtendScript Toolkit 中執(zhí)行可以立即看到結果

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 之間調用和傳遞數據的各種方法

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末煌寇,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子逾雄,更是在濱河造成了極大的恐慌阀溶,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸦泳,死亡現場離奇詭異银锻,居然都是意外死亡,警方通過查閱死者的電腦和手機做鹰,發(fā)現死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門击纬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人钾麸,你說我怎么就攤上這事更振。” “怎么了饭尝?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵肯腕,是天一觀的道長。 經常有香客問我钥平,道長实撒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮知态,結果婚禮上捷兰,老公的妹妹穿的比我還像新娘。我一直安慰自己肴甸,他們只是感情好寂殉,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著原在,像睡著了一般友扰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上庶柿,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天村怪,我揣著相機與錄音,去河邊找鬼浮庐。 笑死甚负,一個胖子當著我的面吹牛,可吹牛的內容都是我干的审残。 我是一名探鬼主播梭域,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼搅轿!你這毒婦竟也來了病涨?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤璧坟,失蹤者是張志新(化名)和其女友劉穎既穆,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體雀鹃,經...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡幻工,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了黎茎。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片囊颅。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖傅瞻,靈堂內的尸體忽然破棺而出迁酸,到底是詐尸還是另有隱情,我是刑警寧澤俭正,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布奸鬓,位于F島的核電站,受9級特大地震影響掸读,放射性物質發(fā)生泄漏串远。R本人自食惡果不足惜宏多,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望澡罚。 院中可真熱鬧伸但,春花似錦、人聲如沸留搔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隔显。三九已至却妨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間括眠,已是汗流浹背彪标。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留掷豺,地道東北人捞烟。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像当船,于是被迫代替她去往敵國和親题画。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內容