CommunityImagemgithub.com

younglark/photoshop-psjs

Use quando precisar automatizar o Photoshop via scripts UXP standalone (.psjs): escrever, executar, verificar e exportar documentos. Abrange executeAsModal, batchPlay, tokens de arquivo, segurança de ID de documento e diferenças entre .psjs, plugins UXP e ExtendScript/JSX.

O que é photoshop-psjs?

Esta skill descreve como um agente de IA pode controlar o Adobe Photoshop de forma autônoma usando scripts UXP standalone (.psjs). Ela define um conjunto de práticas recomendadas para criar, modificar e exportar documentos do Photoshop de forma confiável, incluindo o uso de `executeAsModal` para operações que alteram estado, `batchPlay` para comandos de ação, e o sistema de arquivos UXP para ler/escrever arquivos sem intervenção manual. A skill enfatiza a segurança operacional, como garantir que o script só modifique o documento alvo (verificando IDs de documento) e que use `dialogOptions: "silent"` em todos os comandos `batchPlay` para evitar janelas de erro bloqueantes. Ela também cobre como iniciar o script via linha de comando no Windows e macOS (com polling do resultado), como lidar com históricos de edição via `suspendHistory`, e como validar a saída (por exemplo, exportando PNG e comparando com uma imagem de ouro usando métricas como ΔE). A skill é indicada para tarefas de automação única (escrever script -> executar -> verificar -> copiar resultados), não para desenvolvimento de plugins UXP permanentes ou para uso com ExtendScript/JSX. Ela também fornece um fluxo de trabalho detalhado para fatiamento de interfaces (slicing), onde o agente prepara materiais, escreve um manifest de componentes e exporta fatias 1x PNG com uma estrutura de layout independente de engine.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/younglark/photoshop-skills/tree/HEAD/skills/photoshop-psjs

Installed? Explore more Imagem skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Usando Scripts UXP (.psjs) para Controlar o Photoshop

Receitas executáveis para agentes: criar, modificar e exportar documentos no Photoshop. Os fatos são divididos em duas categorias:

  • Oficial: da documentação da Adobe UXP, com links no final.
  • Testado: experiência comprovada ao executar .psjs no Windows e macOS, Adobe Photoshop 2026. Itens não verificados são marcados como não verificado e não devem ser tratados como API oficial.

Critério de sucesso: O script escreve um JSON de resultado (contendo done / ok / fatal / errs); apenas o documento alvo especificado pela tarefa é modificado, outros documentos abertos não são afetados; quando o alinhamento de pixels é necessário, exporte PNG e compare com a imagem de ouro usando ΔE/diferença de pixel e itere.

Pare primeiro: A tarefa não especifica qual documento modificar, ou solicita sobrescrever um documento com alterações não salvas pelo usuário sem permissão explícita.


1. Quando Usar / Quando Não Usar

Use .psjs quando:

  • Você precisa do Photoshop para algo que só ele faz: renderizar pixels com efeitos de camada, exportar fatias por camada, usar batchPlay para criar formas/texto/efeitos, salvar resultados como PSD/PNG.
  • Inferir uma lista de fatias de um PSD/PSB, revisar e exportar PNG 1x e um JSON de layout independente de engine: veja a seção 9.
  • O agente precisa executar uma tarefa de uma só vez (escrever script → iniciar → fazer polling do log → copiar artefatos), sem a necessidade de um painel persistente.

Não inicie o Photoshop quando:

  • Apenas leitura da árvore de camadas, nomes, IDs, texto, bounds aproximados: use psd-tools ou ag-psd para analisar offline. Testado: layer_id do psd-tools corresponde a layer.id do UXP, você pode usar a estrutura offline para localizar e deixar apenas a renderização/exportação para o PS. Observe que o bbox do psd-tools não inclui efeitos de camada; os bounds visuais finais ainda precisam ser calculados no PS.

Use um plugin UXP quando:

  • Você precisa de um canal persistente e bidirecional (por exemplo, ponte MCP, painel, WebSocket). Oficial: scripts não têm manifest / painel; Network, LaunchProcess, WebView, IPC não estão disponíveis. Essas capacidades precisam ser implementadas em um plugin com permissões declaradas no manifest.
  • Oficial: você não pode chamar outro .psjs de dentro de um plugin; mas o código UXP de um script geralmente pode ser movido para um plugin e executado.

Use ExtendScript / JSX quando:

  • O alvo é Photoshop 23.5 ou inferior, ou você só pode usar DoJavaScript no Windows COM / do javascript no macOS AppleScript / evalScript no CEP. JSX é ES3, API síncrona, modo de manutenção. Não trate psx.jsx (a biblioteca auxiliar ExtendScript de xbytor) como um runtime.

2. Pontos Oficiais (Lembre-se Destes Primeiro)

  • Scripts UXP independentes estão disponíveis desde o Photoshop 23.5, extensão .psjs. A depuração pode usar o UXP Developer Tool ≥ 1.6, mas a execução de scripts não requer o UDT.
  • Formas oficiais de iniciar: File > Scripts > Browse...; arraste o .psjs para o ícone do Dock (Mac) ou para a área de documento não aberta da janela do Photoshop (Mac/Win); execute um script por meio de uma Action. Duplo clique para abrir foi marcado como "Em breve".
  • Scripts são JS moderno, suportam await de nível superior. Exemplos oficiais e testes dependem disso; não escreva um script que define async main mas nunca a chama com await main() e depois sai imediatamente.
  • Qualquer operação que modifique o documento ou o estado do aplicativo deve ser envolvida em require("photoshop").core.executeAsModal(fn, { commandName }). O commandName aparece na barra de progresso (se o script demorar mais de 2–3 segundos, uma barra de progresso aparece e o usuário pode cancelar).
  • Quando o DOM não é suficiente, use require("photoshop").action.batchPlay(descriptors, options). Os descritores são actionJSON. Oficial: prefira o DOM. Use "Copy As JavaScript" no painel Actions no modo desenvolvedor, ou grave descritores com Plugins > Development > Record Action Commands..., não invente nomes de chave.
  • dialogOptions é escrito no _options de cada descritor, com valores "silent" (padrão, sem pop-up mesmo em caso de erro), "dontDisplay" (geralmente sem pop-up, mas pode mostrar se faltar parâmetros ou houver erro), "display". Testado (PS 2026): o agente DEVE usar "silent". Com "dontDisplay", se o comando falhar, uma caixa de erro bloqueante ainda aparece (por exemplo, O comando "Obter" não está disponível no momento.), e o script espera até que alguém clique em OK; após clicar, ele retorna {_obj:"error", message:"", result:-128} (-128 é o código de cancelamento oficial do usuário). "silent" não exibe pop-up e retorna em cerca de 1–5ms com {_obj:"error", message:"NomeDoScript: O comando "…" não está disponível no momento.", result:-25920}. Anteriormente, { dialogOptions: "dontDisplay" } foi passado como segundo argumento para batchPlay sem erro, mas a tabela de opções oficial não tem essa chave, e não é seguro usar "display" para verificar se funciona. Novo código: coloque dialogOptions no _options do descritor, com valor "silent".
  • Parâmetros ilegais em batchPlay causam rejeição; falhas em tempo de execução (como alvo inexistente) resolvem, retornando {_obj:"error", message, result}. result === -128 significa cancelamento pelo usuário. Sempre verifique o array retornado.
  • Sistema de arquivos: scripts não têm manifest, as permissões são incorporadas ao Photoshop. A documentação oficial de scripting ainda diz: você pode usar o seletor de arquivos e getTemporaryFolder(). getEntryWithUrl / createSessionToken são APIs oficiais do FileSystemProvider (veja a seção 4 para testes).
  • require("uxp").script fornece executionContext, args, setResult(result). O FAQ oficial (na documentação inicial) dizia: a primeira versão não suporta passar argumentos para scripts. Não dependa de argumentos de linha de comando ou script.args para passar a configuração da tarefa; escreva caminhos e parâmetros diretamente no script, ou faça o script ler um JSON adjacente. Testado (Windows / PS 2026, Photoshop.exe script.psjs): script.args é []. Se você passar argumentos CLI extras após o caminho do script, o script não será executado (nenhum arquivo de resultado em 3 minutos), o lançador ainda retorna imediatamente com código de saída 0, stdout sem saída do script. Não passe argumentos CLI extras. setResult pode ser chamado, retorna undefined, e não aparece no código de saída ou stdout do Photoshop.exe. Sempre use um arquivo de resultado.
  • Apenas um script pode ser executado por vez, e um script não pode chamar outro script.
  • executionContext oficial: isCancelled / onCancel para responder ao cancelamento do usuário, reportProgress({ value, commandName }) para atualizar a barra de progresso, hostControl.suspendHistory({ documentID, name }) + resumeHistory(id, commit) para agrupar um lote de modificações em uma única etapa do histórico, facilitando o desfazer para o artista. Testado: isCancelled é booleano; reportProgress pode ser chamado, retorna undefined. suspendHistory({documentID, name}) retorna {historySuspensionID}, resumeHistory(id) combina várias modificações subsequentes em uma única etapa, com o nome aparecendo em doc.historyStates. As chaves enumeráveis de hostControl podem estar vazias; use Object.getOwnPropertyNames. Para ler o histórico, use o DOM (doc.historyStates / doc.activeHistoryState), não batchPlay get historyStatesCount (esse comando não está disponível, veja a seção 7).

3. Inicialização e Polling do Agente (Testado no Windows)

Oficialmente, "passar um .psjs para Photoshop.exe pela linha de comando" não é uma interface documentada. Testado (Windows / Photoshop 2026):

& "C:\Program Files\Adobe\Adobe Photoshop 2026\Photoshop.exe" "D:\work\ps-job\run_job.psjs"
  • Não requer o desktop do Creative Cloud, UDT ou modo desenvolvedor.
  • Se o Photoshop já estiver aberto, o script é executado na instância existente.
  • O lançador retorna imediatamente, o script continua de forma assíncrona no PS. Você DEVE fazer polling do JSON de resultado que o próprio script escreve (recomenda-se incluir done, ok, fatal, errs), e não confiar no código de saída do processo para determinar sucesso ou fracasso.
  • Testado: um script de exportação levou cerca de 18 segundos para exportar 28 fatias de um .psb (cerca de 10 segundos para abrir o arquivo) e escreveu export_log.json.
  • Testado (Windows / PS 2026): A associação de arquivos existe (.psjs=Photoshop.PSJSFileType.200, ftype é Photoshop.exe "%1"). Start-Process script.psjs realmente executa o script e escreve o arquivo de resultado. O agente ainda deve passar explicitamente Photoshop.exe + caminho do script e confiar no arquivo de resultado.
  • Antes de iniciar, verifique se o PS não está com uma caixa de diálogo modal (como o prompt "Recuperar documentos" após uma falha, caixas de salvamento, etc.). Se houver uma caixa de diálogo, o script não será executado conforme o esperado e o polling apenas resultará em timeout; após o timeout, primeiro tire um print da tela do PS para ver a interface, não reexecute cegamente.

Fluxo do agente remoto: Escreva o .psjs no lado do agente → copie para a máquina com Photoshop (apenas diretórios autorizados pelo usuário) → inicie com shell e faça polling do log → copie PNG/PSD/log de volta → compare pixels se necessário.

Exemplo de polling (PowerShell):

$ps = "C:\Program Files\Adobe\Adobe Photoshop 2026\Photoshop.exe"
$script = "D:\work\ps-job\run_job.psjs"
$log = "D:\work\ps-job\job_log.json"
if (Test-Path $log) { Remove-Item $log }
& $ps $script
$deadline = (Get-Date).AddMinutes(10)
do {
  Start-Sleep -Seconds 2
  if (Test-Path $log) {
    $j = Get-Content $log -Raw | ConvertFrom-Json
    if ($j.done) {
      $j | ConvertTo-Json -Depth 8
      if (-not $j.ok) { exit 1 }
      break
    }
  }
  if ((Get-Date) -gt $deadline) { throw "timeout esperando por $log" }
} while ($true)

macOS (testado, Photoshop 2026, Mac mini): Oficialmente, ele diz apenas arrastar para o Dock/Janela; o seguinte comando de linha de comando não é visto na documentação oficial, mas foi testado e funciona:

open -a "Adobe Photoshop 2026" /path/to/run_job.psjs
# Quando .psjs está associado, também: open /path/to/run_job.psjs
  • Inicialização a frio: Se o PS não estiver em execução, open -a retorna em cerca de 0,3 segundos (exit 0), o PS inicia e executa o script automaticamente, levando cerca de 8 segundos para escrever o arquivo de resultado.
  • Inicialização a quente: Se o PS já estiver em execução, o script é executado na instância existente e escreve o resultado em alguns segundos.
  • open xxx.psjs sem -a, usando a associação de arquivos, também executa.
  • getEntryWithUrl("file:/Users/<user>/...") pode escrever arquivos sem seletor.
  • Assim como no Windows: o lançador retorna imediatamente, você deve fazer polling do arquivo de resultado e não adicionar argumentos de linha de comando extras.

Exemplo de polling (zsh):

log=~/ps-job/job_log.json; rm -f "$log"
open -a "Adobe Photoshop 2026" ~/ps-job/run_job.psjs
for i in {1..300}; do [ -f "$log" ] && grep -Eq '"done": ?true' "$log" && break; sleep 2; done
cat "$log"

Veja o script esqueleto em examples/run_job.psjs (await de nível superior, executeAsModal, proteção de ID de documento, arquivo de resultado, try/catch). Testado: Seguindo este esqueleto, ele funciona: escreve done/ok, exporta preview.png, fecha o documento que criou, e os IDs dos outros documentos abertos permanecem inalterados.


4. Acesso a Arquivos

FileSystemProvider oficial: getFileForOpening / getFileForSaving / getFolder, getTemporaryFolder, getEntryWithUrl(url), createEntryWithUrl, createSessionToken(entry).

O _path para batchPlay deve ser um session token, não um caminho de sistema bruto. Documentação oficial: ao usar o DOM do Photoshop (como app.open(file), doc.saveAs.psd(file, …)), você pode passar diretamente uma entrada File/Folder, e o host converte para token automaticamente.

Testado (PS 2026 script, sem seletor):

const fs = require("uxp").storage.localFileSystem;
const root = await fs.getEntryWithUrl("file:/D:/work/ps-job"); // diretório deve existir
const out = await root.createFile("job_log.json", { overwrite: true });
await out.write(JSON.stringify(log, null, 2));

URLs como file:/D:/... funcionam no Windows. A documentação de script ainda garante apenas seletor + diretório temporário; trate "caminho arbitrário, sem seletor" como comportamento testado no PS 2026, e em outras versões faça um teste de fumaca de escrita primeiro. Não use módulos de rede — o ambiente de script oficial os proíbe.


5. Escopo e Segurança do Documento (Obrigatório)

Princípio: O script só modifica o documento alvo especificado pela tarefa. O alvo pode ser um documento criado pelo script ou um PSD existente indicado pela tarefa (iterar sobre um design existente é um cenário comum). Todos os outros documentos abertos não devem ser alterados, salvos ou fechados.

Determinar o conjunto alvo targets:

  • Novo: O ID retornado por app.createDocument() é adicionado a targets.
  • Iterar sobre PSD existente: Localize pelo caminho fornecido pela tarefa. Primeiro, verifique nos app.documents se o documento já está aberto por doc.path; se estiver, use essa instância diretamente (não abra uma segunda cópia); se não estiver, use app.open(entry). Confiar apenas no nome não é confiável (nomes duplicados, cópias "-recuperado"). Priorize o caminho, depois o ID do documento fornecido pela tarefa. Testado: Usar o caminho reutiliza a mesma instância (mesmo ID de documento, não abre uma segunda cópia); após edições não salvas, doc.saved === false; ao usar saveAs(..., true) para salvar uma nova versão, o mtime e o tamanho do arquivo original permanecem inalterados, o documento permanece aberto e ainda aponta para o caminho original. No Windows, doc.path tem o formato D:\work\file.psd. Documentos recuperados (como "xxx-recuperado") podem ter path vazio e saved === false, não sendo encontrados pelo caminho; use o ID do documento fornecido pela tarefa.
  • Documentos temporários (como fatias "Nova camada a partir de") são adicionados a targets e fechados com closeWithoutSaving() após o uso.

Proteção: Antes de qualquer batchPlay, salvamento ou fechamento, verifique se app.activeDocument.id está em targets. Esta verificação cobre apenas descritores que implicitamente se referem ao documento atual; para descritores que escrevem explicitamente { _ref: "document", _id }, esse ID também deve ser verificado. Antes e depois da execução, registre app.documents.map(d => ({ name: d.name, id: d.id, path: d.path })) no log. Testado: Ao usar make em uma camada com { _ref: "document", _id } de um documento não ativo, a camada é criada nesse documento e activeDocument não muda; portanto, IDs explícitos devem ser verificados. No entanto, set não funciona em documentos não ativos (veja a seção 7); para alterar propriedades, primeiro defina app.activeDocument = target e depois set.

Ao modificar um documento existente:

  • Se o documento alvo já está aberto e tem alterações não salvas (oficialmente doc.saved === false), significa que o usuário está editando manualmente. Por padrão, você pode continuar editando (este é o objetivo da iteração), mas não sobrescreva o salvamento, a menos que a tarefa solicite explicitamente; primeiro registre no log que ele estava sujo antes da execução.
  • Use hostControl.suspendHistory para agrupar as modificações do script em uma única etapa do histórico, permitindo que o usuário desfaça tudo com um Ctrl+Z.
  • A estratégia de salvamento depende da tarefa: por padrão, salve como uma nova versão (por exemplo, xxx_v14.psd), preservando o arquivo original; apenas salve diretamente com doc.save() se a tarefa solicitar explicitamente "atualizar no local".
  • Ao final do script, não feche o documento alvo que o usuário já tinha aberto; feche apenas os documentos que o próprio script abriu ou criou e que a tarefa não pede para manter.

Limpeza automática: executionContext.hostControl.registerAutoCloseDocument(docID) oficial fecha automaticamente documentos temporários quando o usuário cancela ou o modal termina; use apenas para documentos criados pelo script. Se o artista precisar continuar editando, primeiro chame unregisterAutoCloseDocument. Não registre fechamento automático para documentos existentes do usuário.


6. Ciclo de Validação

  1. O script exporta PNG (e, opcionalmente, PSD).
  2. No lado do agente, compare com a imagem de ouro (CIEDE2000 ΔE, diferença de pixel, zoom local).
  3. Com base nas diferenças, modifique o script (caminhos, gradientes, estilos de camada) — não edite manualmente no documento aberto do usuário esperando que seja reproduzível.
  4. Reexecute, exporte novamente, compare novamente, até atingir a meta ou explicar a diferença restante.

7. Armadilhas Testadas

  • dialogOptions: "dontDisplay" ainda exibe uma caixa de erro bloqueante quando falha. Cada descritor executado pelo agente DEVE ter _options: { dialogOptions: "silent" }. Se o polling atingir timeout, primeiro verifique se o PS está com uma caixa de erro; não reexecute cegamente. Se houver uma caixa de diálogo, não inicie o próximo script.

  • Leia o histórico usando o DOM, não batchPlay get historyStatesCount. O último retorna "O comando 'Obter' não está disponível no momento." Com dontDisplay, exibe pop-up; com silent, retorna result: -25920. Use doc.historyStates / doc.activeHistoryState.

  • set em um documento não ativo falha ("O comando 'Definir' não está disponível no momento."). Primeiro, defina o alvo como app.activeDocument e depois set. O mesmo make de camada, no entanto, pode funcionar em um documento não ativo sem alternar o documento atual — o _id do documento no descritor deve ser incluído na proteção.

  • Multi-contorno deve usar frameFXMulti (um único pode usar frameFX). Gradiente ao longo da expansão da forma usa gradientType: "shapeburst".

  • innerShadow de chave única é silenciosamente ignorado; ele deve ser escrito como innerShadowMulti: [{ _obj: "innerShadow", ... }]. Após a modificação, leia de volta com get layerEffects para confirmar que a chave realmente está lá.

  • Caminho personalizado: primeiro set workPath, depois make contentLayer. As formas criadas dessa forma geralmente não têm keyOriginType e não são formas em tempo real com cantos arredondados editáveis na barra de propriedades. Para cantos arredondados editáveis, use make contentLayer + shape._obj = "rectangle" / "ellipse" com unitValueQuadVersion: 1 e quatro raios de canto.

  • A fonte é atribuída pelo nome PostScript (por exemplo, textItem.characterStyle.font = "MuseoSansRounded-1000") e deve estar instalada; a instalação pelo usuário é suficiente, não precisa ser em nível de máquina.

  • No descritor RGB, o campo verde é chamado de grain, não green. Não "corrija" este nome.

  • executeAsModal deve ser await. Se você esquecer, o código subsequente continuará sendo executado antes que o modal seja obtido.

  • batchPlay lançará uma exceção se o usuário cancelar; não use catch vazio para engolir o cancelamento, caso contrário o script não parará.

ActionJSON de estilos de camada e formas: veja references/batchplay.md.


8. Fontes de Informação

Oficial:

As seções acima incluem complementos testados, provenientes de trabalhos que usam .psjs para criar componentes de UI em lote e comparar pixels com imagens de ouro; não são padrão Adobe.


9. Fluxo de Trabalho de Slicing do Agente

Divida a interface em PNG 1x que podem ser importados por engines de jogo e produza um JSON de layout intermediário organizado por semântica de componente e independente de engine. Detalhes, schema, nomenclatura, métodos de identificação e testes: veja references/slicing.md. Primeiro, siga a árvore de decisão no início desse documento: Abra o material (incluindo efeitos de camada nos grupos e escolha o modo de efeito para cada parte afetada) → Identifique componentes → Separe peças compartilhadas das que variam com o estado → Diferencie variantes de rascunhos antigos → Registre como missing apenas as peças que realmente variam → Determine se elementos repetidos são reutilizados → Pare na trava de revisão. Scripts e auxiliares Python: examples/export_slices.psjs, examples/slicing_helper.py, examples/naming_rules.example.json, examples/export_config.example.json.

Ambiente Python: Execute o auxiliar com o venv do projeto, não instale pacotes no Python do sistema. Necessário: psd-tools[composite], Pillow, numpy. Para abrir documentos grandes, use o testado PSDImage.open(path, parse_limits=ParseLimits(max_objects=None)) (não adivinhe parâmetros e não defina ParseLimits.max_objects como atributo de classe). Veja slicing.md "Ambiente Python" para detalhes.

Divisão de trabalho: O auxiliar apenas prepara os materiais (imagem completa do estado padrão, recortes camada por camada com IDs, árvore de camadas com camadas ocultas, candidatos a nine-slice). O agente que executa esta skill lê esses materiais e escreve o manifest: componentes, partes, nomes canônicos, tipos, estados e hierarquia. --rules é apenas uma convenção de nomenclatura opcional do projeto. infer ainda pode produzir um rascunho de palavras-chave (draft_manifest.json), mas não substitui o inventário do agente.

Fluxo (não exporte antes da confirmação):

  1. Preparar materiais (offline): prepare. --artboard <nome ou id da prancheta> opcional; omitir processa todas as pranchetas visíveis de nível superior; se não houver pranchetas, processa a tela inteira. A árvore inclui camadas ocultas (marcadas visible). crops/ contém principalmente folhas exportáveis; grupos com efeitos de camada são escritos em group_effects.json e crops_index.json (quando a composição é possível, também há um recorte do grupo), e anexa os parâmetros de efeito effect_params lidos pelo psd-tools (tipo, modo de mesclagem, cor, opacidade, ângulo, distância, tamanho, expansão/contração, posição do contorno). Use o índice para encontrar IDs, não adivinhe nomes de arquivo. Se um grupo ID não tiver um recorte, não mude diretamente para as folhas internas — primeiro verifique se esse grupo tem efeitos. Agrupamentos sem efeitos, camadas vazias ou fora da prancheta: volte para tree.json para determinar; a ausência de um recorte não significa estado ausente.
  2. Agente escreve o manifest: Identifique componentes interativos como grupos de guias, barras inferiores, botões, linhas de lista, etc. Separe fundos/highlights/ícones/texto em partes independentes por estado, não cozinhe os estados juntos. Primeiro, veja quais partes no design são compartilhadas entre estados e quais mudam: as compartilhadas vão em shared (nome do arquivo sem sufixo de estado), as que mudam vão em seus respectivos states. Camadas ocultas são consideradas estados alternativos apenas quando o corpo/conteúdo principal é o mesmo, e a diferença é apenas no estilo do estado (luminosidade, contorno, brilho, esquema de cores, etc.); se a mesma posição tem conteúdo ou emblema diferente, trate como rascunho antigo e ignore, não use para substituir o verdadeiro recurso compartilhado e não marque peças compartilhadas como missing. Camadas ocultas que estão na posição do item atualmente selecionado, com o mesmo corpo e apenas com estilo de brilho/destaque, devem ser tratadas como highlight desse estado (o estado selecionado padrão também deve ser incluído); camadas de brilho/balão sobrepostas ao fundo selecionado visível, mesmo com forma diferente, são um highlight sobreposto, não uma substituição — não coloque em uncertain_hidden; apenas quando o conteúdo ou motivo não corresponder, escreva uncertain_hidden (com os recortes de ambos os lados). missing deve ser modelado a partir do item mais completo no mesmo grupo (por exemplo, item selecionado tem base + highlight + label), e cada item irmão que carece de um desses componentes deve ser listado, incluindo o highlight. Uma única linha de lista com estilo especial é apenas uma instância dessa linha; não infira estados ausentes para outras linhas, nem infira um normal ausente para esta linha, a menos que o design tenha conjuntos completos de variantes para cada linha. Ao selecionar o alvo de exportação, verifique se o grupo pai mais próximo do elemento (ou o grupo que representa o elemento) tem efeitos de camada (como sombra projetada). Se o efeito estiver no grupo, mas as folhas internas não tiverem, escolha um effect_mode para essa parte (veja slicing.md "Efeitos de grupo: assar ou renderizar pela engine"): baked (padrão) — layer_id / select_ids usam o ID do grupo, o efeito é assado na imagem, a caixa visível inclui o efeito, a caixa lógica não; engine — select_ids usam as subcamadas, os effect_params do grupo são copiados para engine_effects, renderizados pela engine, a imagem não tem pixels de efeito. Cada parte com efeito escreve uma linha effect_reason. Se as regras do projeto ou o usuário especificarem um modo, siga-o. A única coisa proibida é selecionar apenas subcamadas sem registrar o efeito (o efeito desaparece silenciosamente). Proibido inventar. Elementos repetidos: primeiro determine se são reutilizáveis com base no propósito da UI, no senso comum de UI de jogos (fundos de linha de lista, molduras de avatar, botões do mesmo estilo, medalhas de classificação, ícones de moeda, barras de progresso geralmente são reutilizados; imagens de avatar são conteúdo em tempo de execução e devem ser separadas da moldura e marcadas com placeholder: true; nomes/pontuações/números são texto dinâmico) e nas evidências de reuse_candidates.json: se deve ser reutilizado, exporte uma única imagem e cada instância escreve reuse_of: <nome compartilhado> (o nome compartilhado não inclui número de instância); se não corresponder ao efeito, primeiro suspeite que a decisão está errada e apenas separe as instâncias inconsistentes; se a evidência lógica for forte, mas não corresponder, ou se avatar e moldura estiverem combinados no PSD, escreva em reuse_decisions (evidência, problema, imagens de comparação, opções) e deixe para o usuário decidir; por padrão, exporte separado antes da decisão. Nomeie como modulo_tipo_proposito_estado (minúsculas; peças compartilhadas omitem o segmento de estado). Não use diretamente o nome da camada do PSD. Tipos: image | nine_slice | dynamic_text | art_text.
  3. Trava de revisão: flatten + preview produzem uma prévia anotada e JSON (tags com fx:baked / fx:engine, e efeitos de engine desenham uma faixa estimada para facilitar a mudança de modo pelo usuário durante a revisão; flatten lista partes que perderiam efeitos em effect_issues). O usuário modifica o JSON e confirma; o status permanece pending_review até a confirmação. preview pula caixas delimitadoras invertidas ou vazias com um aviso, não interrompe.
  4. Exportação (.psjs): O script codifica apenas um CONFIG_URL, lê os caminhos do JSON do trabalho. Exporta PNG 1x por layer_id / select_ids: baked seleciona o grupo, o efeito é assado na imagem; engine seleciona as subcamadas e as mescla, a imagem não contém efeitos do grupo. Instâncias com reuse_of exportam apenas uma imagem compartilhada; as outras instâncias registram apenas os bounds. dynamic_text não produz imagem, apenas exporta propriedades de texto; art_text produz imagem.

…

[truncado para tradução]

Habilidades Relacionadas