跳到主要内容

· 阅读需 1 分钟
SleepyZone

图层导出 buffer:

import SketchDom from 'sketch/dom';
import UI from 'sketch/ui';

const document = SketchDom.getSelectedDocument();
const { layers, length, isEmpty } = document.selectedLayers;

const layer = layers[0];

const options = { formats: 'png', output: false }
const buffer = SketchDom.export(layer, options);

buffer 上传:

const formData = new FormData();

formData.append('file', {
data: buffer,
fileName: `${Date.now()}.png`,
mimeType: 'image/png'
}, `${Date.now()}_glaze_layer_img.png`);

return fetch(url, { method: 'POST', body: formData })

· 阅读需 4 分钟
SleepyZone

最近在两个项目里分别用了 antd 和 shadcn 两个 react ui 库,又对比了一下国内外的一些组件库,发现两边有一些不一样。

CSS 样式

不得不说老外总是能从一些我们已经不怎么关注的地方卷出一些东西来,Tailwind CSS 出现以后,国外组件库样式方案基本都是这一套了。

我自己尝试了一下,配合 vscode 插件无脑写样式确实挺爽的,虽然 classname 会超长。当然也有方式组合这些原子样式,但那味道就不对了。

因为这些样式最终都是构建到最终产物内,那就肯定是按需使用了😂。类似的 shadcn 组件也是这样用到哪个 install 哪个,还管什么摇树😆,而且组件和样式都暴露给你,随意修改。

再说说 antd,从 classname 过渡到 css in js ,但对使用者来讲并没有什么本质的变化,不过想覆盖样式的时候确实方便了许多。从 antd 里学到了 has where 这些 css 知识。

不过有一点是一致的,css variable 已经是共识了。

表单

都说国内已经搞大而全的超级 app,组件库也一样。通常表单都会附带一个表单实例,这个实例可以管理各个表单组件的 value onChange,负责收集表单组件的数据以及给表单组件赋值。同时会贴心的提供数组类型的表单,联动也会支持。我用的反正挺爽的。

国外的这些组件库,好像都不做这些事情。如果要管理表单,自己去 install 个 useForm。联动和复杂格式也都没有提供,组件库就真的只是 ui。

虽然他们内部不提供很多功能,但通常又会有大量的模板,或许国外模板付费意愿比较强吧。😂

API

用 shadcn 的时候,copy 代码的时候有个明显的感觉,就是量大。他们是真的奉行了组件要组合。比如 Drawer:

import {
Drawer,
DrawerClose,
DrawerContent,
DrawerDescription,
DrawerFooter,
DrawerHeader,
DrawerTitle,
DrawerTrigger,
} from "@/components/ui/drawer"

function App () {
return (
<Drawer>
<DrawerTrigger>Open</DrawerTrigger>
<DrawerContent>
<DrawerHeader>
<DrawerTitle>Are you absolutely sure?</DrawerTitle>
<DrawerDescription>This action cannot be undone.</DrawerDescription>
</DrawerHeader>
<DrawerFooter>
<Button>Submit</Button>
<DrawerClose>
<Button variant="outline">Cancel</Button>
</DrawerClose>
</DrawerFooter>
</DrawerContent>
</Drawer>
)
}

可以看到,什么关闭按钮、标题都会抽成一个组件。

国内一般都是提供一个数据的 props ,奉行了一切皆数据。即使像 radio 这种组合的组件,也会提供一个 options 的数据接口。

import React, { useState } from 'react';
import { Button, Drawer } from 'antd';

const App: React.FC = () => {
const [open, setOpen] = useState(false);

const showDrawer = () => {
setOpen(true);
};

const onClose = () => {
setOpen(false);
};

return (
<>
<Button type="primary" onClick={showDrawer}>
Open
</Button>
<Drawer title="Basic Drawer" onClose={onClose} open={open} closeIcon={} footer={}>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</>
);
};

export default App;

以上只是针对我看到的几个点做了对比,没有哪个好哪个坏,毕竟我都用的挺爽的。

最后!国内有些组件库,甚至是大厂的组件库,一个大厂还搞两个类似的没有创意的组件库,真的让人感觉丢人!

· 阅读需 2 分钟
SleepyZone

程序员的钱比粪还难掏

事情起因,有个独立开发老哥在推上发了一句牢骚:程序员的钱比粪还难掏。引起了挺多讨论,简单说下自己的看法。

首先,要比喻程序员的钱难赚,用掏粪做对比本就不恰当。

再者,程序员已经是付费意愿相当高的一个群体了,但为什么还是赚不到钱。程序员付费意愿高的前提是因为他们更聪明,如果你这个东西一没有提供价值二没有深度程序员分分钟命令行就能跑一个,为什么要付费呢?

国产开源和国产项目

事情起因,一个开源项目的文档设置为先 Star 后阅读,且需要授权验证虽然代码里设置了绕过方法,但还是引起了很多人的不满。

另外一个事情,有人拉了 ProductHunt 的点赞互助群,有人也表示不满,拉低了国产项目的质量。

我既不是开源大佬也不是出海开发,这些事情,我也不知道如何评价。但有个感觉,大家对国产两个字真的有点过于苛刻了。

地铁上手机码字,就这样吧。

· 阅读需 2 分钟
SleepyZone

之前为了给娃取名字,看了一遍诗经,发现了好多熟悉的名字,原来都来自于诗经。

宜家

就是大家逛的那个宜家,取自周南·桃夭

也是大家熟悉的桃之夭夭的来源。

白凯南 最早和贾玲搭档的喜剧演员,取自邶风·凯风

凯风自南,吹彼棘心。

周邦彦

宋代词人,取自郑风·羔裘

邦之彦兮,国家栋梁的意思。

同样有,有邦之媛也,取自鄘风·君子偕老,说女子倾城倾国姿色美。

张赫宣

国内歌手,取自卫风·淇奥

赫兮咺兮,指人显赫、威仪、心胸宽广。

陈都灵

国内演员,当时我不知道为何会有人用 都 做名字,直到看到了 郑风·有女同车

彼美孟姜,洵美且都。都指女生娴静,优雅。

屠呦呦

诺贝尔奖得主,取自小雅·鹿鸣

呦呦鹿鸣。

维嘉

湖南台主持人,取自大雅·生民之什

其告维何?笾豆静嘉。

周秉文

一个电视剧的主角名字,取自周颂·清庙

济济多士,秉文之德。(秉:秉承,操持。文之德:周文王的德行。)

除了名字,还有很多成语。

比如:高山仰止、普天之下莫非王土、如履薄冰、它山之石可以攻玉、衣冠楚楚、青青子衿、如隔三秋、信誓旦旦、七月流火、知我者谓我心忧等等。

诗经真的博大精深啊!

· 阅读需 10 分钟
SleepyZone

fabritor 在最新版本支持了渐变色填充,可以让文字或背景实现更华丽的效果。在实践过程中发现渐变其实是一件挺有意思(很炫酷)的事情,接下来就展开聊聊前端里关于渐变的那些事。

CSS 渐变

作为前端,说到渐变,最先想到的就是 CSS 渐变了。不过印象中很少手写,一般切页面的时候也很少有这种效果,有也是直接复制 Sketch 导出的 CSS 🤪。

CSS 里的渐变有三类:线性渐变、径向渐变和锥形渐变。直接给丢一段语法和 DEMO 可能有点摸不着头脑。我们可以先看一下维基百科给出的渐变定义:

颜色渐变(有时也叫颜色带)是指一定范围的随之位置而变的颜色,通常用于填充某一个区域。渐变产生的颜色随位置连续变化,产生平滑的颜色过渡。

从概念上看,渐变主要由以下内容组成:

  1. 随位置变化的颜色,也叫做色标(color stop)。色标由两部分组成,一个是颜色,一个是颜色所在位置。如:blue 20% 或者 blue 20px
  2. 需要渐变色填充的区域,确定渐变的起点和终点,也就是色标前进的方向。

不论是哪种渐变,都是配置以上两部分,通常语法就是 xx-gradient(direction, color stop, color stop ...)。而各类渐变色标部分其实是一致的,那就只要区分确定渐变方向的参数就行了。

线性渐变

比如线性渐变,顾名思义,色标沿着一条直线前进。渐变方向是一条直线,就直接用角度确定渐变方向。

.linear {
background: linear-gradient(90deg, blue 0, pink 20%, green 100%);
}

上面代码定义了线性渐变,色标以 90deg 方向(从左到右)前进,依次从蓝色、粉色、绿色渐变,并且定义了每个颜色的位置。

效果如图:

在使用角度的时候,0deg 代表渐变方向为从下到上,90deg 代表渐变方向为从左到右,诸如此类正角度都属于顺时针方向。而负角度意味着逆时针方向。

前往 MDN 了解更多关于线性渐变的知识。

径向渐变

径向渐变,色标以圆或者椭圆前进。要确定渐变方向,只需要确定圆或者椭圆的的中心即可。

.radial {
background: radial-gradient(circle at 50% 50%, blue 0, pink 40%, green 100%);
}

上面代码定义了径向渐变,圆心在元素的中心。

前往 MDN 了解更多关于径向渐变的知识。

锥形渐变

锥形渐变,色标围绕着中心点旋转,每个色标的区域类似一个扇形。和径向渐变一样,需要确定一个中心点。另外,因为是围绕着中心点旋转,还需要确定一个其实旋转角度。

.conic {
background: conic-gradient(
from 45deg at 50% 30%,
blue 0,
pink 40%,
green 100%
);
}

上面代码定义了锥形渐变,中心在元素的 50% 30% 处,从 45deg 开始旋转。

前往 MDN 了解更多关于锥锥形渐变的知识。

更多

CSS 渐变除了单一的设置渐变,还支持更高级的渐变设置,比如可以将多个渐变堆叠起来:

.stacked-linear {
background: linear-gradient(
217deg,
rgba(255, 0, 0, 0.8),
rgba(255, 0, 0, 0) 70.71%
), linear-gradient(127deg, rgba(0, 255, 0, 0.8), rgba(0, 255, 0, 0) 70.71%),
linear-gradient(336deg, rgba(0, 0, 255, 0.8), rgba(0, 0, 255, 0) 70.71%);
}

更多效果可以前往 MDN 查看。

CSS 渐变的能力十分强大,关键看有没有创意了。🤔

Canvas 渐变

canvas 也是支持渐变色的,支持线性渐变和径向渐变。

Canvas

线性渐变 createLinearGradient(x1, y1, x2, y2),和 CSS 线性渐变使用角度确定方向不同,四个参数分别表示渐变的起点 (x1,y1) 与终点 (x2,y2)。

const lineargradient = ctx.createLinearGradient(0, 0, 150, 150);

径向渐变 createRadialGradient(x1, y1, r1, x2, y2, r2),六个参数分别确定渐变的内圆坐标(x1,y1),内圆半径(r1)以及外圆坐标(x2,y2),外圆半径(r2)。

const radialgradient = ctx.createRadialGradient(75, 75, 0, 75, 75, 100);

确定渐变区域和方向后,就可以给渐变添加色标了:

lineargradient.addColorStop(0, "white");
lineargradient.addColorStop(1, "black");

fabric.js

fabritor 内的渐变基于 fabric.js 实现。

fabric.js 的渐变也就是封装了 Canvas 渐变 API,源码位置https://github.com/fabricjs/fabric.js/blob/5.x/src/gradient.class.js

// 代码片段
var gradient;

if (this.type === 'linear') {
gradient = ctx.createLinearGradient(
coords.x1, coords.y1, coords.x2, coords.y2);
}
else if (this.type === 'radial') {
gradient = ctx.createRadialGradient(
coords.x1, coords.y1, coords.r1, coords.x2, coords.y2, coords.r2);
}

for (i = 0, len = this.colorStops.length; i < len; i++) {
var color = this.colorStops[i].color,
opacity = this.colorStops[i].opacity,
offset = this.colorStops[i].offset;
}
gradient.addColorStop(offset, color);
}

return gradient;

canvas 的渐变色同时支持赋值给 stroke 和 fill 属性:

CSS 文字渐变

不知道你发现了没有,canvas 内是用 fill 属性表示填充,所以不论是形状还是文字,都可以应用渐变色。而 CSS 渐变一般我们用在 background 或者 background-image 属性内,也就是一般用到背景内,文字颜色是用 color 属性设置的,我尝试给 color 属性设置渐变,并不会生效。

那 CSS 要给文字设置渐变色,要怎么做呢?

这里看到一篇文章,How to add a gradient overlay to text with CSS,里面给了一种设置文字渐变色的方法。

background-size: 100%;
background-repeat: repeat;
background-clip: text;
color: transparent;
background-image: linear-gradient(45deg, #f3ec78, #af4261);

关键属性就是 background-clip,设置为 text,将背景裁剪成文字的前景色,这里我们又将文字设置为透明,文字就展示为渐变色了。

作者后面还给出几个更加炫酷的案例,可以前往原文查看。

SVG 渐变

SVG 现在用的越来越多了,大多数图标库都直接提供 SVG 图标了。那如何在 SVG 实现渐变呢,首先想到的就是 SVG 是有 fill 属性的,但很遗憾,直接给fill 属性设置 CSS 渐变也是不生效的,SVG 有自己的渐变语法。

SVG 设置渐变首先需要一段渐变 SVG😂:

<svg style="width:0;height:0;position:absolute;" aria-hidden="true" focusable="false">
<linearGradient id="my-cool-gradient" x1="0" y1="0" x2="1" y2="1">
<stop offset="0%" stop-color="#447799" />
<stop offset="50%" stop-color="#224488" />
<stop offset="100%" stop-color="#112266" />
</linearGradient>
</svg>

你会发现,除了语法不一样,和 canvas 里简直是一一对应的。

这时候将 linearGradient 标签对应的 id 赋值给 svg fill 属性即可。

可以 css 设置:

.icon-sprite-gradient {
fill: url(sprite.svg#my-cool-gradient) red;
}

也可以直接内联 fill 属性设置:

<svg class="icon" fill="url(#my-cool-gradient) #447799;" aria-hidden="true" focusable="false">
<use xlink:href="#symbol-id"></use>
</svg>

径向渐变语法也和 canvas 一致,这里不再展开,依然可以去 MDN 查看。

如果你体验过 fabritor,你会发现,文字设置渐变色之后,工具栏的图标也跟随展示为渐变色,就是是用了上述方式实现的。

另外 fabric.js 里,渐变类有个 toSVG 的方法,将 canvas 渐变转换为 svg 渐变。

渐变色选择器:react colors beauty

最后,推荐一下我开发的渐变色选择器 https://github.com/sleepy-zone/react-colors,同时支持纯色和渐变色选择(支持色标、线性渐变角度配置),已经在 fabritor 上使用了!

如果你的项目也需要一个渐变色选择器,不妨试一下!

· 阅读需 3 分钟
SleepyZone

在圣诞节发布 2.0 版本之后,fabritor 就进入了下一个迭代,终于在 2024 年元旦,next 分支合并进主干,发布 2.1 版本,也算是和我的项目一起跨年了。

2.1 版本主要在文本和图片带来一些增强,一些创意的增强。(都在下面的主图里了!

颜色渐变

首要支持的便是颜色渐变。fabricjs 虽然支持渐变,但怎么配置确实一个难题,属实难找到一个好用的支持渐变的颜色选择器。

所以自己动手开发了 react-colors-beauty,UI 上参考了 sketch 填充选择器,同时支持纯色和渐变色的选择器,文档地址:https://sleepy-zone.github.io/react-colors/

在文字颜色、文字边框、形状背景、画板背景都支持了渐变配置。

(同时,支持渐变的图标,也以渐变展示。

文字图片填充

fabricjs 对象的 fill 属性是支持 pattern 的,也就是图片填充,这也算是对渐变的一种补充。这样可以实现渐变难以实现的效果。

主图里 Happy New Year 的英文就是使用一张烟花图片渐变产生的。

填充图片:

图片裁剪

图片新增裁剪功能,在图片工具栏点击裁剪后,就会将当前图片选中,进行自由裁剪。

图片滤镜

在 2.0 版本中,我提到重写了图片对象,就是为了便利的享受 fabricjs 内置的滤镜。

这里内置了几个滤镜。(不知道翻译的好不好!

写在后面

至此,fabritor 作为一个图片编辑器,功能基本完善了。后续的方向一个是更像一个产品去维护它,更好的操作体验。另外抽出一个快速安装包,以便开发者更简单的部署一个自己的版本。

2024,一起加油吧!

· 阅读需 5 分钟
SleepyZone

2023年最后一个工作日,请假的人占了大半,坐在工位上,想了想今年好像还是有不少事情,应该是可以记录一下的。

依旧没起色的工作

工作上依旧没什么起色,但我也越来越习惯这种没起色的工作状态,我也把 github 上的自我介绍改为:“A 30+、LowLevel P😅 frontend developer”。但确实很自由,可以想一些自己的事情,也可以做一些自己的事情。就是不知道能持续多久(可能哪天就被毕业了也说不定。(虽然有时候也很羡慕大佬们长篇大论写自己工作的事情🤩

因为一波波的裁员潮,2023年前端们讲的最多的就是前端已死。清晰记得去年(2022)我所在的前端组走了 1/3,直到现在,每个人聊的也都是不确定,身边谁谁谁又走了,自己离职的还是领了大礼包。

知乎上的焦虑也越来越多,V2EX 上也有人在问做什么副业,推上独立开发者也越来越多,每个人都想做点什么。前一段时间一个整理副业的 github 很快就获得了几千个 star,也能说明大家的焦虑。

我也开始做一点事情,年底开了一个项目,坚持每天更新。2024年努力更新 github。

AI 今年也很火,火到让元宇宙瞬间没了动静,我所在的部门也瞬间进行了调整。特别早的时候我还开了 ChatGPT 的会员,开了 Midjourney 的会员,对话生图不亦乐乎,甚至做了应用。然而从各大厂商开始 All in 的时候,我就有点厌倦了。大佬们开始读论文了,而我就变成一个旁观者,每天在公司看似做着和 AI 相关的项目。坐等 AI 能惊艳到我的那天到来。

变化很大的生活

今年生活最大的变化便是,老婆怀孕。再有一个月,小宝宝就要来到身边了。(然而名字还没想好😤

老婆怀孕后,我的生活也开始了比较大的变化。因为通勤距离比较长,从每天挤地铁,改为现在每天开车上下班,从一开始有点战战兢兢到现在也能比较好的自如应对。包揽了家里几乎所有的家务(虽然以前可能也都是我😂),不得不说,洗碗机真的拯救了我。

不过,还是妈妈会更辛苦也会更敏感,从一开始的一个月一次的产检到现在两周一次一周一次,伴随着各种检查。每当有一些异常,都会想宝宝是不是有什么异常,一直等到医生的定论才会安下心来。

还有一个月,我笑称这个元旦,是我们最后的一个二人世界的假期了😂。

最重要的还是健康

工作越久,越觉得健康才是最重要的。

去年食管反流,今年勉强算好了,但感觉很难回到以前的肠胃了。体检又检出了 0.5cm 胆囊息肉,如果再变大一点,就要手术了。吃东西也变得小心翼翼,失去了很多吃的乐趣。

很多人年轻熬夜,年轻时可能不觉得什么,随着年龄增大,确实会有些力不从心,还是要健康作息和饮食,再加一些必要的运动(很难。

2024年,健康也是一个关键字。

2024

大家一起加油吧!

· 阅读需 1 分钟
SleepyZone

恭喜你找到这么优秀的博客!