先日「トプリクス for Photoshop」をリリースし、続きInDesign版を着手したところ何故かカラーテーマを切り替えてもうまくいかないゾ?となったのでいろいろ問題点を試行錯誤して解決してみました。
まずはこんな感じでPhotoshop Pluginのテンプレート「quick-layers-starter」からPhotoshop・InDesign両用のサンプルを作成しました。
HTML
<!DOCTYPE html> <html> <head> <script src="main.js"></script> <link rel="stylesheet" href="styles.css"> </head> <body> <h1 id="title">Layers</h1> <sp-body id="layers"> No layers </sp-body> <footer> <div id="layerIcon"></div> </footer> </body> </html>
CSS
body { padding: 0 16px; } li:before { content: '• '; width: 3em; } #layers { border: 1px solid #808080; border-radius: 4px; padding: 16px; } h1{ color: var(--uxp-host-text-color); border-radius: 10px; padding: 10px; } #layerIcon{ width: 32px; height: 32px; margin-right: 5px; background-image: url("layer/dark.png"); } #layerIcon:hover{ background-image: url("layer/light.png"); } #layerIcon:active{ background-image: url("layer/dark.png"); }
javascript
const {entrypoints} = require("uxp"); const APID=require("uxp").host.name; entrypoints.setup({ panels: { vanilla: { show(node) { } } } }); document.getElementById("layerIcon").addEventListener("click",async function(){ let allLayerNames; if(APID=="InDesign"){ const allLayers = require("indesign").app.activeDocument.layers; let al=[]; for(let l=0;l<allLayers.length;l++){ al.push(allLayers.item(l).name); } allLayerNames = al.map(layer => layer); }else{ const app = require("photoshop").app; const allLayers = app.activeDocument.layers; allLayerNames = allLayers.map(layer => layer.name); }; const sortedNames = allLayerNames.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); document.getElementById("layers").innerHTML = ` <ul>${ sortedNames.map(name => `<li>${name}</li>`).join("") }</ul>`; });
※manifest.jsonは割愛
改変したところはInDesign対応にしたのとh1タグを使用、ボタンを画像にしたところです。これをデバッグしてみます。まずはPhotoshop
文字のカラーはちゃんと切り替わります。もちろんこのままでは画像は切り替わりません。でもなんで画像がギザギザ?。
お次はInDesignでデバッグ
bodyタグ内にあるh1タグの色が変更されない…。まぁsp-bodyタグ内に配置すればいいんですがね。
スポンサーリンク
まずテーマの切り替えを検知してみた
実は「トプリクス for Photoshop」ではテーマの切り替えを検知して画像を切り替えたりしていました。今回のInDesign用に書くとこんな感じです。
javascript
document.theme.onUpdated.addListener(async(theme)=>{ const btElement=document.getElementById("layerIcon"); const h1Element=document.getElementById("title"); if(theme=="light" || theme=="lightest"){ h1Element.style.color="#424242"; btElement.style.backgroundImage='url("layer/light.png")'; }else{ h1Element.style.color="#ffffff"; btElement.style.backgroundImage='url("layer/dark.png")'; } });
しかし、これだと起動時にどのテーマか分からないのでエラいことになります。それにhover・activeの設定がよくわかりません。動かすとこんな感じです。
一度でも切り替えすれば、上手くいきます。「トプリクス for Photoshop」では切り替えた時のテーマをローカルに保存して次回以降上手くいくようにしていました。
var(–uxp-host-text-color)が効かない問題
まぁまず前提としてUXPでは「Spectrum UXP widgets」というのがありまして頭に「sp」がつくやつです。「sp-label」とか「sp-body」とかですね。
こやつら使用するとテーマを切り替えても問題なく上手いことやってくれます(サンプルのレイヤー名のとこですな)。
しかし「トプリクス」ではツリー表示をするために「aタグ」やら何やらを使用しており「sp」を使用できないのです。
もしかしたら「sp-body」内に作成するようにすれば行けたかもしれませんが…。とにかくInDesign版は何故か
CSS
color: var(--uxp-host-text-color);
が効かないので、起動時に現在のテーマをチェックできないか調べたところ見つからず…。しかし意外なところに解決策はありました。
それはCSSでした
なんと公式の「CSS Reference」のところに「prefers-color-scheme」というモノがありテーマに合わせてCSSで使用できる変数を定義できたのです。
Photoshopで使用できる「–uxp-host-text-color」もデフォルトでこういう感じで定義されていたのか!
ということで今回のサンプルだと
CSS
:root { --uxp-host-font-size: 13px; --uxp-host-font-size-smaller: 12px; --uxp-host-font-size-larger: 14px; --uxp-host-text-color: #ffffff; --uxp-host-border-color: #454545; --uxp-host-background-color: #535353; --layer-png: url("layer/dark.png"); --layer-hover-png: url("layer/light.png"); } @media (prefers-color-scheme: darkest) { :root { --uxp-host-text-color: #ffffff; --uxp-host-border-color: #292929; --uxp-host-background-color: #323232; --layer-png: url("layer/dark.png"); --layer-hover-png: url("layer/light.png"); } } @media (prefers-color-scheme:light) { :root { --uxp-host-text-color: #424242; --uxp-host-border-color: #9c9c9c; --uxp-host-background-color: #b8b8b8; --layer-png: url("layer/light.png"); --layer-hover-png: url("layer/dark.png"); } } @media (prefers-color-scheme: lightest) { :root { --uxp-host-text-color: #4b4b4b; --uxp-host-border-color: #d1d1d1; --uxp-host-background-color: #f0f0f0; --layer-png: url("layer/light.png"); --layer-hover-png: url("layer/dark.png"); } }
こういう感じでrootに定義しました。ちなみに画像以外の定義はPhotoshopのデフォルトを調べて定義しているのでご参考にどうぞ。
使い方はこんな感じです。
CSS
h1{ color: var(--uxp-host-text-color); border-radius: 10px; padding: 10px; } #layerIcon{ width: 32px; height: 32px; margin-right: 5px; background-image: var(--layer-png); } #layerIcon:hover{ background-image: var(--layer-hover-png); } #layerIcon:active{ background-image: var(--layer-hover-png); }
やっと機能開発に専念できる…
これでやっと安心して眠れます。じゃなくてインターフェース関係にストレスがちょっと減って機能開発に重点がおけます。良かった…。
完成したサンプルコードをgitHubのコチラに上げておきました。ご自由にお使いください。
スポンサーリンク
More from my site
スポンサーリンク