Appearance
预设管理系统
概述
Eagle2Ae AE 扩展 v2.4.0 引入了全新的预设管理系统(Preset Management System),该系统支持每个面板实例独立的预设文件管理,提供预设的导出、导入、备份和恢复功能。通过智能的预设管理,用户可以轻松地在不同设备或项目间共享配置。
核心特性
多面板预设隔离
- 每个面板实例拥有独立的预设文件
- 支持面板间配置隔离和共享
- 自动识别面板ID并关联对应预设
智能预设文件命名
- 自动生成面板特定的预设文件名
- 支持描述性的文件命名规范
- 避免预设文件名冲突
自动保存机制
- 配置变更时自动保存到预设文件
- 支持防抖保存,避免频繁写入
- 提供手动保存和强制保存选项
预设导出导入
- 支持预设文件的导出和导入
- 提供JSON格式的预设文件
- 支持批量预设管理
备份与恢复
- 自动创建预设文件备份
- 支持版本化备份管理
- 提供一键恢复功能
跨平台兼容
- 支持Windows和macOS系统
- 兼容不同AE版本的预设格式
- 提供降级兼容处理
使用指南
基本预设管理
查看当前预设
javascript
// 获取当前面板的预设文件名
const presetFileName = aeExtension.getPresetFileName();
console.log(`当前面板预设文件: ${presetFileName}`);
// 查看预设文件路径
const presetPath = aeExtension.getPresetsFilePath();
console.log(`预设文件路径: ${presetPath}`);手动保存预设
javascript
// 手动触发预设保存
await aeExtension.savePresetsSilently();
// 保存预设并显示结果
const saveResult = await aeExtension.savePresetsSilently();
if (saveResult) {
console.log('✅ 预设保存成功');
} else {
console.log('❌ 预设保存失败');
}导出预设文件
javascript
// 导出当前面板预设
await aeExtension.handleExportPresets();
// 或者直接调用导出方法
aeExtension.exportPresetToFile();高级功能
预设文件管理
javascript
// 获取预设目录
const presetsDir = aeExtension.getPresetsBaseFolderPath();
console.log(`预设目录: ${presetsDir}`);
// 确保预设目录存在
await aeExtension.ensurePresetsFolderReady();
// 打开预设目录
await aeExtension.handleOpenPresetsFolder();自定义预设目录
javascript
// 选择自定义预设目录
await aeExtension.handleChoosePresetsDirectory();
// 设置预设目录
aeExtension.settingsManager.updatePreference('presetsDirectory', '/custom/presets/path');批量预设操作
javascript
// 批量导出所有面板预设
const allPanels = ['panel1', 'panel2', 'panel3'];
for (const panelId of allPanels) {
const panelExtension = getPanelExtension(panelId);
if (panelExtension) {
await panelExtension.handleExportPresets();
}
}技术实现
预设文件命名机制
javascript
/**
* 获取面板特定的预设文件名
* @returns {string} 预设文件名,如 'Eagle2Ae1.Presets', 'Eagle2Ae2.Presets'
*/
getPresetFileName() {
// 从面板ID提取编号
const panelNumber = this.panelId.replace('panel', '');
return `Eagle2Ae${panelNumber}.Presets`;
}
/**
* 获取预设文件完整路径
* @returns {string} 预设文件完整路径
*/
getPresetsFilePath() {
const baseFolder = this.getPresetsBaseFolderPath();
const fileName = this.getPresetFileName();
if (baseFolder) {
// 用户自定义目录
return `${baseFolder}\\${fileName}`;
} else {
// 默认目录
if (window.require) {
const path = window.require('path');
const os = window.require('os');
const documentsPath = path.join(os.homedir(), 'Documents');
return path.join(documentsPath, 'Eagle2Ae-Ae', 'presets', fileName);
} else {
// 降级方案
return `我的文档\\Eagle2Ae-Ae\\presets\\${fileName}`;
}
}
}预设保存实现
javascript
/**
* 静默保存预设到JSON(无弹窗与打开文件夹)
* @returns {Promise<boolean>} 是否保存成功
*/
async savePresetsSilently() {
try {
const fileName = this.getPresetFileName();
console.log(`[${this.panelId}] 💾 准备保存预设到文件: ${fileName}`);
const settings = this.settingsManager.getSettings();
const preferences = this.settingsManager.getPreferences();
// 收集所有配置
const exportPayload = {
importSettings: settings,
userPreferences: preferences,
uiSettings: this.getUISettingsFromLocalStorage(),
exportedAt: new Date().toISOString()
};
// Demo 模式:保存到虚拟文件系统
if (window.__DEMO_MODE_ACTIVE__) {
try {
const jsonContent = JSON.stringify(exportPayload, null, 2);
// 保存到虚拟文件系统
if (window.demoFileSystem) {
// 使用面板特定的文件名
const demoFileName = `Eagle2Ae-Ae/presets/${this.getPresetFileName()}`;
const result = window.demoFileSystem.writeFile(
demoFileName,
jsonContent
);
if (result.success) {
this.log(`💾 预设已保存到虚拟文件系统 (${result.size} bytes)`, 'info');
return true;
} else {
throw new Error(result.error);
}
} else {
// 降级:保存到 localStorage
localStorage.setItem('eagle2ae_preset_json', jsonContent);
this.log('💾 预设已保存到浏览器存储 (Demo 模式)', 'info');
return true;
}
} catch (e) {
this.log(`⚠️ Demo 模式保存预设失败: ${e.message}`, 'warning');
return false;
}
}
// CEP 模式:保存到文件系统
// 使用面板特定的文件名
const params = {
fileName: this.getPresetFileName(),
overwrite: true,
jsonData: JSON.stringify(exportPayload, null, 2)
};
const baseFolder = this.getPresetsBaseFolderPath();
if (baseFolder) {
params.baseFolderFsPath = baseFolder;
} else {
params.targetSubFolder = 'Eagle2Ae-Ae\\presets';
}
const result = await this.executeExtendScript('exportImportSettingsToJSON', params);
if (result && result.success) {
this.log('💾 预设已自动保存到文档目录', 'info');
return true;
} else {
const msg = result && result.error ? result.error : '未知错误';
this.log(`⚠️ 自动保存预设失败: ${msg}`, 'warning');
return false;
}
} catch (error) {
this.log(`⚠️ 自动保存预设异常: ${error.message}`, 'warning');
return false;
}
}预设加载实现
javascript
/**
* 从JSON自动读取预设并应用到UI
* @returns {Promise<void>}
*/
async loadPresetsFromDisk() {
try {
const fileName = this.getPresetFileName();
console.log(`[${this.panelId}] 🔎 尝试加载预设文件: ${fileName}`);
this.log(`🔎 ${window.i18n?.getText('logs.tryingToLoadLocalPresets') || 'Trying to load local presets...'}`, 'info');
let parsed = null;
// Demo 模式:从虚拟文件系统加载
if (window.__DEMO_MODE_ACTIVE__) {
try {
let content = null;
// 尝试从虚拟文件系统读取
if (window.demoFileSystem) {
// 使用面板特定的文件名
const demoFileName = `Eagle2Ae-Ae/presets/${this.getPresetFileName()}`;
const result = window.demoFileSystem.readFile(demoFileName);
if (result.success) {
content = result.content;
this.log(`✅ 从虚拟文件系统加载预设 (${result.size} bytes)`, 'info');
}
}
// 降级:从 localStorage 读取
if (!content) {
content = localStorage.getItem('eagle2ae_preset_json');
if (content) {
this.log('✅ 从浏览器存储加载预设 (Demo 模式)', 'info');
}
}
if (content) {
parsed = JSON.parse(content);
} else {
this.log('ℹ️ Demo 模式:未找到保存的预设', 'info');
// 如果预设文件不存在,创建默认预设文件
const fileNameToCreate = this.getPresetFileName();
console.log(`[${this.panelId}] 📝 预设文件不存在,正在创建: ${fileNameToCreate}`);
this.log(`📝 正在创建默认预设文件: ${fileNameToCreate}`, 'info');
const saveResult = await this.savePresetsSilently();
if (saveResult) {
this.log(`✅ 默认预设文件已创建: ${this.getPresetFileName()}`, 'success');
// 应用默认配置到界面
try {
const quickSettingsContainer = document.querySelector('.quick-settings-container');
if (quickSettingsContainer) {
this.updateSettingsUI();
this.loadQuickSettings();
} else {
this.log('⚠️ DOM 未就绪,跳过 UI 更新', 'warning');
}
} catch (uiError) {
this.log(`⚠️ UI 更新失败: ${uiError.message}`, 'warning');
}
} else {
this.log(`⚠️ 创建默认预设文件失败`, 'warning');
}
return;
}
} catch (e) {
this.log(`⚠️ Demo 模式加载预设失败: ${e.message}`, 'warning');
return;
}
} else {
// CEP 模式:从文件系统加载
// 使用面板特定的文件名
const params = { fileName: this.getPresetFileName() };
const baseFolder = this.getPresetsBaseFolderPath();
if (baseFolder) {
params.baseFolderFsPath = baseFolder;
} else {
params.targetSubFolder = 'Eagle2Ae-Ae\\presets';
}
const result = await this.executeExtendScript('readImportSettingsFromJSON', params);
if (!result || !result.success) {
const msg = result && result.error ? result.error : '未找到预设文件';
this.log(`ℹ️ 本地预设不可用:${msg}`, 'info');
// 如果预设文件不存在,创建默认预设文件
const fileNameToCreate = this.getPresetFileName();
console.log(`[${this.panelId}] 📝 预设文件不存在,正在创建: ${fileNameToCreate}`);
this.log(`📝 正在创建默认预设文件: ${fileNameToCreate}`, 'info');
const saveResult = await this.savePresetsSilently();
if (saveResult) {
this.log(`✅ 默认预设文件已创建: ${this.getPresetFileName()}`, 'success');
// 应用默认配置到界面
try {
const quickSettingsContainer = document.querySelector('.quick-settings-container');
if (quickSettingsContainer) {
this.updateSettingsUI();
this.loadQuickSettings();
} else {
this.log('⚠️ DOM 未就绪,跳过 UI 更新', 'warning');
}
} catch (uiError) {
this.log(`⚠️ UI 更新失败: ${uiError.message}`, 'warning');
}
} else {
this.log(`⚠️ 创建默认预设文件失败`, 'warning');
}
return;
}
// 解析 JSON
parsed = typeof result.jsonData === 'string' ? JSON.parse(result.jsonData) : result.jsonData;
}
// 应用配置到设置管理器
if (parsed && parsed.importSettings) {
this.settingsManager.saveSettings(parsed.importSettings);
}
// 应用用户偏好
if (parsed && parsed.userPreferences) {
this.settingsManager.savePreferences(parsed.userPreferences);
}
// 应用 UI 面板组设置
if (parsed && parsed.uiSettings) {
try {
this.setPanelLocalStorage('uiSettings', JSON.stringify(parsed.uiSettings));
this.log('✅ 已恢复 UI 面板组设置', 'info');
} catch (e) {
console.warn('无法保存 uiSettings:', e);
}
}
// 应用语言设置
if (parsed && parsed.language) {
try {
localStorage.setItem('language', parsed.language);
localStorage.setItem('lang', parsed.language);
// 如果 i18n 系统已加载,切换语言
if (window.i18n && typeof window.i18n.setLanguage === 'function') {
window.i18n.setLanguage(parsed.language);
}
this.log(`✅ 已恢复语言设置: ${parsed.language}`, 'info');
} catch (e) {
console.warn('无法应用语言设置:', e);
}
}
// 应用主题设置
if (parsed && parsed.userPreferences && parsed.userPreferences.theme) {
try {
this.setPanelLocalStorage('aeTheme', parsed.userPreferences.theme);
// 如果主题切换函数存在,应用主题
if (typeof this.applyTheme === 'function') {
this.applyTheme(parsed.userPreferences.theme);
}
this.log(`✅ 已恢复主题设置: ${parsed.userPreferences.theme}`, 'info');
} catch (e) {
console.warn('无法应用主题设置:', e);
}
}
// 应用项目旁设置
if (parsed && parsed.projectAdjacentSettings) {
try {
localStorage.setItem('ae_extension_project_adjacent_settings', JSON.stringify(parsed.projectAdjacentSettings));
this.log('✅ 已恢复项目旁复制设置', 'info');
} catch (e) {
console.warn('无法保存项目旁设置:', e);
}
}
// 应用自定义文件夹设置
if (parsed && parsed.customFolderSettings) {
try {
localStorage.setItem('ae_extension_custom_folder_settings', JSON.stringify(parsed.customFolderSettings));
this.log('✅ 已恢复自定义文件夹设置', 'info');
} catch (e) {
console.warn('无法保存自定义文件夹设置:', e);
}
}
// 应用到UI
try {
// 检查关键 DOM 元素是否存在
const quickSettingsContainer = document.querySelector('.quick-settings-container');
if (quickSettingsContainer) {
this.updateSettingsUI();
this.loadQuickSettings();
this.log('✅ 已加载并应用本地预设(包含 UI 设置、语言、主题等)', 'success');
} else {
this.log('⚠️ DOM 未就绪,跳过 UI 更新(配置已加载到内存)', 'warning');
}
} catch (uiError) {
this.log(`⚠️ UI 更新失败: ${uiError.message}`, 'warning');
}
} catch (error) {
this.log(`⚠️ ${(window.i18n?.getText('logs.loadLocalPresetsFailedPrefix') || 'Failed to load local presets:')} ${error.message}`, 'warning');
}
}自动预设同步
javascript
/**
* 设置自动预设同步(监听变更并防抖保存)
*/
setupAutoPresetSync() {
// 防抖计时器
this._presetSaveTimer = null;
const triggerSave = () => {
if (this._presetSaveTimer) clearTimeout(this._presetSaveTimer);
this._presetSaveTimer = setTimeout(() => {
this.savePresetsSilently();
}, 600); // 600ms 防抖延迟
};
// 监听设置、导出设置、偏好与自动保存事件
this.settingsManager.addListener((type) => {
if (['settings', 'exportSettings', 'preferences', 'autoSave'].includes(type)) {
triggerSave();
}
});
}预设目录管理
javascript
/**
* 获取当前预设目录(用户自定义的绝对路径),如果未设置则返回null
* @returns {string|null}
*/
getPresetsBaseFolderPath() {
try {
if (this.settingsManager && typeof this.settingsManager.getPreference === 'function') {
const p = this.settingsManager.getPreference('presetsDirectory');
if (p && typeof p === 'string' && p.trim() !== '') return p;
}
} catch (e) {
this.log(`⚠️ 获取预设目录失败:${e.message}`, 'warning');
}
return null;
}
/**
* 确保预设目录存在(启动时调用)
* @returns {Promise<void>}
*/
async ensurePresetsFolderReady() {
// Demo 模式:虚拟文件系统不需要创建目录
if (window.__DEMO_MODE_ACTIVE__) {
this.log('📁 Demo 模式:使用虚拟文件系统', 'info');
return;
}
try {
const params = {};
const base = this.getPresetsBaseFolderPath();
if (base) {
params.baseFolderFsPath = base;
} else {
params.targetSubFolder = 'Eagle2Ae-Ae\\presets';
}
const result = await this.executeExtendScript('ensurePresetsFolder', params);
if (result && result.success) {
this.log(`📁 预设目录就绪:${result.folderPath}`, 'info');
} else {
const msg = result && result.error ? result.error : '未知错误';
this.log(`⚠️ 创建预设目录失败:${msg}`, 'warning');
}
} catch (e) {
this.log(`⚠️ ${(window.i18n?.getText('logs.ensurePresetDirErrorPrefix') || 'Ensure preset directory error:')} ${e.message}`, 'warning');
}
}预设文件格式
JSON结构示例
json
{
"importSettings": {
"mode": "project_adjacent",
"projectAdjacentFolder": "Eagle_Assets",
"customFolderPath": "",
"addToComposition": true,
"timelineOptions": {
"enabled": true,
"placement": "current_time",
"sequenceInterval": 1.0
},
"fileManagement": {
"keepOriginalName": true,
"addTimestamp": false,
"createTagFolders": false,
"deleteFromEagle": false
},
"exportSettings": {
"mode": "project_adjacent",
"autoCopy": true,
"burnAfterReading": false,
"addTimestamp": false,
"createSubfolders": false,
"projectAdjacentFolder": "Eagle_Assets"
}
},
"userPreferences": {
"communicationPort": 8080,
"theme": "dark",
"language": "zh-CN",
"presetsDirectory": null
},
"uiSettings": {
"theme": true,
"language": true,
"log": true,
"projectInfo": true,
"logPanel": true,
"header": true,
"fullscreen": false
},
"exportedAt": "2025-09-15T10:30:45.123Z",
"language": "zh-CN"
}最佳实践
使用建议
定期备份预设
javascript// 建议定期导出预设文件作为备份 setInterval(() => { aeExtension.handleExportPresets(); }, 86400000); // 每24小时自动备份一次跨设备同步
javascript// 将预设文件保存到云同步目录 aeExtension.settingsManager.updatePreference('presetsDirectory', 'C:\\Users\\Username\\OneDrive\\Eagle2Ae\\Presets');团队协作
javascript// 为团队创建标准化预设 const teamPreset = { importSettings: { mode: 'project_adjacent', projectAdjacentFolder: 'Team_Assets', // 统一的团队设置 }, userPreferences: { theme: 'dark', language: 'zh-CN' } }; // 导出团队标准预设供其他成员使用 aeExtension.exportPresetToFile(teamPreset, 'TeamStandard.Presets');
性能优化
防抖保存
javascript// 使用防抖避免频繁保存 const debouncedSave = debounce(() => { aeExtension.savePresetsSilently(); }, 1000); // 1秒防抖 // 在设置变更时调用 settingsManager.addListener(() => { debouncedSave(); });增量保存
javascript// 只保存变更的部分而不是整个预设 function saveChangedSettings(changedSettings) { const currentPresets = aeExtension.getCurrentPresets(); const updatedPresets = { ...currentPresets, importSettings: { ...currentPresets.importSettings, ...changedSettings } }; aeExtension.savePresets(updatedPresets); }
错误处理
保存失败处理
javascript// 处理预设保存失败的情况 async function handlePresetSave() { const saveResult = await aeExtension.savePresetsSilently(); if (!saveResult) { // 保存失败时的降级处理 console.warn('预设保存失败,使用内存中的设置'); // 可以选择: // 1. 提示用户手动保存 // 2. 临时保存到localStorage // 3. 继续使用当前设置而不中断流程 } }加载失败处理
javascript// 处理预设加载失败的情况 async function handlePresetLoad() { try { await aeExtension.loadPresetsFromDisk(); } catch (error) { console.error('预设加载失败:', error); // 降级到默认设置 aeExtension.settingsManager.resetSettings(); aeExtension.loadSettingsToUI(); // 提示用户 aeExtension.showNotification('预设加载失败,已恢复到默认设置', 'warning'); } }
故障排除
常见问题
预设文件丢失
- 症状:设置重置为默认值
- 解决:检查预设目录权限,恢复备份文件
预设保存失败
- 症状:设置变更未保存
- 解决:检查磁盘空间,验证目录权限
跨面板配置冲突
- 症状:不同面板间配置相互影响
- 解决:检查面板ID识别是否正确
调试技巧
启用详细日志
javascript// 在控制台中启用预设管理日志 localStorage.setItem('debugLogLevel', '0');监控预设变更
javascript// 监听预设保存事件 aeExtension.settingsManager.addListener((eventType, data) => { if (eventType === 'autoSave') { console.log('预设自动保存:', data); } });检查预设文件
javascript// 手动检查预设文件内容 async function inspectPresets() { const fileName = aeExtension.getPresetFileName(); const presetPath = aeExtension.getPresetsFilePath(); console.log('预设文件名:', fileName); console.log('预设文件路径:', presetPath); // 读取并解析预设文件 const fileContent = await readFile(presetPath); const presetData = JSON.parse(fileContent); console.log('预设内容:', presetData); }
扩展性
自定义预设格式
javascript
// 扩展预设管理系统以支持自定义格式
class CustomPresetManager extends PresetManager {
constructor() {
super();
this.customFormatHandlers = new Map();
}
// 注册自定义格式处理器
registerFormatHandler(format, handler) {
this.customFormatHandlers.set(format, handler);
}
// 导出自定义格式
async exportCustomFormat(format, data) {
const handler = this.customFormatHandlers.get(format);
if (handler) {
return await handler.export(data);
}
throw new Error(`不支持的格式: ${format}`);
}
// 导入自定义格式
async importCustomFormat(format, fileContent) {
const handler = this.customFormatHandlers.get(format);
if (handler) {
return await handler.import(fileContent);
}
throw new Error(`不支持的格式: ${format}`);
}
}预设版本管理
javascript
// 实现预设版本管理
class PresetVersionManager {
constructor() {
this.versionHistory = [];
}
// 创建预设版本
createVersion(presetData, versionName) {
const version = {
id: Date.now().toString(36),
name: versionName || `版本 ${this.versionHistory.length + 1}`,
data: presetData,
timestamp: new Date().toISOString(),
panelId: aeExtension.panelId
};
this.versionHistory.push(version);
// 限制版本历史数量
if (this.versionHistory.length > 10) {
this.versionHistory.shift();
}
return version;
}
// 恢复到指定版本
async restoreVersion(versionId) {
const version = this.versionHistory.find(v => v.id === versionId);
if (version) {
await aeExtension.settingsManager.saveSettings(version.data.importSettings);
await aeExtension.settingsManager.savePreferences(version.data.userPreferences);
aeExtension.loadSettingsToUI();
return true;
}
return false;
}
}