1. 项目缘起与整体设计思路1.1 为什么会有 artcraft 这个想法做创意工具这些年,我越来越强烈地感受到一个矛盾:市面上要么是功能极其复杂、学习曲线陡峭的专业软件,要么是简单到只能套模板的在线工具,中间那块“既能自由发挥、又不需要啃几百页手册”的地带几乎是空白的。artcraft 这个项目就是冲着这个空白去的。它的核心定位很明确:一个面向创意工作者的轻量级视觉内容创作工具,把常见的图形合成、色彩处理、排版布局、素材管理这几件事整合到一个统一的工作台里,让用户在一个界面内完成从灵感草稿到成品导出的全流程。说白了,就是让你不用在四五个软件之间来回切换、反复导入导出,把精力真正花在创作本身。这个项目适合谁?我总结了三类人:一是独立设计师和插画师,需要快速出图但不想开重型软件;二是内容创作者和自媒体运营,日常要做封面图、海报、社交配图;三是有一定审美基础的产品经理或开发者,需要自己动手做演示素材和界面原型。这三类人的共同特点是:有明确的创作需求,但不想被工具绑架。1.2 整体架构是怎么搭的artcraft 的整体设计遵循一个原则:分层解耦,按需加载。我把整个系统拆成了四个核心层,每一层只跟相邻层打交道,这样后期维护和功能扩展都不会牵一发动全身。第一层是渲染引擎层,负责所有图形绘制、图层合成和实时预览。这一层我选了基于 Canvas 的 2D 渲染方案,而不是 WebGL。原因很实际:artcraft 的目标场景是平面视觉内容,2D 渲染完全够用,而且 Canvas 的兼容性和调试便利性远好于 WebGL。只有在处理大量粒子效果或复杂滤镜时,才会按需启用 WebGL 加速通道。第二层是数据处理层,管理项目文件、图层数据、历史记录和素材库。这里的关键设计是不可变数据结构——每次操作不直接修改原数据,而是生成一份新的状态快照。这样做的好处是撤销/重做变得极其简单,只需要在快照链上前后移动指针就行,不用手动记录每一步的反向操作。第三层是交互控制层,处理鼠标、键盘、触控板的各种输入事件,把它们翻译成具体的操作指令。这一层最复杂的地方在于手势冲突消解——比如双指缩放和画布拖拽在触控板上很容易打架,我花了不少时间调参数才找到一个手感自然的阈值。第四层是导出与集成层,负责把作品输出成 PNG、JPG、SVG、PDF 等格式,以及跟外部工具的数据交换。这一层我特意做了插件化设计,后续要加新格式只需要写一个导出插件注册进去就行。1.3 技术选型背后的取舍选型这件事,我的原则是不追新,只选对的。前端框架我用了 Svelte 而不是 React 或 Vue,很多人觉得意外。理由很简单:artcraft 的交互密度极高,每一帧都可能触发大量状态更新,Svelte 的编译时优化让运行时开销小很多,在低端设备上的流畅度差距肉眼可见。我实测过同样一个拖拽图层的操作,Svelte 版本的帧率比 React 版本稳定高出 15 到 20 帧。状态管理没有引入 Redux 或 MobX 这类库,而是自己写了一个轻量的发布订阅 + 快照机制。核心代码不到 200 行,但完全满足需求,还避免了第三方库带来的包体积膨胀。构建工具用的 Vite,热更新速度飞快,开发体验比 Webpack 好太多。存储方案上,项目文件用JSON + 二进制资源分离的方式。JSON 存图层结构、属性、变换矩阵这些元数据,图片、字体等大文件单独存成二进制并建立索引。这样保存和加载都很快,而且 JSON 部分可以直接用文本编辑器查看和修改,调试起来很方便。这里有个经验:千万不要把所有东西都塞进一个 JSON 里,尤其是 base64 编码的图片。我早期版本就这么干过,结果一个稍微复杂点的项目文件就超过 50MB,加载要等好几秒,用户体验极差。2. 核心功能模块的细节拆解2.1 图层系统:一切创作的基础图层是 artcraft 最核心的概念,所有内容都挂在图层上。我把图层分成了五种类型:位图层、矢量层、文本层、调整层和组层。每种类型有自己的属性和渲染逻辑,但共享同一套变换体系(位置、旋转、缩放、透明度)。位图层就是普通的图片,支持裁剪、蒙版和混合模式。矢量层用来画形状和路径,底层用的是自己实现的一套轻量级路径引擎,支持贝塞尔曲线和布尔运算。文本层除了基本的字体、字号、颜色,还支持字间距、行高、对齐方式和文字变形。调整层比较特殊,它本身不产生内容,而是对下方所有图层施加色彩调整(亮度、对比度、饱和度、曲线等)。组层就是文件夹,用来组织和管理其他图层。图层之间的混合模式是我花心思最多的地方。标准的那套(正片叠底、滤色、叠加、柔光等)都实现了,但真正难的是性能优化。我的做法是:只有当混合模式不是“正常”时,才启用离屏渲染和逐像素计算;正常模式下直接走 Canvas 的原生合成,速度快很多。图层的变换矩阵用 3x3 矩阵表示,支持任意顺序的平移、旋转、缩放组合。这里有个坑:很多人习惯先旋转再缩放,但矩阵乘法不满足交换律,顺序不同结果完全不一样。我在 UI 上把变换拆成了独立的滑块,用户调哪个就应用哪个,内部按固定顺序合成矩阵,避免了混乱。2.2 色彩处理:从拾色器到全局调色色彩是视觉创作的灵魂,artcraft 在色彩处理上下了不少功夫。拾色器支持HSV、RGB、HSL、HEX四种模式切换,还有吸管工具可以从画布任意位置取色。吸管工具的实现有个细节:它取的是合成后的最终颜色,而不是某个图层的原始颜色,这样更符合直觉。全局调色板功能允许用户保存常用颜色,支持分组和命名。调色板数据存在项目文件里,换设备打开也能保持一致。我还加了一个“从图片提取配色”的功能,用中位切分算法把图片的主色调提取出来,生成一组协调的配色方案。这个功能在给客户做方案时特别实用,直接从参考图里提色,省去了手动配色的时间。色彩调整方面,调整层支持亮度/对比度、色相/饱和度/明度、色彩平衡、曲线、色阶这几种常用调整。曲线调整是最复杂的,我用的是单调三次样条插值来保证曲线平滑,控制点可以任意拖动,实时预览没有明显延迟。一个实操心得:做色彩调整时,尽量用调整层而不是直接改图层属性。调整层可以随时开关、调透明度、加蒙版,非破坏性编辑的好处谁用谁知道。我见过太多人直接改图层颜色,改完发现不对想还原,只能一步步撤销,效率极低。2.3 排版与文字:不只是打字文字排版看起来简单,做起来坑最多。artcraft 的文本引擎支持富文本编辑,同一文本层里可以有不同的字体、字号、颜色和样式。底层用的是自己封装的一套文本布局算法,处理换行、对齐、字间距调整这些事。字体管理是个大问题。系统字体、项目内嵌字体、网络字体三种来源要统一管理。我的方案是:项目文件里只存字体引用和子集化后的字形数据,不存完整字体文件。这样项目文件不会因为嵌了几个字体就膨胀到几百 MB。导出时再把用到的字形子集打包进去,保证在其他设备上打开不会缺字。文字变形功能支持弧形、波浪、透视几种预设,也可以自定义路径让文字沿着路径排列。路径文字的实现思路是:先把路径离散成一系列点,计算每个点的切线和法线,然后把每个字符按顺序放到对应位置上并旋转到切线方向。听起来简单,但字符间距和路径曲率的配合需要反复调参才能看起来自然。2.4 素材库与资源管理素材库是 artcraft 区别于普通绘图工具的重要模块。用户可以把自己常用的图片、图标、形状、渐变、样式存进素材库,跨项目复用。素材库分本地库和项目库两级:本地库存在浏览器 IndexedDB 里,跟设备绑定;项目库存在项目文件里,跟着项目走。素材的检索支持标签、颜色、类型多维度筛选。我还加了一个基于感知哈希的相似图片搜索,上传一张图就能找到素材库里视觉上相似的素材。这个功能在素材积累多了之后特别有用,不用再靠记忆去找图。资源导入支持拖拽、粘贴、文件选择三种方式。拖拽导入时有个细节:要区分是导入到当前图层还是新建图层。我的做法是按住 Shift 拖入就新建图层,直接拖入就替换当前图层内容。这个交互逻辑在文档里没写,但用起来很自然,很多用户反馈说“不知不觉就学会了”。3. 实操流程与关键环节实现3.1 从零开始创建一个项目打开 artcraft 后,第一件事是新建项目。新建面板会让你选画布尺寸和背景。尺寸预设里有常用的社交媒体尺寸(各种封面、帖子、故事),也可以自定义。这里有个小设计:尺寸输入框支持直接输入算式,比如输入1920/2会自动算出 960,省去了手动计算的麻烦。画布背景支持纯色、渐变和透明三种。选透明背景时,画布上会显示棋盘格底纹,导出 PNG 时保留透明通道,导出 JPG 时自动填充白色。这个逻辑看似简单,但很多工具处理得不好,要么导出后透明变黑,要么棋盘格被一起导出去。项目创建后,界面分成了四个区域:左侧是工具栏和图层列表,中间是画布,右侧是属性面板,顶部是菜单和快捷操作栏。这个布局是我反复调整后的结果,核心原则是常用功能不超过一次点击,次要功能不超过两次点击。3.2 图层操作的核心流程添加图层的方式有好几种:点工具栏的加号、用快捷键、从素材库拖入、粘贴剪贴板内容。我重点说一下从素材库拖入这个流程,因为它涉及多个模块的协作。当你从素材库拖一张图到画布上时,系统会做这几件事:首先判断拖入位置是否在已有图层范围内,如果是就弹出选项问你是替换还是新建;然后读取素材的元数据(尺寸、格式、色彩空间);接着根据画布尺寸和素材尺寸计算初始缩放比例,默认按“适应画布”缩放,但不超过 100%;最后创建新图层并插入到图层列表的合适位置。整个过程在 100 毫秒内完成,用户感觉不到延迟。图层排序支持拖拽调整,拖拽时会有半透明的预览条指示插入位置。这里有个细节:拖拽到组图层上时会自动放入组内,而不是放在组的前面或后面。这个行为符合大多数人的直觉,但实现时要小心处理事件冒泡,避免拖拽事件被组图层拦截。3.3 变换与对齐的实操细节变换图层时,选中图层后会出现一个包围框,八个角上有控制点。拖拽角点缩放,拖拽边中点单轴缩放,按住 Shift 保持比例,按住 Alt 以中心为基准缩放。旋转是鼠标移到角点外侧变成旋转图标后拖拽,按住 Shift 以 15 度为单位吸附。对齐功能支持相对画布和相对其他图层两种模式。相对画布时,可以把图层对齐到画布的上、下、左、右、水平居中、垂直居中。相对其他图层时,需要先选中多个图层,然后以最后选中的那个为基准对齐。这个“最后选中为基准”的规则要在 UI 上明确提示,否则用户会困惑为什么对齐结果跟预期不一样。分布功能可以把三个以上的图层按等间距排列,支持水平和垂直两个方向。实现时要注意:分布的是图层之间的间距,而不是图层中心点的间距。如果图层尺寸差异很大,这两种算法的结果完全不同。我选的是间距均分,因为视觉上更均匀。3.4 导出与分享的完整链路导出是创作的最后一公里,也是最容易出问题的地方。artcraft 的导出流程是这样的:先选择导出范围(整个画布、选中图层、某个组),再选格式和参数,最后选保存位置。PNG 导出支持透明通道和色彩深度选择(8 位/16 位)。JPG 导出有质量滑块,实时显示预估文件大小。SVG 导出会把矢量图层转成路径,位图图层嵌入为 base64 或者引用外部文件(可选)。PDF 导出支持多页,可以把多个画板合并成一个 PDF。导出时的尺寸缩放是个容易忽略的点。我提供了 0.5x、1x、2x、3x 四档预设,也可以自定义。2x 和 3x 主要用于高清屏适配和印刷场景。这里有个计算细节:缩放后的尺寸要取整,但取整方式会影响最终像素的精确度。我的做法是先用浮点数计算,最后一步再四舍五入,避免中间步骤的累积误差。踩过的坑:早期版本导出 SVG 时,我把所有图层都转成了路径,结果文件巨大而且丢失了文本的可编辑性。后来改成只对矢量层转路径,文本层保留为<text>元素,位图层用<image>嵌入,文件大小直接降了 70%。4. 常见问题与排查技巧实录4.1 性能问题的排查思路artcraft 最常见的性能问题就是画布卡顿,尤其是在图层多、滤镜复杂的时候。排查这类问题,我总结了一个三步法。第一步,打开性能面板看帧率。如果帧率低于 30fps,说明确实有性能瓶颈。第二步,逐个隐藏图层,看是哪个图层导致的。通常是某个大尺寸的位图层加了复杂滤镜,或者某个调整层影响了大量下方图层。第三步,针对问题图层做优化:位图层可以降低预览分辨率,滤镜可以改成“仅在导出时应用”,调整层可以合并到下方图层。还有一个容易被忽略的性能杀手是历史记录。每步操作都存快照,操作多了之后内存占用会飙升。我的做法是限制历史记录最多存 50 步,超过就丢弃最早的。同时,快照只存差异部分而不是完整状态,内存占用能降低 60% 以上。4.2 文件兼容性与数据丢失的预防项目文件在不同版本之间打开时,偶尔会出现属性丢失或渲染异常。根本原因是数据结构变更后没有做向后兼容。我的解决方案是给项目文件加一个版本号,加载时先检查版本,如果低于当前版本就执行一系列迁移函数,把旧数据结构转换成新的。迁移函数要写得非常小心,因为一旦出错就可能导致用户数据损坏。我的做法是:迁移前先备份原始数据,迁移后再校验关键字段是否存在,如果校验失败就回滚到备份并提示用户。这个机制上线后,再也没有收到过数据丢失的反馈。另一个常见问题是字体缺失。项目里用了某款字体,换台电脑打开发现字体变了,排版全乱。解决办法就是前面提到的字体子集化嵌入。但要注意版权问题:只嵌入用到的字形,而且要在项目设置里明确标注字体的授权信息。4.3 交互手感问题的调优经验交互手感是个很玄学的东西,参数差一点感觉就完全不一样。我举几个实际调过的例子。拖拽的惯性:拖拽图层松手后,图层会继续滑行一小段距离然后停下。这个惯性系数我调了十几次,最终定在 0.92。太高了停不下来,太低了感觉拖不动。缩放的吸附阈值:按住 Shift 缩放时,接近 100%、50%、200% 这些常用比例时会自动吸附。吸附的触发范围是 ±3%,这个值也是试出来的。范围太大容易误吸附,太小又感觉不到。旋转的步进:不按 Shift 时自由旋转,按住 Shift 以 15 度步进。但 15 度在精细调整时太粗,所以我又加了一层:按住 Shift + Alt 以 1 度步进。这个组合键在文档里没写,但用过的用户都说好。4.4 常见问题速查表问题现象可能原因排查方法解决方案画布卡顿图层过多或滤镜复杂逐个隐藏图层定位降低预览分辨率或合并图层导出图片模糊导出分辨率设置过低检查导出尺寸和缩放比例提高导出分辨率到 2x 以上文字显示异常字体缺失或子集化错误检查字体引用和嵌入状态重新嵌入字体子集撤销后状态不对快照数据不完整检查历史记录链清除历史记录重新操作文件打不开版本不兼容或数据损坏查看版本号和文件大小用迁移工具转换或从备份恢复颜色偏差色彩空间不一致检查项目色彩配置统一使用 sRGB 色彩空间拖拽无响应事件被其他元素拦截检查元素层级和事件绑定调整 z-index 或事件穿透保存失败存储空间不足或权限问题查看浏览器存储配额清理缓存或更换存储位置这张表里的每一条都是我或用户实际遇到过的,不是凭空编的。尤其是“颜色偏差”那条,我当初被坑了很久,后来才发现是某个滤镜在 sRGB 和 Adobe RGB 之间转换时出了问题。5. 扩展方向与个人实践体会5.1 后续可以怎么扩展artcraft 目前的定位是单机创作工具,但它的架构留了不少扩展口子。最直接的一个方向是协作功能——把项目文件的状态同步到云端,多人同时编辑。技术上可以用 CRDT(无冲突复制数据类型)来解决并发冲突,每个操作都带时间戳和作者标识,合并时自动消解冲突。这个方向我已经在原型阶段验证过可行性,但考虑到复杂度,暂时没有正式上线。另一个方向是模板市场。用户可以把自己做的项目存成模板分享出去,其他人一键套用。模板里可以包含图层结构、样式、调色板,但不包含具体内容。这个功能的关键是模板的版本管理和依赖解析——模板引用的字体、素材要能自动下载或提示用户安装。还有一个我比较看好的方向是AI 辅助创作。不是那种“输入一句话生成一张图”的粗暴方式,而是更细粒度的辅助:比如智能抠图、自动配色建议、排版优化提示、相似素材推荐。这些功能可以在不改变用户创作主导权的前提下,显著提升效率。5.2 我个人的一些实操体会做了这么久 artcraft,最大的体会是:工具的价值不在于功能多,而在于让用户忘记工具的存在。最好的状态是用户脑子里想的是“我要做一个什么样的图”,而不是“这个功能在哪个菜单里”。为了达到这个状态,我在交互上做了大量减法,把很多高级功能藏到了二级菜单或快捷键里,主界面只保留最常用的操作。另一个体会是性能优化永远不嫌早。我早期为了快速出原型,很多地方用了简单粗暴的实现方式,结果后期优化时发现牵一发动全身,改一个地方要动好几个模块。如果重来一次,我会在架构设计阶段就把性能边界定好,比如单个图层最大尺寸、最大图层数量、历史记录上限这些,一开始就写进约束里。最后分享一个小技巧:做创意工具一定要自己高频使用。我每天至少花一个小时用 artcraft 做实际的东西——做封面、做海报、做演示图。只有自己用,才能发现那些“文档里不会写、测试用例覆盖不到”的问题。比如我就是在自己用的时候发现,连续快速切换图层时偶尔会闪一下,后来查出来是渲染队列没有做防抖处理。这种问题,不自己用根本发现不了。
1. 项目缘起与整体设计思路1.1 为什么会有 artcraft 这个想法做创意工具这些年,我越来越强烈地感受到一个矛盾:市面上要么是功能极其复杂、学习曲线陡峭的专业软件,要么是简单到只能套模板的在线工具,中间那块“既能自由发挥、又不需要啃几百页手册”的地带几乎是空白的。artcraft 这个项目就是冲着这个空白去的。它的核心定位很明确:一个面向创意工作者的轻量级视觉内容创作工具,把常见的图形合成、色彩处理、排版布局、素材管理这几件事整合到一个统一的工作台里,让用户在一个界面内完成从灵感草稿到成品导出的全流程。说白了,就是让你不用在四五个软件之间来回切换、反复导入导出,把精力真正花在创作本身。这个项目适合谁?我总结了三类人:一是独立设计师和插画师,需要快速出图但不想开重型软件;二是内容创作者和自媒体运营,日常要做封面图、海报、社交配图;三是有一定审美基础的产品经理或开发者,需要自己动手做演示素材和界面原型。这三类人的共同特点是:有明确的创作需求,但不想被工具绑架。1.2 整体架构是怎么搭的artcraft 的整体设计遵循一个原则:分层解耦,按需加载。我把整个系统拆成了四个核心层,每一层只跟相邻层打交道,这样后期维护和功能扩展都不会牵一发动全身。第一层是渲染引擎层,负责所有图形绘制、图层合成和实时预览。这一层我选了基于 Canvas 的 2D 渲染方案,而不是 WebGL。原因很实际:artcraft 的目标场景是平面视觉内容,2D 渲染完全够用,而且 Canvas 的兼容性和调试便利性远好于 WebGL。只有在处理大量粒子效果或复杂滤镜时,才会按需启用 WebGL 加速通道。第二层是数据处理层,管理项目文件、图层数据、历史记录和素材库。这里的关键设计是不可变数据结构——每次操作不直接修改原数据,而是生成一份新的状态快照。这样做的好处是撤销/重做变得极其简单,只需要在快照链上前后移动指针就行,不用手动记录每一步的反向操作。第三层是交互控制层,处理鼠标、键盘、触控板的各种输入事件,把它们翻译成具体的操作指令。这一层最复杂的地方在于手势冲突消解——比如双指缩放和画布拖拽在触控板上很容易打架,我花了不少时间调参数才找到一个手感自然的阈值。第四层是导出与集成层,负责把作品输出成 PNG、JPG、SVG、PDF 等格式,以及跟外部工具的数据交换。这一层我特意做了插件化设计,后续要加新格式只需要写一个导出插件注册进去就行。1.3 技术选型背后的取舍选型这件事,我的原则是不追新,只选对的。前端框架我用了 Svelte 而不是 React 或 Vue,很多人觉得意外。理由很简单:artcraft 的交互密度极高,每一帧都可能触发大量状态更新,Svelte 的编译时优化让运行时开销小很多,在低端设备上的流畅度差距肉眼可见。我实测过同样一个拖拽图层的操作,Svelte 版本的帧率比 React 版本稳定高出 15 到 20 帧。状态管理没有引入 Redux 或 MobX 这类库,而是自己写了一个轻量的发布订阅 + 快照机制。核心代码不到 200 行,但完全满足需求,还避免了第三方库带来的包体积膨胀。构建工具用的 Vite,热更新速度飞快,开发体验比 Webpack 好太多。存储方案上,项目文件用JSON + 二进制资源分离的方式。JSON 存图层结构、属性、变换矩阵这些元数据,图片、字体等大文件单独存成二进制并建立索引。这样保存和加载都很快,而且 JSON 部分可以直接用文本编辑器查看和修改,调试起来很方便。这里有个经验:千万不要把所有东西都塞进一个 JSON 里,尤其是 base64 编码的图片。我早期版本就这么干过,结果一个稍微复杂点的项目文件就超过 50MB,加载要等好几秒,用户体验极差。2. 核心功能模块的细节拆解2.1 图层系统:一切创作的基础图层是 artcraft 最核心的概念,所有内容都挂在图层上。我把图层分成了五种类型:位图层、矢量层、文本层、调整层和组层。每种类型有自己的属性和渲染逻辑,但共享同一套变换体系(位置、旋转、缩放、透明度)。位图层就是普通的图片,支持裁剪、蒙版和混合模式。矢量层用来画形状和路径,底层用的是自己实现的一套轻量级路径引擎,支持贝塞尔曲线和布尔运算。文本层除了基本的字体、字号、颜色,还支持字间距、行高、对齐方式和文字变形。调整层比较特殊,它本身不产生内容,而是对下方所有图层施加色彩调整(亮度、对比度、饱和度、曲线等)。组层就是文件夹,用来组织和管理其他图层。图层之间的混合模式是我花心思最多的地方。标准的那套(正片叠底、滤色、叠加、柔光等)都实现了,但真正难的是性能优化。我的做法是:只有当混合模式不是“正常”时,才启用离屏渲染和逐像素计算;正常模式下直接走 Canvas 的原生合成,速度快很多。图层的变换矩阵用 3x3 矩阵表示,支持任意顺序的平移、旋转、缩放组合。这里有个坑:很多人习惯先旋转再缩放,但矩阵乘法不满足交换律,顺序不同结果完全不一样。我在 UI 上把变换拆成了独立的滑块,用户调哪个就应用哪个,内部按固定顺序合成矩阵,避免了混乱。2.2 色彩处理:从拾色器到全局调色色彩是视觉创作的灵魂,artcraft 在色彩处理上下了不少功夫。拾色器支持HSV、RGB、HSL、HEX四种模式切换,还有吸管工具可以从画布任意位置取色。吸管工具的实现有个细节:它取的是合成后的最终颜色,而不是某个图层的原始颜色,这样更符合直觉。全局调色板功能允许用户保存常用颜色,支持分组和命名。调色板数据存在项目文件里,换设备打开也能保持一致。我还加了一个“从图片提取配色”的功能,用中位切分算法把图片的主色调提取出来,生成一组协调的配色方案。这个功能在给客户做方案时特别实用,直接从参考图里提色,省去了手动配色的时间。色彩调整方面,调整层支持亮度/对比度、色相/饱和度/明度、色彩平衡、曲线、色阶这几种常用调整。曲线调整是最复杂的,我用的是单调三次样条插值来保证曲线平滑,控制点可以任意拖动,实时预览没有明显延迟。一个实操心得:做色彩调整时,尽量用调整层而不是直接改图层属性。调整层可以随时开关、调透明度、加蒙版,非破坏性编辑的好处谁用谁知道。我见过太多人直接改图层颜色,改完发现不对想还原,只能一步步撤销,效率极低。2.3 排版与文字:不只是打字文字排版看起来简单,做起来坑最多。artcraft 的文本引擎支持富文本编辑,同一文本层里可以有不同的字体、字号、颜色和样式。底层用的是自己封装的一套文本布局算法,处理换行、对齐、字间距调整这些事。字体管理是个大问题。系统字体、项目内嵌字体、网络字体三种来源要统一管理。我的方案是:项目文件里只存字体引用和子集化后的字形数据,不存完整字体文件。这样项目文件不会因为嵌了几个字体就膨胀到几百 MB。导出时再把用到的字形子集打包进去,保证在其他设备上打开不会缺字。文字变形功能支持弧形、波浪、透视几种预设,也可以自定义路径让文字沿着路径排列。路径文字的实现思路是:先把路径离散成一系列点,计算每个点的切线和法线,然后把每个字符按顺序放到对应位置上并旋转到切线方向。听起来简单,但字符间距和路径曲率的配合需要反复调参才能看起来自然。2.4 素材库与资源管理素材库是 artcraft 区别于普通绘图工具的重要模块。用户可以把自己常用的图片、图标、形状、渐变、样式存进素材库,跨项目复用。素材库分本地库和项目库两级:本地库存在浏览器 IndexedDB 里,跟设备绑定;项目库存在项目文件里,跟着项目走。素材的检索支持标签、颜色、类型多维度筛选。我还加了一个基于感知哈希的相似图片搜索,上传一张图就能找到素材库里视觉上相似的素材。这个功能在素材积累多了之后特别有用,不用再靠记忆去找图。资源导入支持拖拽、粘贴、文件选择三种方式。拖拽导入时有个细节:要区分是导入到当前图层还是新建图层。我的做法是按住 Shift 拖入就新建图层,直接拖入就替换当前图层内容。这个交互逻辑在文档里没写,但用起来很自然,很多用户反馈说“不知不觉就学会了”。3. 实操流程与关键环节实现3.1 从零开始创建一个项目打开 artcraft 后,第一件事是新建项目。新建面板会让你选画布尺寸和背景。尺寸预设里有常用的社交媒体尺寸(各种封面、帖子、故事),也可以自定义。这里有个小设计:尺寸输入框支持直接输入算式,比如输入1920/2会自动算出 960,省去了手动计算的麻烦。画布背景支持纯色、渐变和透明三种。选透明背景时,画布上会显示棋盘格底纹,导出 PNG 时保留透明通道,导出 JPG 时自动填充白色。这个逻辑看似简单,但很多工具处理得不好,要么导出后透明变黑,要么棋盘格被一起导出去。项目创建后,界面分成了四个区域:左侧是工具栏和图层列表,中间是画布,右侧是属性面板,顶部是菜单和快捷操作栏。这个布局是我反复调整后的结果,核心原则是常用功能不超过一次点击,次要功能不超过两次点击。3.2 图层操作的核心流程添加图层的方式有好几种:点工具栏的加号、用快捷键、从素材库拖入、粘贴剪贴板内容。我重点说一下从素材库拖入这个流程,因为它涉及多个模块的协作。当你从素材库拖一张图到画布上时,系统会做这几件事:首先判断拖入位置是否在已有图层范围内,如果是就弹出选项问你是替换还是新建;然后读取素材的元数据(尺寸、格式、色彩空间);接着根据画布尺寸和素材尺寸计算初始缩放比例,默认按“适应画布”缩放,但不超过 100%;最后创建新图层并插入到图层列表的合适位置。整个过程在 100 毫秒内完成,用户感觉不到延迟。图层排序支持拖拽调整,拖拽时会有半透明的预览条指示插入位置。这里有个细节:拖拽到组图层上时会自动放入组内,而不是放在组的前面或后面。这个行为符合大多数人的直觉,但实现时要小心处理事件冒泡,避免拖拽事件被组图层拦截。3.3 变换与对齐的实操细节变换图层时,选中图层后会出现一个包围框,八个角上有控制点。拖拽角点缩放,拖拽边中点单轴缩放,按住 Shift 保持比例,按住 Alt 以中心为基准缩放。旋转是鼠标移到角点外侧变成旋转图标后拖拽,按住 Shift 以 15 度为单位吸附。对齐功能支持相对画布和相对其他图层两种模式。相对画布时,可以把图层对齐到画布的上、下、左、右、水平居中、垂直居中。相对其他图层时,需要先选中多个图层,然后以最后选中的那个为基准对齐。这个“最后选中为基准”的规则要在 UI 上明确提示,否则用户会困惑为什么对齐结果跟预期不一样。分布功能可以把三个以上的图层按等间距排列,支持水平和垂直两个方向。实现时要注意:分布的是图层之间的间距,而不是图层中心点的间距。如果图层尺寸差异很大,这两种算法的结果完全不同。我选的是间距均分,因为视觉上更均匀。3.4 导出与分享的完整链路导出是创作的最后一公里,也是最容易出问题的地方。artcraft 的导出流程是这样的:先选择导出范围(整个画布、选中图层、某个组),再选格式和参数,最后选保存位置。PNG 导出支持透明通道和色彩深度选择(8 位/16 位)。JPG 导出有质量滑块,实时显示预估文件大小。SVG 导出会把矢量图层转成路径,位图图层嵌入为 base64 或者引用外部文件(可选)。PDF 导出支持多页,可以把多个画板合并成一个 PDF。导出时的尺寸缩放是个容易忽略的点。我提供了 0.5x、1x、2x、3x 四档预设,也可以自定义。2x 和 3x 主要用于高清屏适配和印刷场景。这里有个计算细节:缩放后的尺寸要取整,但取整方式会影响最终像素的精确度。我的做法是先用浮点数计算,最后一步再四舍五入,避免中间步骤的累积误差。踩过的坑:早期版本导出 SVG 时,我把所有图层都转成了路径,结果文件巨大而且丢失了文本的可编辑性。后来改成只对矢量层转路径,文本层保留为<text>元素,位图层用<image>嵌入,文件大小直接降了 70%。4. 常见问题与排查技巧实录4.1 性能问题的排查思路artcraft 最常见的性能问题就是画布卡顿,尤其是在图层多、滤镜复杂的时候。排查这类问题,我总结了一个三步法。第一步,打开性能面板看帧率。如果帧率低于 30fps,说明确实有性能瓶颈。第二步,逐个隐藏图层,看是哪个图层导致的。通常是某个大尺寸的位图层加了复杂滤镜,或者某个调整层影响了大量下方图层。第三步,针对问题图层做优化:位图层可以降低预览分辨率,滤镜可以改成“仅在导出时应用”,调整层可以合并到下方图层。还有一个容易被忽略的性能杀手是历史记录。每步操作都存快照,操作多了之后内存占用会飙升。我的做法是限制历史记录最多存 50 步,超过就丢弃最早的。同时,快照只存差异部分而不是完整状态,内存占用能降低 60% 以上。4.2 文件兼容性与数据丢失的预防项目文件在不同版本之间打开时,偶尔会出现属性丢失或渲染异常。根本原因是数据结构变更后没有做向后兼容。我的解决方案是给项目文件加一个版本号,加载时先检查版本,如果低于当前版本就执行一系列迁移函数,把旧数据结构转换成新的。迁移函数要写得非常小心,因为一旦出错就可能导致用户数据损坏。我的做法是:迁移前先备份原始数据,迁移后再校验关键字段是否存在,如果校验失败就回滚到备份并提示用户。这个机制上线后,再也没有收到过数据丢失的反馈。另一个常见问题是字体缺失。项目里用了某款字体,换台电脑打开发现字体变了,排版全乱。解决办法就是前面提到的字体子集化嵌入。但要注意版权问题:只嵌入用到的字形,而且要在项目设置里明确标注字体的授权信息。4.3 交互手感问题的调优经验交互手感是个很玄学的东西,参数差一点感觉就完全不一样。我举几个实际调过的例子。拖拽的惯性:拖拽图层松手后,图层会继续滑行一小段距离然后停下。这个惯性系数我调了十几次,最终定在 0.92。太高了停不下来,太低了感觉拖不动。缩放的吸附阈值:按住 Shift 缩放时,接近 100%、50%、200% 这些常用比例时会自动吸附。吸附的触发范围是 ±3%,这个值也是试出来的。范围太大容易误吸附,太小又感觉不到。旋转的步进:不按 Shift 时自由旋转,按住 Shift 以 15 度步进。但 15 度在精细调整时太粗,所以我又加了一层:按住 Shift + Alt 以 1 度步进。这个组合键在文档里没写,但用过的用户都说好。4.4 常见问题速查表问题现象可能原因排查方法解决方案画布卡顿图层过多或滤镜复杂逐个隐藏图层定位降低预览分辨率或合并图层导出图片模糊导出分辨率设置过低检查导出尺寸和缩放比例提高导出分辨率到 2x 以上文字显示异常字体缺失或子集化错误检查字体引用和嵌入状态重新嵌入字体子集撤销后状态不对快照数据不完整检查历史记录链清除历史记录重新操作文件打不开版本不兼容或数据损坏查看版本号和文件大小用迁移工具转换或从备份恢复颜色偏差色彩空间不一致检查项目色彩配置统一使用 sRGB 色彩空间拖拽无响应事件被其他元素拦截检查元素层级和事件绑定调整 z-index 或事件穿透保存失败存储空间不足或权限问题查看浏览器存储配额清理缓存或更换存储位置这张表里的每一条都是我或用户实际遇到过的,不是凭空编的。尤其是“颜色偏差”那条,我当初被坑了很久,后来才发现是某个滤镜在 sRGB 和 Adobe RGB 之间转换时出了问题。5. 扩展方向与个人实践体会5.1 后续可以怎么扩展artcraft 目前的定位是单机创作工具,但它的架构留了不少扩展口子。最直接的一个方向是协作功能——把项目文件的状态同步到云端,多人同时编辑。技术上可以用 CRDT(无冲突复制数据类型)来解决并发冲突,每个操作都带时间戳和作者标识,合并时自动消解冲突。这个方向我已经在原型阶段验证过可行性,但考虑到复杂度,暂时没有正式上线。另一个方向是模板市场。用户可以把自己做的项目存成模板分享出去,其他人一键套用。模板里可以包含图层结构、样式、调色板,但不包含具体内容。这个功能的关键是模板的版本管理和依赖解析——模板引用的字体、素材要能自动下载或提示用户安装。还有一个我比较看好的方向是AI 辅助创作。不是那种“输入一句话生成一张图”的粗暴方式,而是更细粒度的辅助:比如智能抠图、自动配色建议、排版优化提示、相似素材推荐。这些功能可以在不改变用户创作主导权的前提下,显著提升效率。5.2 我个人的一些实操体会做了这么久 artcraft,最大的体会是:工具的价值不在于功能多,而在于让用户忘记工具的存在。最好的状态是用户脑子里想的是“我要做一个什么样的图”,而不是“这个功能在哪个菜单里”。为了达到这个状态,我在交互上做了大量减法,把很多高级功能藏到了二级菜单或快捷键里,主界面只保留最常用的操作。另一个体会是性能优化永远不嫌早。我早期为了快速出原型,很多地方用了简单粗暴的实现方式,结果后期优化时发现牵一发动全身,改一个地方要动好几个模块。如果重来一次,我会在架构设计阶段就把性能边界定好,比如单个图层最大尺寸、最大图层数量、历史记录上限这些,一开始就写进约束里。最后分享一个小技巧:做创意工具一定要自己高频使用。我每天至少花一个小时用 artcraft 做实际的东西——做封面、做海报、做演示图。只有自己用,才能发现那些“文档里不会写、测试用例覆盖不到”的问题。比如我就是在自己用的时候发现,连续快速切换图层时偶尔会闪一下,后来查出来是渲染队列没有做防抖处理。这种问题,不自己用根本发现不了。