Illustratorの文字を1文字ずつ2色へ交互に変更するJSXの例です。オブジェクト全体として選択した1個のテキストフレームだけを対象にし、2色はスウォッチの名前で指定します。文書内で最初に見つかった文字や、スウォッチの並び順で色を決める方式は使いません。
準備と対象範囲
- 文書のコピーを開き、プロセスカラーのスウォッチを「交互_A」「交互_B」の名前で作る。2つの名前は重複させない。
- 選択ツールで、変更したいテキストフレーム1個を選ぶ。文字の編集中の範囲選択や、複数オブジェクトの選択は対象外。
- UTF-8でalternateTextColors.jsxとして保存し、「ファイル」→「スクリプト」→「その他のスクリプト」から実行する。
- 表示された入力欄に2つのスウォッチ名を指定し、変更後の塗り色を確認してから必要なら別名保存する。
対応する色はRGBColor、CMYKColor、GrayColorの単色です。特色、レジストレーション、グラデーション、パターンはこの例では受け付けません。元の色を退避してから割り当てますが、Illustrator全体をまとめて巻き戻すトランザクションではありません。
(function () {
if (app.documents.length === 0) { alert("ドキュメントを開いてください。"); return; }
var doc = app.activeDocument, sel = doc.selection;
if (!sel || sel.length !== 1 || !sel[0] || sel[0].typename !== "TextFrame") {
alert("選択ツールでテキストフレーム全体を1個選んでください。"); return;
}
var frame = sel[0], parent = frame;
while (parent && parent.typename !== "Document") {
if (parent.locked || parent.hidden || (parent.typename === "Layer" && !parent.visible)) {
alert("対象または親がロック・非表示です。"); return;
}
parent = parent.parent;
}
if (!frame.editable) { alert("編集できないテキストです。"); return; }
var chars = frame.textRange.characters;
if (chars.length === 0) { alert("文字がありません。"); return; }
var nameA = prompt("1色目のスウォッチ名", "交互_A");
if (nameA === null) { return; }
var nameB = prompt("2色目のスウォッチ名", "交互_B");
if (nameB === null) { return; }
nameA = String(nameA).replace(/^\s+|\s+$/g, "");
nameB = String(nameB).replace(/^\s+|\s+$/g, "");
if (!nameA || !nameB || nameA === nameB) { alert("異なる2つの名前を指定してください。"); return; }
function findColor(name) {
var found = null, count = 0;
for (var n = 0; n < doc.swatches.length; n++) {
if (doc.swatches[n].name === name) { found = doc.swatches[n].color; count++; }
}
if (count !== 1) { throw Error("スウォッチ名が未登録または重複しています:" + name); }
if (found.typename !== "RGBColor" && found.typename !== "CMYKColor" && found.typename !== "GrayColor") {
throw Error("この例は通常のRGB・CMYK・グレーのスウォッチだけを扱います:" + name);
}
return found;
}
var a, b, before = [], i;
try {
a = findColor(nameA); b = findColor(nameB);
for (i = 0; i < chars.length; i++) { before.push(chars[i].characterAttributes.fillColor); }
} catch (e) { alert("変更前の確認で停止しました:" + e); return; }
try {
for (i = 0; i < chars.length; i++) {
chars[i].characterAttributes.fillColor = (i % 2 === 0) ? a : b;
}
alert("文字コレクションの " + chars.length + " 件へ交互の塗り色を指定しました。保存前に表示を確認してください。");
} catch (e) {
var restoreFailed = 0;
for (i = 0; i < before.length; i++) {
try { chars[i].characterAttributes.fillColor = before[i]; } catch (r) { restoreFailed++; }
}
alert("色の変更に失敗しました:" + e + "\n元の色への復帰失敗:" + restoreFailed + " 件。文書を確認してください。自動保存はしません。");
}
}());

どこから1文字と数えるか
textRange.charactersの先頭を1色目にし、コレクションの添字が偶数なら1色目、奇数なら2色目を指定します。空白や改行もコレクションに含まれれば順番へ数えます。結合文字や絵文字について、見た目の1文字とコレクションの1要素が常に一致するとは保証しません。空白を飛ばす、行ごとに先頭色へ戻すなどのルールは実装していません。
この処理は実行時の文字へ塗り色を割り当てるものです。後から文字を追加・削除しても交互の色を自動で並べ直しません。本文が確定してから実行し直すか、編集後も続く表現が必要ならアピアランスなど別の方法を検討してください。
失敗時の扱いと確認結果
途中の割り当てで例外が起きた場合、退避した色へ戻す処理を試み、戻せなかった数を表示します。復元にも失敗する可能性があるため、保存前に文書を確認します。レイヤーや親グループのロック・非表示は勝手に解除しません。
2026年10月3日、Illustrator 30.8.2(64-bit)/Windows 11で、自作のポイント文字「ABCDE」を試験しました。塗り色はRGB(230,30,45)とRGB(25,90,220)が5要素へ交互に割り当てられ、別のテキスト「UNCHANGED」のGrayColor値は処理前と同じ30相当でした。試験用に入力欄と終了通知を固定したハーネスで確認した結果です。CMYK・Grayの入力色、エリア内文字、パス上文字、特殊文字、Macの実機試験は未実施です。
対象なし、複数選択、ロック・非表示、同名スウォッチ、未対応の色、割り当て失敗など19ケースは模擬オブジェクトで確認しました。実機のすべての条件を検証した結果ではありません。
動かし方はJSXの保存・実行、特色とプロセスカラーは色とスウォッチの設定、対象の取得はDOMの基本を参照してください。

コメント