辛宝Otto

辛宝Otto 的玄酒清谈

北漂前端程序员儿 / 探索新事物 / Web Worker 主播之一/内向话痨
xiaoyuzhou
email

編寫一個小工具方便快速為文章添加 Banner

image.png

背景#

今天想投稿幾篇文章到不同的網站,發現掘金要求提供文章 Banner 圖,創建掘金文章集合也需要提供圖片,提供圖片倒是沒啥,主要是尺寸都不一樣,我默認只有 1:1 的圖片。

奇奇怪怪的尺寸 + 重複勞動編輯 + 隨用隨棄無需保存的圖片 + 風格儘量統一 = 做一個模板圖片生成工具。

目前也不需要複雜的拖拽功能、多樣的素材,看起來簡單的圖片背景 + 文字 + 尺寸可調就滿足要求了。

那就順手做一個,先做一個簡單版本的,也積累一些常用代碼

目前實現的效果長這樣,訪問地址 https://ijust.cc/tools/canvas

image.png

製作思路#

  • 固定一個常用的模板,文字要可以編輯
  • 樣式可以使用 html2canvas (特意使用了一個其他方案) 生成圖片
  • 避免樣式不同,背景可變

技術選型#

shadcn 樣式#

功能不複雜,寫個表單,堆個樣式,生成圖片就可以。對完成任務有信心,所以嘗試困難 i+1,我能不能順手學習的 tailwind 相關的組件庫。

博客的網站已經整體使用 tailwindcss + varlet 組件了,不想重新引入 element-plus/arco-design 相關的組件,看起來 tailwindcss 提供的組件,侵入性不大,打包體積應該影響不大。

翻閱筆記,之前就加入收藏夾的 shadcn 映入眼簾,目前 shadcn-vue 進展特別快,樣式比較簡約,背後依賴 radix 作為低級封裝,應該挺不錯的。後續 shadcn 模板庫起來了,應該也不錯。

這樣選擇 shadcn-vue 作為組件庫,開搞。

用起來稍微有別別扭,看了一會兒也就順眼了,風格很素,我選擇 gray 風格,也沒有特別傻黑。

image.png

html-to-image 生成圖片#

基於 html 生成圖片,大名鼎鼎的 html2canvas 就很不錯,我去 https://npmtrends.com/ 一搜,發現 https://github.com/bubkoo/html-to-image 還不錯,更新頻率高、文檔樣式現代,api 清晰,也拿來用。

動態顏色 hsl#

背景顏色這塊,我習慣稍微素一點的顏色,常規的 taiwindcss colors 感覺還不太夠,我想更自由一點,所以我把目光投向了相同飽和度、亮度,不同色相的思路。

image.png

這一點在 ps 上用的比較多,通過拖動色相,快速改變整體顏色。

image.png

這一塊用到的是 HSB 色彩模型,相同位置,只修改色相就可以。如下圖。

image.png

這樣 hsb 的後兩者就有值了,H 透過滑塊拖動就可以。

第一反應 filter,也就是 hub-rotate

.hue{
  filter: hue-rotate(45deg);
}

實際寫出來不好使,部分元素比如人物形象不參與 filter,做不到,要逐一修改 background 和 text 還挺麻煩。

還是動態修改 css,但我發現 css 裡沒有 hsb 有個 hsl,問問軍師:

介紹 hsb 和 hsl 的區別
HSB (色相、飽和度、亮度) 和 HSL (色相、飽和度、亮度) 是兩種常用的顏色模型,它們在描述顏色的方式上有一些區別。巴拉巴拉

兩者如何轉換?

// HSB to HSL
function hsbToHsl(h, s, b) {
  let l = (2 - s) * b / 2;
  s = s * b / (l < 0.5 ? l * 2 : 2 - l * 2);
  return [h, s, l];
}

// HSL to HSB
function hslToHsb(h, s, l) {
  let v = l + s * (l < 0.5 ? l : 1 - l);
  s = 2 * s / (v + l);
  return [h, s, v];
}

// Example usage
const hsbColor = [0.5, 0.7, 0.8];
const hslColor = hsbToHsl(...hsbColor);
console.log(hslColor); // [0.5, 0.4666666666666667, 0.65]

const convertedHsbColor = hslToHsb(...hslColor);
console.log(convertedHsbColor); // [0.5, 0.7, 0.8]

function hslToRgb(h: number, s: number, l: number) {
  // 將色調值轉換為 0 到 1 之間的小數
  h = h / 360;

  // 飽和度和亮度值為百分比,轉換為 0 到 1 之間的小數
  s = s / 100;
  l = l / 100;

  let r, g, b;

  if (s === 0) {
    // 當飽和度為 0 時,顏色為灰色
    r = g = b = l;
  } else {
    const hue2rgb = (p, q, t) => {
      if (t < 0) t += 1;
      if (t > 1) t -= 1;
      if (t < 1 / 6) return p + (q - p) * 6 * t;
      if (t < 1 / 2) return q;
      if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
      return p;
    };

    const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    const p = 2 * l - q;

    r = hue2rgb(p, q, h + 1 / 3);
    g = hue2rgb(p, q, h);
    b = hue2rgb(p, q, h - 1 / 3);
  }

  // 將 RGB 值轉換為整數,並將值限制在 0 到 255 之間
  r = Math.round(r * 255);
  g = Math.round(g * 255);
  b = Math.round(b * 255);

  // return { r, g, b };
  return `rgb(${r},${g},${b})`;
}

懂了,有現成的方法,試了試好使,工具庫 + 1,學到了點東西。

一番操作,就實現了 css 動態修改 h 色相。

<div :style='{
background: 'hsl(' + config.hue[0] + ',48.1%,48.6%)',
}'>動態背景<div>

chrome 實際運行的時候,還是 rgb,但是用著舒服,拖拽滑塊顏色就改變了。

改變顏色時候順手加個 will-change 和 transition 舒服。

補充:後來順手加了一個 45 度傾斜的線性漸變,from A to B。這裡以色相顏色為 A,對應顏色加一點,+50 得到顏色 B,實際效果也挺不錯。

補充:後來順手加一個低維背景圖,也很好看,用的是

效果#

image.png

image.png

image.png

展望#

後續可以嘗試作為獨立服務,圖片自定義啥的。

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。