Appearance
AE 扩展 - 功能概览
欢迎来到 Eagle2Ae AE 扩展的功能文档中心。这里详细介绍了扩展提供的所有核心功能和高级特性。
📚 功能目录
核心功能
- 多面板支持 - 支持同时打开多个扩展面板实例,每个面板拥有独立配置
- UI 控制系统 - 主题切换、语言切换、组件显示控制等个性化功能
- 拖拽导入增强 - 文件夹拖拽、序列帧检测、项目内文件检测
- 剪贴板导入优化 - 智能剪贴板图片检测和导入
- 项目状态检测器 - 全面的项目状态检测系统
- 虚拟对话框系统 - 演示模式下的虚拟对话框体验
管理系统
模块功能
- 文件夹打开模块 - 文件夹打开功能的核心实现
- 文件夹打开系统升级 - 文件夹打开功能的增强实现
- 图层检测系统升级 - 图层检测功能的增强实现
- 素材分类修复 - 素材分类的修复实现
- 素材分类 - 素材分类的核心实现
🚀 功能亮点
v2.4.0 版本新增功能
- 多面板支持 - 突破单面板限制,支持并行工作流
- UI 控制系统 - 全方位个性化界面定制
- 导入功能增强 - 拖拽和剪贴板导入全面优化
- 状态检测系统 - 确保操作安全性和准确性
- 虚拟对话框系统 - 提供一致的演示模式体验
性能优化
- 智能缓存机制 - 减少重复检测,提高响应速度
- 防抖处理 - 避免频繁操作导致的性能问题
- 内存优化 - 及时清理临时数据,减少内存占用
用户体验改进
- 响应式设计 - 适配不同屏幕尺寸
- 视觉反馈 - 提供实时状态提示
- 错误处理 - 优雅处理各种异常情况
🛠️ 技术实现
架构设计
- 模块化设计 - 功能解耦,便于维护和扩展
- 事件驱动 - 基于事件的通信机制
- 配置管理 - 统一的配置管理系统
- 多面板架构 - 支持同时打开多个扩展面板实例,每个面板拥有独立配置
核心技术
- CEP 扩展技术 - 基于 Adobe CEP 技术栈
- HTTP 轮询通信 - 通过HTTP轮询机制与Eagle插件通信
- ExtendScript 集成 - 与 AE 脚本深度集成
- 现代前端技术 - HTML5、CSS3、ES6+
核心功能实现
多面板支持
支持同时打开多个扩展面板实例,每个面板拥有独立的预设文件和配置。
javascript
// 面板ID识别机制
getPanelId() {
try {
if (this.csInterface && typeof this.csInterface.getExtensionID === 'function') {
const extensionId = this.csInterface.getExtensionID();
// 从 Extension ID 中提取面板编号
if (extensionId.includes('panel1')) {
return 'panel1';
} else if (extensionId.includes('panel2')) {
return 'panel2';
} else if (extensionId.includes('panel3')) {
return 'panel3';
}
}
// Demo 模式:从 URL 参数获取
if (window.location && window.location.search) {
const urlParams = new URLSearchParams(window.location.search);
const panelParam = urlParams.get('panel');
if (panelParam && ['panel1', 'panel2', 'panel3'].includes(panelParam)) {
return panelParam;
}
}
// 默认返回 panel1
return 'panel1';
} catch (error) {
return 'panel1';
}
}UI 控制系统
全新的UI控制系统,支持主题切换、语言切换、组件显示控制等功能。
javascript
// 主题切换实现
applyTheme(theme) {
const root = document.documentElement;
const btn = document.getElementById('theme-toggle-btn');
const iconSpan = btn ? btn.querySelector('.icon') : null;
const isLight = theme === 'light';
// 切换CSS类
root.classList.toggle('theme-light', isLight);
// 保存到localStorage
try {
this.setPanelLocalStorage('aeTheme', isLight ? 'light' : 'dark');
} catch (_) { }
// 更新按钮状态
if (btn) {
btn.setAttribute('aria-pressed', String(isLight));
btn.title = isLight ? '切换为暗色模式' : '切换为亮色模式';
if (iconSpan) iconSpan.textContent = isLight ? '☀️' : '🌙';
}
}
// 语言切换实现
toggleLanguage() {
const currentLang = this.getCurrentLanguage();
const nextLang = currentLang === 'zh-CN' ? 'en-US' : 'zh-CN';
// 更新语言设置
this.updateLanguage(nextLang);
// 保存设置
try {
this.setPanelLocalStorage('language', nextLang);
this.setPanelLocalStorage('lang', nextLang);
} catch (e) {
console.warn('无法保存语言设置:', e);
}
// 更新UI文本
if (this.i18n && typeof this.i18n.updatePageTexts === 'function') {
this.i18n.updatePageTexts();
}
}拖拽导入增强
全面增强的拖拽导入功能,支持文件夹拖拽、序列帧检测等高级特性。
javascript
// 序列帧检测算法
detectImageSequence(files) {
// 只检测图片文件
const imageFiles = files.filter(file => this.getFileCategory(file) === 'image');
if (imageFiles.length < 2) return null;
// 按文件名排序
imageFiles.sort((a, b) => a.name.localeCompare(b.name));
// 尝试找到数字模式
const patterns = [];
for (const file of imageFiles) {
const name = file.name;
const nameWithoutExt = name.substring(0, name.lastIndexOf('.'));
// 查找数字模式 - 支持多种数字格式,优先匹配最后一个数字序列
const numberMatches = nameWithoutExt.match(/(.*?)(\d+)([^\d]*)$/);
if (numberMatches) {
const [, prefix, number, suffix] = numberMatches;
patterns.push({
prefix: prefix || '',
number: parseInt(number),
suffix: suffix || '',
numberLength: number.length,
originalNumber: number,
file
});
}
}
// 找到最一致的模式
const patternGroups = {};
patterns.forEach(p => {
const key = `${p.prefix}_${p.suffix}_${p.numberLength}`;
if (!patternGroups[key]) {
patternGroups[key] = [];
}
patternGroups[key].push(p);
});
// 找到最大的组
let bestGroup = null;
let maxSize = 0;
for (const [key, group] of Object.entries(patternGroups)) {
if (group.length > maxSize) {
maxSize = group.length;
bestGroup = group;
}
}
// 排序并检查连续性
bestGroup.sort((a, b) => a.number - b.number);
const numbers = bestGroup.map(p => p.number);
const start = numbers[0];
const end = numbers[numbers.length - 1];
// 检测步长
let step = 1;
if (numbers.length > 1) {
const diffs = [];
for (let i = 1; i < numbers.length; i++) {
diffs.push(numbers[i] - numbers[i - 1]);
}
// 找到最常见的差值作为步长
const diffCounts = {};
diffs.forEach(diff => {
diffCounts[diff] = (diffCounts[diff] || 0) + 1;
});
let maxCount = 0;
for (const [diff, count] of Object.entries(diffCounts)) {
if (count > maxCount) {
maxCount = count;
step = parseInt(diff);
}
}
}
// 构建模式字符串
const firstPattern = bestGroup[0];
const pattern = `${firstPattern.prefix}[${start}-${end}]${firstPattern.suffix}`;
return {
files: bestGroup.map(p => p.file),
pattern,
start,
end,
step,
totalFiles: bestGroup.length
};
}项目状态检测器
全面的项目状态检测系统,确保操作的安全性和准确性。
javascript
// 项目状态检测器类
class ProjectStatusChecker {
constructor(csInterface, logManager) {
this.csInterface = csInterface;
this.logManager = logManager;
this.cache = new Map();
this.cacheTimeout = 5000; // 5秒缓存超时
this.log('📊 项目状态检测器已初始化', 'debug');
}
/**
* 检测环境
* @returns {Object} 环境检测结果
*/
checkEnvironment() {
const envInfo = {
isCEP: false,
isDemo: false,
hasCSInterface: false,
aeVersion: 'unknown',
cepVersion: 'unknown',
platform: 'unknown'
};
try {
// 检测是否为CEP环境
envInfo.isCEP = typeof window !== 'undefined' &&
typeof window.cep !== 'undefined' &&
typeof window.cep.process !== 'undefined';
// 检测是否为Demo模式
envInfo.isDemo = window.__DEMO_MODE_ACTIVE__ === true ||
(window.demoMode && window.demoMode.state && window.demoMode.state.currentMode !== 'normal');
// 检测CSInterface
envInfo.hasCSInterface = typeof CSInterface !== 'undefined';
// 获取AE版本信息
if (envInfo.hasCSInterface) {
try {
const csInterface = new CSInterface();
const hostEnv = csInterface.getHostEnvironment();
if (hostEnv && hostEnv.appVersion) {
envInfo.aeVersion = hostEnv.appVersion;
}
} catch (error) {
// 忽略获取版本信息的错误
}
}
return envInfo;
} catch (error) {
return { ...envInfo, error: error.message };
}
}
}预设管理系统
每个面板实例独立的预设文件管理,支持导出导入和备份恢复。
javascript
// 预设管理器
class PresetManager {
constructor(panelId, settingsManager, csInterface) {
this.panelId = panelId;
this.settingsManager = settingsManager;
this.csInterface = csInterface;
this.log(`💾 预设管理器已为面板 ${panelId} 初始化`, 'debug');
}
/**
* 获取当前面板的预设文件名
* @returns {string} 'Eagle2Ae1.Presets', 'Eagle2Ae2.Presets', 或 'Eagle2Ae3.Presets'
*/
getPresetFileName() {
const panelNumber = this.panelId.replace('panel', '');
return `Eagle2Ae${panelNumber}.Presets`;
}
}设置管理系统
高级设置管理功能,支持字段监听和自动保存。
javascript
// 设置管理器
class SettingsManager {
constructor(panelId) {
this.panelId = panelId;
this.settings = this.getDefaultSettings();
this.validators = new Map();
this.fieldListeners = new Map();
this.log(`⚙️ 设置管理器已为面板 ${panelId} 初始化`, 'debug');
}
/**
* 添加字段监听器
* @param {string} fieldPath - 字段路径
* @param {Function} listener - 监听器函数
* @param {boolean} once - 是否只监听一次
* @returns {Function} 移除监听器的函数
*/
addFieldListener(fieldPath, listener, once = false) {
if (typeof listener !== 'function') {
throw new Error('监听器必须是函数');
}
if (!this.fieldListeners.has(fieldPath)) {
this.fieldListeners.set(fieldPath, []);
}
this.fieldListeners.get(fieldPath).push(listener);
this.log(`👂 已添加字段 ${fieldPath} 的监听器`, 'debug');
// 返回移除监听器的函数
return () => {
this.removeFieldListener(fieldPath, listener);
};
}
}📖 使用指南
建议按以下顺序阅读功能文档:
入门级功能
进阶级功能
专家级功能
🎯 最佳实践
功能组合使用
- 结合多面板支持和UI控制系统,创建个性化工作环境
- 利用拖拽导入增强和剪贴板导入优化,提高素材处理效率
- 通过项目状态检测器和虚拟对话框系统,确保操作安全性
性能优化建议
- 合理使用缓存机制,避免重复检测
- 适时启用防抖处理,减少不必要的操作
- 定期清理临时数据,保持良好性能
故障排除
- 查看各功能文档中的故障排除章节
- 利用日志系统定位问题
- 参考常见问题解答
请使用左侧导航栏浏览各个功能文档,获取详细信息。