告別龐大 PSD,輕鬆測量尺寸

原由

做爲前端工程師,平常開發離不開 psd 文件。javascript

可是平常開發的一個小彈窗頁面,它的 psd 竟然須要 30+Mb,因此常常得按期清理 psd...html

對於我一個 PS 小菜雞來講,用 PSD 無非只是須要用來度量元素大小(元素間距),查看屬性等簡單的功能。前端

思考,對比

相對比於 sketch,sketch 具備 sketch-measure,設計師導出成靜態資源給前端便可。java

對於 PSD 來講,市面上已經有如 pxcook / lanhuapp,體驗也很不錯,可是須要下載 U 同窗提供的 (龐大的) psd 才能進行標註體驗。node

並且有時候仍是須要 U 同窗給(龐大的) PSD 文件,咱們才能在 pxcook / lanhuapp 中自動標註。webpack

因而鑑於以上,考慮作一個開源項目,相似於 sketch-measure, 定位爲 psd-measure。git

效果展現

DEMO
源碼,歡迎 stargithub

命令行

咱們也可使用命令行來導出頁面標註web

bashchrome

npm i measure-export-cli -g
# 開啓服務,在線預覽 `path/to/psdDir` 下的 psd
measure-export start path/to/psdDir
# 構建 `path/to/psdDir` 下的 psd 至 `dist` 文件目錄
measure-export build path/to/psdDir

Chrome 插件

提供 Chrome 插件,當咱們點擊 psd 連接時候跳出 Measure UI,而不是下載 PSD,固然咱們也能夠點擊右上方的下載進行下載。

安裝

  1. 下載擴展,點擊下載
  2. 打開 Chrome 擴展頁面: chrome://extensions/
  3. 拖拽下載的包至頁面中進行安裝
  4. 出現該圖標表示安裝完成

設計與實現

流程以下:

PSD 文件格式介紹

  • File Header(定長) 主要包括這個 psd 文件總體的數據,如版本,尺寸大小,圖片通道數,使用的顏色類別(rgb、cmyk...)
  • Color Mode Data Section(變長) 主要是部分顏色類型圖片須要用到
  • Image Resources(變長) 放置一些外部的圖片資源
  • Layer and Mask(變長) 放置圖層和蒙層的各類信息,大小位置,字體,描邊等等
  • Image Data(變長) 放置圖像像素數據

PSD.js

使用 psd.js 即是解析上述文件結構,獲得可讀的數據結構。
其中 psd.js 使用 getter 獲得懶解析數據,即以下代碼:

const obj = Object.defineProperty({}, 'someParsedVal', {
  get: function () {
    if (!this._someParsedVal) {
      const afterMs = Date.now() + 3000
      while (true) {
        if (Date.now() >= afterMs) {
          this._someParsedVal = 'ok'
          break
        }
      }
    }
    return this._someParsedVal
  }
})

obj.someParsedVal // 3s 後出來
obj.someParsedVal // 很快

在 mobx3 中也有相似的設計(LazyInitializer)

psd-html

將 PSD 解析爲 HAST,進而轉換爲 HTML

HAST (HTML 抽象語法樹)

以下 html:

<a href="http://alpha.com" class="bravo" download></a>

對應 HAST 爲

{
  "type": "element",
  "tagName": "a",
  "properties": {
    "href": "http://alpha.com",
    "id": "bravo",
    "className": ["bravo"],
    "download": true
  },
  "children": []
}

先後端同構

先後端同構的意思:同時運行在客戶端和服務端,具體即是同時執行在瀏覽器環境和 nodejs 環境

實現先後端同構的一些經常使用方式,藉助構建工具 browserify / rollup / webpack 來分別打包不一樣環境的 js

模擬環境
  • 在 nodejs 環境,對於 nodejs built-in modules 不進行打包
  • 在 browser 環境,則將預設的 built-in modules 打包進去,以及一些 global 變量(如 process.env / __dirname)也會進行 mock
利用 變量替換 + treeshake 區分不一樣環境的代碼
  • 如 webpack 配置 DefinePlugin

    {
      plugins: [
        new webpack.DefinePlugin({
          'process.env.RUN_ENV': JSON.stringify('browser')
        })
      ]
    }
  • 在代碼中對不一樣環境打包進行區分

    module.exports =
      process.env.RUN_ENV === 'browser'
        ? {
            psdToHtml,
            psdToHtmlFromBuffer,
            psdToHtmlFromURL,
            psdToHAST,
            psdToHASTFromBuffer
          }
        : {
            psdToHtml,
            psdToHtmlFromPath,
            psdToHtmlFromBuffer,
            psdToHAST,
            psdToHASTFromBuffer,
            psdToHASTFromPath
          }
  • 最終打包出來的 js 則會剔除掉 psdToHASTFromPath 相關代碼
package.json 配置

以下:

{
  "main": "dist/psd-html.cjs.js",
  "browser": "dist/psd-html.browser.cjs.js",
  "cdn": "dist/psd-html.browser.umd.min.js",
  "unpkg": "dist/psd-html.browser.umd.min.js"
}
  • main: nodejs 環境加載的 js
  • browser: browser 環境加載的 js
  • cdn: 部分 cdn 服務加載的 js
  • unpkg: unpkg cdn 服務加載的 js (主要使用 UMD 規範打包)

直接訪問 https://unpkg.com/@moyuyc/psd... 則會重定向至 https://unpkg.com/@moyuyc/psd...{latest-version}/dist/psd-html.browser.umd.min.js

html-measure 交互

佈局定位

將 psd 導出成整個圖片,利用每個圖層的定位和大小來自動標註。

其餘

2 個 div,相對與同一個父級的絕對定位,如何判斷他們是否相交?

.
.
.
.
.
.
.
.
.
.

正面直接判斷是很費力的,要考慮各類狀況,這時候須要逆向思惟,考慮不相交的狀況。
這時候就簡單了

不相交只要知足下面四種狀況之一就能夠

function isIntersect(node1, node2) {
  const rect1 = node1.getBoundingClientRect()
  const rect2 = node2.getBoundingClientRect()
  return !(
    rect1.right < rect2.left ||
    rect1.left > rect2.right ||
    rect1.bottom < rect2.top ||
    rect1.top > rect2.bottom
  )
}

measure-export(-cli)

輸入 psd / html 導出 meas-ui 靜態資源,流程如圖(區分 prod 和 dev 環境)

.svg)

Todo

  • [ ] 提供 chrome 插件:當瀏覽器打開 psd 時候,渲染測量尺寸 UI

相關項目

參考資料

相關文章
相關標籤/搜索