Background#
Today I wanted to submit a few articles to different websites and found that Juejin requires an article banner image, and creating a Juejin article collection also requires an image. Providing images is not a problem, but the main issue is that the sizes are all different and I only have 1:1 images by default.
Strange sizes + repetitive editing work + disposable images that don't need to be saved + consistent style = a template image generation tool.
Currently, I don't need complex drag and drop functionality or diverse materials. It seems that a simple image with background + text + adjustable size will meet the requirements.
So I decided to make one, starting with a simple version and also accumulating some commonly used code.
The current implementation looks like this:
Production Ideas#
- Fix a commonly used template with editable text.
- Use html2canvas (specifically chose an alternative solution) to generate images.
- Avoid different styles and have a variable background.
Technology Selection#
shadcn Style#
The functionality is not complex, so I'll write a form, stack some styles, and generate images. I'm confident in completing the task, so I'll try to learn a tailwind-related component library.
The blog website already uses tailwindcss + varlet components as a whole, so I don't want to reintroduce components related to element-plus/arco-design. The components provided by tailwindcss seem to have little intrusion and should not significantly affect the bundle size.
After browsing my notes, I came across shadcn, which I had already bookmarked. Currently, shadcn-vue is progressing very quickly, with a relatively simple style and radix as a low-level encapsulation, so it should be good. Once the shadcn template library is established, it should be even better.
So I chose shadcn-vue as the component library and started working on it.
It felt a bit awkward at first, but after looking at it for a while, it became more pleasing to the eye. The style is very simple, and I chose the gray style, which is not too dull.
html-to-image Image Generation#
To generate images based on HTML, the famous html2canvas is great. I searched on https://npmtrends.com/ and found that https://github.com/bubkoo/html-to-image is also good. It has a high update frequency, modern documentation style, clear API, so I'll use it.
Dynamic Color hsl#
For the background color, I prefer slightly muted colors. The regular taiwindcss colors don't seem to be enough, so I looked for a solution with the same saturation and brightness but different hues.
I often use this technique in Photoshop to quickly change the overall color by dragging the hue.
This uses the HSB color model, where only the hue needs to be modified. As shown in the following image.
I tried using the filter property, specifically hue-rotate
:
.hue {
filter: hue-rotate(45deg);
}
But it didn't work as expected. Some elements, such as character images, should not be affected by the filter, so it was difficult to achieve the desired effect by individually modifying the background and text.
Instead, I dynamically modified the CSS and found that CSS doesn't have HSB, but it has HSL. So I asked for advice:
Explain the difference between HSB and HSL.
HSB (Hue, Saturation, Brightness) and HSL (Hue, Saturation, Lightness) are two commonly used color models with some differences in how they describe colors. Blah blah blah.
How do they convert?
// 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]
I understood. There are ready-made methods available, and they worked well. +1 for the utility library, and I learned something new.
After some manipulation, I was able to dynamically modify the hue in CSS.
<div :style='{
background: 'hsl(' + config.hue[0] + ',48.1%,48.6%)',
}'>Dynamic Background<div>
In Chrome, it still shows as RGB, but it feels comfortable to use. The color changes as I drag the slider.
I added will-change
and transition
for a smoother color change.
Result#
Outlook#
In the future, I can try to make it a standalone service with customizable images, etc.