This site runs best with JavaScript enabled.

1. 根据 hex 背景颜色计算前景文字颜色

// 计算出经验灰度值,然后反色作为文字颜色
const getTextColorFromHex = (bgColor) => {
if (/^#([0-9a-f-A-F]{3}|[0-9a-f-A-F]{6})$/.test(bgColor))
return bgColor
.replace(/^#/, "")
.replace(/^\w+$/, c =>
c.length == 3
? c
.split("")
.map(c => c.repeat(2))
.join("")
: c
)
.match(/\w{2}/g)
.map(hexV => parseInt(hexV, 16))
.reduce((t, v, i) => t + [0.299, 0.587, 0.114][i] * v, 0) /
255 >
0.5
? "#000"
: "#fff"
else
return '#fff'
}

2. SSL

快速生成一个本地 SSL 证书用来调试

openssl req -x509 -nodes -new -sha256 -days 1024 -newkey rsa:2048 -keyout localhost.key -out localhost.pem -subj "/C=US/CN=Example-Root-CA"
openssl x509 -outform pem -in localhost.pem -out localhost.crt
mkcert 可以命令行本地签发https证书
mkcert --install
mkcert *.example.com

快速配置网站 SSL

  1. 免费证书颁发机构 Let’s Encrypt
  2. 推荐 ACME 客户端 Certbot

3. canvas 圆角矩形、圆角图片、多行文字

const roundRect = (ctx, x, y, w, h, r) => {
var min_size = Math.min(w, h);
if (r > min_size / 2) r = min_size / 2;
ctx.moveTo(x + r, y);
ctx.arcTo(x + w, y, x + w, y + h, r);
ctx.arcTo(x + w, y + h, x, y + h, r);
ctx.arcTo(x, y + h, x, y, r);
ctx.arcTo(x, y, x + w, y, r);
}
const roundImage = (ctx, image, x, y, w, h, r) => {
ctx.save()
ctx.beginPath();
roundRect(ctx, x, y, w, h, r);
ctx.clip()
ctx.closePath();
ctx.drawImage(image, 0, 0, image.width, image.height, x, y, w, h);
ctx.restore()
}
const drawText = (ctx, text, x, y, maxWidth, lineHeight) => {
let arrText = text.split('');
let line = '';
for (let n = 0; n < arrText.length; n++) {
let testLine = line + arrText[n];
let metrics = ctx.measureText(testLine);
let testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
ctx.fillText(line, x, y);
line = arrText[n];
y += lineHeight;
} else {
line = testLine;
}
}
ctx.fillText(line, x, y);
return y + lineHeight
}

4. 直接启动 AS 的模拟器

@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
:begin
::
D:\android_sdk\emulator\emulator.exe -netdelay none -netspeed full -avd fake_Pixel_3_XL_29

5. 直接静默启动 scrcpy,同时指定某个设备

@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("%~nx0 h",0)(window.close)&&exit
:begin
::
"D:\Program Files\scrcpy-win64-v1.16\scrcpy.exe" -s a9e8d32c

6. API 收集

// 很多免费的
// https://api.isoyu.com/

节假日

// https://github.com/NateScarlet/holiday-cn
{
"$schema": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/schema.json",
"$id": "https://raw.githubusercontent.com/NateScarlet/holiday-cn/master/2022.json",
"year": 2022,
"papers": [
"http://www.gov.cn/zhengce/content/2021-10/25/content_5644835.htm"
],
"days": [
{
"name": "元旦",
"date": "2022-01-01",
"isOffDay": true
},
{
"name": "元旦",
"date": "2022-01-02",
"isOffDay": true
}
]
}

城市地区划分

// https://github.com/modood/Administrative-divisions-of-China
[
{"code":"110101","name":"东城区","cityCode":"1101","provinceCode":"11"},
{"code":"110102","name":"西城区","cityCode":"1101","provinceCode":"11"},
]

地图

这些网站可以帮你下载高清地图:

城市天气

// http://image.data.cma.cn/static/doc/market/China_SURF_Station.xlsx 全部的气象站ID对应关系,带 GPS
// http://www.nmc.cn/rest/position 获取 station, url 和城市地区
// http://www.nmc.cn/rest/weather?stationid=54399 station 的详情
// http://m.nmc.cn/publish/forecast/ABJ/beijing.html 没有小时预报,只能曲线匹配
// http://weather.cma.cn/api/weather/view 无需 stationid,支持 jsonp , ?callback=x&stationid=&_=
// 'http://image.nmc.cn/assets/img/w/40x40/4/${response.data!['weather']['img']}.png' 图标
// 全球天气
https://worldweather.wmo.int/zh/dataguide.html
// 全球城市id+GPS
// https://worldweather.wmo.int/zh/json/Country_zh.xml
// https://worldweather.wmo.int/zh/json/234_zh.xml 某个城市的预报
// https://worldweather.wmo.int/zh/json/present.xml 全球实时天气
// 'https://worldweather.wmo.int/images/${'i'}${icon}${(icon >= 21 && icon <= 25) ? 'a' : ''}.png' 图标系统

城市层级 / 天气api的AREAID

// https://e.weather.com.cn/chunyun/js/city.js
{
"北京": {
"北京": {
"北京": {
"AREAID": "101010100",
"NAMECN": "北京"
},
"海淀": {
"AREAID": "101010200",
"NAMECN": "海淀"
},
"朝阳": {
"AREAID": "101010300",
"NAMECN": "朝阳"
},
// ...
}
// ...
}
// ...
}

7. node 批量修改 MP3

var fs = require('fs')
var path = require('path')
const NodeID3 = require('node-id3')
const dir = fs.readdirSync(__dirname)
const files = dir.filter(f => !/(js)|(node)$/.test(f))
files.forEach(file => {
let s = 0
let e = 0
const match1 = file.match(/S(\d+)E(\d+)/)
const match2 = file.match(/Season(\d+)Episode(\d+)/)
if (match1) {
s = match1[1].padStart(2, '0')
e = match1[2].padStart(2, '0')
} else if (match2) {
s = match2[1].padStart(2, '0')
e = match2[2].padStart(2, '0')
}
const name = `TBBT S${s}E${e}`
const filepath = path.join(__dirname, file)
const tags = { title: name }
const success = NodeID3.write(tags, filepath)
// fs.renameSync(filepath, path.join(__dirname, `${name}.mp3`))
console.log(path.join(__dirname, `TBBT_S${s}E${e}.mp3`), success)
})

8. 多种 NLP 算法收集

聊天机器人、语音识别、OCR、词库等,还有脏话、敏感词检测
https://www.giters.com/fighting41love/funNLP

9. 中文样式

.post {
font-family: 'chinese quotation marks','opensans regular','helvetica neue',Helvetica,'noto sans sc','microsoft yahei',微软雅黑,STXihei,华文细黑,Arial,sans-serif;
/* Roboto,San Francisco,"Helvetica Neue",Helvetica,Arial,PingFangSC-Light,"Hiragina Sans GB","WenQuanYi Micro Hei",'microsoft yahei ui','microsoft yahei',sans-serif */
/* HanHei SC,PingHei,PingFang SC,STHeitiSC-Light,Helvetica Neue,Helvetica,Arial,sans-serif*/
font-size: 16px;
line-height: 28px;
letter-spacing: 1px;
-webkit-font-smoothing: antialiased;
-webkit-text-stroke-width: .2px;
}
  1. 老旧项目 webpack 的 node-sass 依赖处理
node-sassNodeJs 版本强相关,还要用 windows-build-tool 要有 python2 等依赖,在新版 NodeJs 里面已经没法使用了。但是老旧项目还想运行的话,需要使用 sass-loaderoptions 中的 implementation 属性切到 dart-sass
const webpackConfig = {
//...
rules: [
{
loader: 'sass-loader',
options: { implementation: require('sass'), sourceMap: true }
}
]
//...
}
一些包装的 config 也可以用 webpack-chain 处理
// 这个参数需要根据console出来的数据结构来做,跟版本号有关系
// 参考:https://github.com/XHMM/taro-plugin-dart-sass/blob/master/src/index.ts
// console.log(chain.toConfig().module.rules[0])
// console.log(chain.toConfig().module.rules[0].use)
// console.log(chain.toConfig().module.rules[0].use[1])
chain.module.rule('sass').use('1').loader('sass-loader').options({
  // @ts-ignore
  implementation: require('sass'),
});
🔝

🐞 关于

有时间就会分享一些技术文章、专业内容、经典问题、系列功能等。

{⛔ 未标注内容均为原创,请勿转载 ©️}