从 sketch 中获取颜色、字体组件内容

文 /  郁结

在做“智能设计” DSM 平台,DSM 是定义 C 端的设计规范、设计审查、自动生成设计稿的平台。

第一步呢,就是从一份 sketch 文件中,提炼一些“规范库”(包括 颜色、字号、字重)的内容。

从 sketch 中获取颜色、字体组件内容_第1张图片

      (智能设计 - 相关内容定义)

先介绍下 颜色、字体组件

颜色组件:就是可以复用的颜色,可以在“外观”里(参考位置下方截图的绿框)选择和新建

(如果找不到,可以选中一个颜色块,就会展示了)

字体组件:同上,也是可以复用的字体样式,在“外观”(下方绿色框)中选择和新建

(如果找不到,可以选中一个字体内容,就会展示了)

如何从 sketch 中获取呢?

解题思路:

  • 看看可不可以用别人的轮子
  • 查看官方文档

前人造轮子

我查了查轮子,没查到特别好用的(可能是我搜索的姿势不对),下面是我搜的轮子~

大家如果查到好用的,也可以推荐给我~

imgcook 有没有相关的API

操作:人工询问&代码查看

结果:目前只针对了sketch画板做了一定的解析,没有针对颜色和字体的提取API。

sketch to html

介绍:从 sketch 转换成 html,已无更新。

地址:https://github.com/yu-tou/sketch-to-html

结果:没有找到针对颜色和字体的提取API,部分代码思路可以参考

sketch-node-parser

介绍:Parse files from Sketch using pure NodeJS.(用nodejs 转换 sketch)

地址:GitHub - afiedler/sketch-node-parser: Parse files from Sketch using pure NodeJS

结果:没有找到针对颜色和字体的提取API,sketch文件结构解析可以参考

看看官方文档

没办法了~ 看看文档自己写吧!找到的学习网站:sketch developer(英文原版网站)、(中文 较为落后,缺失内容)。

sketch 文件的结构

其实 .sketch 的文件是一个文件集合,改成 .zip 后缀后解压,就可以获取相关的文件。

拿 antd 官方的资源文档举例(我用的是绿框中的文件):

从 sketch 中获取颜色、字体组件内容_第2张图片

解压了上方下载的 AntDesign4.0-Light.sketch 文件后结构如下图:

从 sketch 中获取颜色、字体组件内容_第3张图片

介绍解压后相关的的文件:

  • meta.json:sketch 的元数据(metadata),包括一系列页面(pages) 、 画板(artboards、sketch的版本号、使用的字体(font)。
  • document.json:包括了所有页面的共用数据,比如:分享的样式(shared styles),这些会(用do_objectID字段) 关联到 pages 文件夹中对应的 json 页面。
  • user.json:包含了用户页面的元数据(metadata),如: canvas 视图(viewport)、 每个页面的缩放(zoom)大小、文件是否被上传到 sketch 云空间等。
  • pages 文件夹:文件夹中的每个 json 文件都是一个单独的 skectch 的页面(page)。
  • images 文件夹:包含了所有的在 sketch 中使用的位图(bitmaps),会保持引用时的原位图尺寸(而非修改后的尺寸)
  • previews 文件:包含了一张用户最后编辑的页面的预览。如果小于2048*2048,存原图。大于2048*2048会裁剪成这个长度的矩形图片。

从 sketch 中获取颜色、字体组件内容_第4张图片

(官方文档文件夹介绍)

对照找下官方对于文档(下方截图)的描述( 官方文档原文),认真阅读下,发现共享的数据会存储在document.json 文件中,只要解析document.json 文件就可以获取共享样式(shared styles)。共享样式:包括字体、颜色等。

具体看看 document.json

打开这个43009行的文件,我懵了,整理下后,发现就是这些结构,然后我们需要的就是 layerStyles(颜色)、layerTextStyles(字体),下面为 document.json 的整个内容结构。

从 sketch 中获取颜色、字体组件内容_第5张图片

layerStyles

先说说颜色的结构,找到 object-value-fills-color 里的 rgba - red/green/blue/alpha ,具体layerStyles 的 json 截图如下:

颜色转换 rgba 转 hex

如果还需要rgba 转换成 hex的色值,我刚好也做了,基本网上可以找到很多资料,但是实际测试下来,需要注意的重点是由于数值需要乘255的原因,会有小数的情况,所以使用 Math.round 来四舍五入取整。

直接 show code :

//rgba to hex function
function Rgba2hex(r, g, b, a) {
  r = Math.round(r * 255);
  g = Math.round(g * 255);
  b = Math.round(b * 255);
  r = r.toString(16);
  g = g.toString(16);
  b = b.toString(16);
  a = Math.round(a * 255).toString(16);

  if (r.length == 1) r = "0" + r;
  if (g.length == 1) g = "0" + g;
  if (b.length == 1) b = "0" + b;
  if (a.length == 1) a = "0" + a;

  return r + g + b + a;
}

layerTextStyles

字体的结构,按顺序找到 layerTextStyles - objects - value - textStyle - encodedAttributes

- MSAttributedStringFontAttribute - attributes 获取相关的数值,具体 json 如下:

说说代码思路 & 代码

写下代码思路(下面的流程图,大家可以放大查看):

  1. sketch 文件上传
  2. 二进制流 buffer 读取
  3. 解压 buffer 变成 files
  4. files 中找到 doucment.json ,从 buffer 变成json 内容
  5. 解析 doucment.json , 获取 字体 和 颜色

show code 环节~

import * as JSZip from "jszip";

//二进制流 buffer 读取
function blobToBuffer(file: any) {
  return new Promise((resolve) => {
    let arrayBuffer;
    const fileReader = new FileReader();
    fileReader.onload = (event: any) => {
      arrayBuffer = event?.target?.result;
      resolve(arrayBuffer);
    };
    fileReader.readAsArrayBuffer(file);
  });
}

// buffer 变成json 内容
async function zipFileToJSON(zipFile: any, fileName: any) {
  const text = await zipFile[fileName].async("text");
  const json = JSON.parse(text);
  return json;
}

//解压 buffer 变成 files
async function unZipSketch(buffer: any) {
  const zip = await JSZip.loadAsync(buffer);
  return zip.files;
}


const getRenameAttr = async (file: any, getType: string) => {
  //1.sketch 文件上传
  //2.二进制流 buffer 读取
  const buffer: any = await blobToBuffer(file);

  //3.解压 buffer 变成 files
  const zipFile = await unZipSketch(buffer);

  //4.files 中找到 doucment.json ,从 buffer 变成json 内容
  const docFile = await zipFileToJSON(zipFile, "document.json");

  //5.解析 doucment.json , 获取 字体 和 颜色
  let fontList: any = [];
  //命名 字体 解析
  const fontReferences = docFile?.layerTextStyles?.objects || [];
  for (let index = 0; index < fontReferences.length; index++) {
    const font = fontReferences[index];
    const textStyle =
          font?.value?.textStyle?.encodedAttributes
    ?.MSAttributedStringFontAttribute?.attributes;
    const fontPush = {
      name: font.name,
            fontSize: textStyle?.size,
              fontWeight: textStyle?.name,
    };
    fontList.push(fontPush);
  }

  //命名 颜色 解析
  let colorList: any = [];
  const colorReferences = docFile?.layerStyles?.objects || [];
  for (let index = 0; index < colorReferences.length; index++) {
    const color = colorReferences[index];
    const fill = color?.value?.fills[0].color;
    const { blue, green, red, alpha } = fill;
    // console.log("fill", fill);
    const colorPush = {
      name: color.name,
      value: Rgba2hex(red, green, blue, alpha),
    };
    colorList.push(colorPush);
  }

  let finalList: any = {};
  if (colorList.length > 0) {
    finalList.colorList = colorList;
  }
  if (fontList.length > 0) {
    finalList.fontList = fontList;
  }

  return finalList;
};

附录:

官方插件的学习文档

  • 官方解析工具 CLI 介绍文章(需)
  • 插件参考:开源 | Picasso:sketch设计稿智能解析工具

你可能感兴趣的:(新手入门,sketch相关,前端看设计,sketch,前端,html)