辛宝的玄酒清谈!
1368 words
7 minutes
编写一个小工具方便快速为文章添加 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

展望#

后续可以尝试作为独立服务,图片自定义啥的。

编写一个小工具方便快速为文章添加 Banner
https://ijust.cc/posts/add-a-post-banner-tool/
Author
辛宝 Otto
Published at
2023-10-24