Butterfly 友链魔改教程
发表于更新于
字数总计1.6k阅读时长7分钟阅读量
更新日志
- 更新精灵图生成器,修改缺省的本地文件库的位置,修复
db.json
异常膨胀的 BUG
- 窄屏不再添加 css 动画
- 精灵图支持拆分
- 改进精灵图生成器
该教程不适合小白食用,需要有一定的基本功!
教程中没有支持配置项,如果你希望支持配置项的话可以自行修改。
魔改
首先需要修改 pug,修改\layout\includes\page\flink.pug
为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | #article-container .flink if site.data.link - let index = 0 // 计数器,不要修改 let group = 0 // 分组计数器,不要修改 const avatarRoot = './sprites/avatar-' const ext = 'jpg' // 头像拓展名,按需修改 const limit = 0 // 每张图片头像数量限制,按需修改,需要和精灵图保持一致 let rootStyle = `.group-0{background:url(${avatarRoot}0.${ext})}` - each list in site.data.link if list.class_name h2!= list.class_name if list.class_desc .flink-desc!= list.class_desc - let className = list.beautify ? 'beautify' : 'terse' - if (list.deprecated) className += ' deprecated' .flink-list(class = className) each item in list.link_list a.flink-item(href = url_for(item.link), target = '_blank') if list.beautify if item.tag span.card-tag!= item.tag img.card-bg.no-lightbox(src = url_for(item.siteshot)) .info if list.deprecated .text span.name!= item.name else - const styleStr = index === 0 ? '' : `background-position-y:-${(index) * 100}px` .avatar.no-lightbox(class=`group-${group.toString(16)}`, style=styleStr) .text span.name!= item.name span.descr!= item.descr - if (++index === limit) { index = 0 ++group rootStyle += `.group-${group.toString(16)}{background:url(${avatarRoot}${group}.${ext})}` }; - style!= rootStyle != page.content
|
然后添加样式,修改\source\css\_page\flink.styl
为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | maxWidth(value) @media screen and (max-width: unit(value, px)) {block}
minWidth(value) @media screen and (min-width: unit(value, px)) {block}
.flink-list display flex flex-wrap wrap
.flink-item position relative border-radius 8px overflow hidden border var(--km-button-border) background var(--hl-bg)
&:hover text-decoration none !important box-shadow var(--km-subt-shadow) border var(--km-light-border)
.avatar transition all .6s border-radius 50% background-size cover width 100px height 100px
.card-tag position absolute color white font-size 10px left 0 top 0 padding 4px 8px background #0084FF z-index 1 border-bottom-right-radius 12px transition all .6s
.text display flex flex-direction column padding-right 10px
.name max-width 100% font-weight bold text-overflow ellipsis white-space nowrap overflow hidden
.descr margin-bottom 10px font-size small overflow hidden max-height 52px
&.beautify .flink-item width calc(25% - 16px) height 210px margin 8px transition all .6s
+maxWidth(1000) width calc(33% - 16px)
+maxWidth900() width calc(25% - 16px)
+maxWidth(700) width calc(33% - 16px)
+maxWidth(500) width calc(50% - 16px)
+maxWidth(350) width calc(100% - 16px)
.card-bg position relative height 60% min-width 100% object-fit cover margin 0 !important transition all .6s !important filter blur(0)
.info position relative height 40% transition background .6s, height .6s
.avatar position absolute left -32px top -32px transform scale(.2)
.text position relative top 0 margin-left 30px transition all .6s
+minWidth(500) &:hover .card-bg height 35% filter blur(3px)
.info height 66% background #F2B94B color white
.avatar left -10px top -50px transform rotateZ(-35deg) rotateX(360deg) rotateY(360deg) scale(.6)
.text top 26px margin-left 10px
.descr max-height 78px
.card-tag left -100%
&.terse &:not(.deprecated) .flink-item height 100px
.flink-item width calc(25% - 12px) padding 6px margin 6px
+maxWidth1024() width calc(33% - 12px)
+maxWidth(1000) width calc(50% - 12px)
+maxWidth900() width calc(33% - 12px)
+maxWidth(700) width calc(50% - 12px)
+maxWidth(450) width calc(100% - 12px)
.info position relative height 100% width 100%
.avatar position absolute transform scale(.7) left -10px top -6px
.text position relative left 85px width calc(100% - 80px) transition all .6s
+minWidth(600) &:hover .avatar transform rotateX(180deg) rotateY(180deg) scale(.01) left -100px opacity 0
.text left 10px width calc(100% - 20px)
.text:first-child left 10px width calc(100% - 20px)
|
编写 YML
然后我们还需要编写友链的 YML 文件,格式要求如下:
1 2 3 4 5 6 7 8 9 10 | - class_name: name beautify: true deprecated: false link_list: - name: name link: url descr: text siteshot: url
|
生成精灵图
接下来我们需要生成一个精灵图,有两种选择:
- 手动拼接
- 使用工具自动生成
前者的话找一个图片编辑软件自己一个一个按顺序拼接起来就可以了,每个头像必须为正方形且大小相同、纵向排列。
我写了一个自动化生成的工具,可以供小伙伴们使用:
该软件使用 Kotlin 编写,运行环境的最低要求为 JRE8,使用时通过命令启动即可:
1 | java -jar ./SpriteBuilder.jar [args]
|
目前支持的参数有:
参数名 | 值类型 | 解释(缺省值) |
---|
yml | String | 友链文件的路径(./source/_data/link.yml ) |
output | String | 输出文件的路径,不带拓展名(./sprites/avatar ) |
size | Int | 单个头像的大小(120 ) |
retry | Int | 网络拉取重试次数(2 ) |
limit | Int | 每张精灵图的头像数量限制,填 <= 0 的数表明无限制(0 ) |
format | String | 输出的图像格式,支持 jpg 和 png(jpg ) |
local | String | 本地图像库地址(./.sprite_data/ ) |
timeout | Int | 网络拉取超时时间,单位 ms(10000 ) |
该工具支持解析友链 YML 的信息,然后拼接出图片,只支持导出 jpg 格式。
YML 的格式要求如下:
1 2 3 4 5 6 7 8 9 10 11 | - deprecated: false link_list: - link: url avatar: url0 - link: url avatar: url1 - deprecated: false link_list:
|
工具支持解析ImageIO.read
支持的所有图像格式,同时附加webp
格式支持,基本覆盖常用格式,解析图像时使用图像的二进制数据判断图像格式。
本地图像库用于自动替换友链的头像,比如有如下 yaml:
1 2 3 | - link_list: - link: https://kmar.top/ avatar: https://image.xxx.top/qq.jpg
|
工具会在本地图像库中检查目录中是否存在名为kmar.*
的文件,如果有的话会直接使用本地图像库中的图片,不会发起网络请求。
在本地库中查找时,会使用link
的域名(不带二级域名和顶级域名)作为文件名称,比如:
https://kmar.top/
- kmarhttps://www.kmar.top/
- kmarhttps://abc.github.io/
- github
如果本地图像库中存在多个文件名一致但拓展名不一致的文件,会选择最后一个。
工具在拉取文件时的请求头设置如下:
1 2 3 | referer: 'https://sprite-builder.kmar.top/' user-agent: 'sprite-builder' accept: 'image/webp, image/*'
|
当拉取文件遇到 403 错误时,会尝试将referer
设置为空,然后重新进行拉取(如果没有超出重试次数限制的话)。
创作不易,扫描下方打赏二维码支持一下吧ヾ(≧▽≦*)o
Butterfly 友链魔改教程空 梦 | 山岳库博
更新于 2023-10-18
发布于 2023-04-23