【photoshopJavaScript】レイヤーの順序を逆にする
結論
function reverse_layer_order(document){
for(var index = 0; index < document.layers.length; index++){
if(!document.layers[index]){continue}
var key_layer = document.layers[0]
var target_layer = document.layers[index]
if(key_layer.name === target_layer.name){continue}
if(target_layer.typename == "ArtLayer" && target_layer.isBackgroundLayer == true){continue}
target_layer.move(key_layer, ElementPlacement.PLACEBEFORE)
}
}
こう。「レイヤーを上から順番に最前面に出していけば、最終的に全部ひっくり返るよね」というやり方。
レイヤーの順序を移動するのは、こう。
target_layer.move(key_layer, ElementPlacement.PLACEBEFORE)
何がやりたいかっていうと
こうなっているレイヤー構成を
こうしたいんですね。
えっこれはレイヤーじゃなくてレイヤーセットだ? まあそうなんですけどやることは同じなんで勘弁してください。
やりたいのはフォルダの順序の変更なんですが、記事にするならフォルダの順序変えるよりレイヤーの順序変える方が汎用性高いかなって。
アクティブドキュメントを取得する
var document = app.activeDocument
アプリケーションオブジェクトからアクティブドキュメントを取得します。
アプリケーションオブジェクトはどこかで勝手に「app」という名前でインスタンスが作られていますので、いきなりapp.って書けばアクセスできます。と、言うことを毎回忘れて探します。いきなりapp.って書けばアクセスできます。
アクティブドキュメント内のレイヤー一覧を取得する
var layers = document.layers
でレイヤーの一覧が取れます。
ちなみに、Documentオブジェクトからレイヤーの一覧を取得出来るんですが、取得出来る「レイヤーの一覧っぽいもの」が何種類かあります。
document.artLayers……レイヤーフォルダを除いた、レイヤーのリストが取れる(調整レイヤーはリストに含まれる。ただし、レイヤーフォルダ内のレイヤーは調整レイヤーも含めてリストに含まれない)
document.layers……レイヤーフォルダを含む、全てのレイヤーのリストが取れる(※フォルダ内のレイヤーはLayerSetオブジェクトとして入ってくるので、フォルダ内のレイヤーに対しても全て処理をしたい場合工夫がいる)
document.layerSets……レイヤーフォルダだけのリストが取れる
document.layerComps……レイヤーカンプのリストが取れる。(レイヤーカンプがどんなものかについては調べてください)
用途に応じて取得しましょう。アートレイヤーだけ、とかレイヤーセットだけ、とかをごにょごにょしたいなら、layersで取得してから種類を判断するより、最初からartLayersで取得するのがよいでしょう。
どーーしても取得してから種類を判断して色々やりたいんだけど、という場合は、各要素のtypenameプロパティを取得してあげれば種類が判定できます。
今回はレイヤーセットだけ拾いたいので、サンプルコートでは
var layerSets = document.layerSets
を採用して進めています。
レイヤーリストをforで処理する
for(var index = 0; index < layerSets.length; index++){
$.writeln(layerSets[index])
}
ついついfor...in使いたくなるんですが、for...in使うと、LayerSets(やLayers)が持ってるプロパティのキーまで拾ってしまって不都合なので、大人しく古式ゆかしい方法で回します。
レイヤーを並び替える
レイヤーの類いの並び替えにはmoveメソッドを使います。
target_layer.move(key_layer, ElementPlacement.PLACEBEFORE)
ArtLayer / LayerSet オブジェクトのいずれかに対して、moveメソッドを使います。
が、こいつ結構挙動に癖がありまして、「基準にするレイヤーと、その前に置くか後ろに置くかを指定すると、そのレイヤーの前/後に移動する」という、微妙に痒いところに手が届かない仕様です。直接「一番前!!!」とか「何番目!!!」とか指定できないのよ面倒ね。
と言うわけで、今回は「レイヤーの並び順を逆転させる」ということをやりたいので、「n番目のレイヤーを順番に、【今一番手前にあるレイヤー】の上に重ねる(=最前面に移動する)を繰り返す」という愚直な方法で行きたいと思います。
12345
と並んでいるレイヤーの、2枚目を最前面に移動すると
21345
続いて3枚目を最前面に移動して
32145
…………と繰り返して、最後まで移動すると54321に並び変わるというわけです。
順序指定のための定数について
moveメソッドを使ったレイヤー準入れ替えの際、移動先の指定にはScripting Constans=予め用意されている定数値を使います。
基準のレイヤーの上に重ねたい場合 ElementPlacement.PLACEBEFORE を、基準レイヤーの下に入れたい場合は ElementPlacement.PLACEAFTER を指定します。
ちなみに、ElementPlacementには他にもINSIDEとPLACEATBIGINNING、PLACEATENDというのもあるんですが、使える時と使えない時があります。
INSIDE、PLACEATBIGINNING、PLACEATENDは、「ArtLayerをLayerSet内に移動する」場合にしか使えません。移動させたい対象がレイヤーフォルダの場合はPLACEBEFOREとPLACEAFTERしか使えず、レイヤーフォルダをレイヤーフォルダの中に格納するということはできない模様。(レイヤーパネル上でマウスでドラッグすれば入るのにねー)
最前面のレイヤーを取得する
var key_layer = document.layerSets[0]
document.layerSetsの0番が最前面にあるレイヤーを指します。番号が大きくなるほど背面です。
forで回してn枚目のレイヤーを取得する
for(var index = 0; index < document.layerSets.length; index++){
var key_layer = document.layerSets[0]
var target_layer = document.layerSets[index]
target_layer.move(key_layer, ElementPlacement.PLACEBEFORE)
}
layersやlayerSetsは先述のとおり、for…inで回すには不都合なので、古式ゆかしくindexを一つずつずらして処理します。
このとき、「最前面にあるレイヤー」はレイヤーを一枚移動させる度に変わるので、毎回取得しなおします。
エラー対策
エラーで落ちると悲しいので、紛れ込んでくる可能性の高そうなエラーは対策しておきます。
・layerSets[index]が存在しない(falseになる)場合処理を飛ばす
・レイヤーのtypenameがArtLayerで、かつisBackgroundLayerプロパティがtrueの場合、背景レイヤーなので重ね順の移動できなくてエラーになるので飛ばす
(・基準にするレイヤーと移動したいレイヤーの名前が同じ場合、移動する意味がないので飛ばしてもいい。飛ばさなくてもエラーにはならない)
ってことで、エラー対策を組み込んだ完成形がこちら。
function reverse_layer_order(document){
for(var index = 0; index < document.layers.length; index++){
if(!document.layers[index]){continue}
var key_layer = document.layers[0]
var target_layer = document.layers[index]
if(key_layer.name === target_layer.name){continue}
if(target_layer.typename == "ArtLayer" && target_layer.isBackgroundLayer == true){continue}
target_layer.move(key_layer, ElementPlacement.PLACEBEFORE)
}
}
↑すべてのレイヤーを取得する版
function reverse_layersets_order(document){
for(var index = 0; index < document.layerSets.length; index++){
if(!document.layerSets[index]){continue}
if(document.layerSets[index].typename != "LayerSet"){continue}
var key_layer = document.layerSets[0]
var target_layer = document.layerSets[index]
if(key_layer.name === target_layer.name){continue}
target_layer.move(key_layer, ElementPlacement.PLACEBEFORE)
}
}
↑レイヤーフォルダだけ取得する版
完成!!!お疲れ様でした。
この記事が気に入ったらサポートをしてみませんか?