-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f9d873e
commit 35a7440
Showing
4 changed files
with
229 additions
and
0 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Document</title> | ||
<link | ||
rel="stylesheet" | ||
href="https://gcore.jsdelivr.net/gh/CeriseBouquet/static@master/fonts/GlowSans/font.css" | ||
/> | ||
<link | ||
rel="stylesheet" | ||
href="https://gcore.jsdelivr.net/gh/CeriseBouquet/static@master/fonts/RoGSans_sliced/font.css" | ||
/> | ||
</head> | ||
<body> | ||
<main> | ||
<div id="logo"> | ||
<div id="text"> | ||
<div id="leftText"></div> | ||
<div id="rightText"></div> | ||
</div> | ||
<img id="halo" src="./halo.png" alt="" /> | ||
<div id="crossGroup"> | ||
<svg width="480" height="200" version="1.1"> | ||
<polygon points="252,0 159,190 165,190 287,0" style="fill: #fff" /> | ||
</svg> | ||
<img id="cross" src="./cross.png" alt="" /> | ||
</div> | ||
</div> | ||
|
||
<div id="controller"> | ||
<input type="text" id="ltInput" placeholder="Blue" /> | ||
<input type="text" id="rtInput" placeholder="Archive" /> | ||
</div> | ||
</main> | ||
|
||
<style> | ||
html, | ||
body { | ||
margin: 0; | ||
padding: 0; | ||
width: 100%; | ||
height: 100%; | ||
background-color: transparent; | ||
} | ||
* { | ||
box-sizing: border-box; | ||
} | ||
body { | ||
display: flex; | ||
justify-content: center; | ||
align-items: center; | ||
} | ||
main { | ||
} | ||
#logo { | ||
font-family: | ||
RoGSanSrfStd-Bd, | ||
GlowSansSC-Normal-Heavy_diff, | ||
apple-system, | ||
BlinkMacSystemFont, | ||
Segoe UI, | ||
Helvetica, | ||
Arial, | ||
PingFang SC, | ||
Hiragino Sans GB, | ||
Microsoft YaHei, | ||
sans-serif; | ||
font-size: 80px; | ||
line-height: 1; | ||
position: relative; | ||
display: flex; | ||
padding: 1.35em 0.5em; | ||
box-shadow: 0 0 0 4px red; | ||
} | ||
#text { | ||
position: relative; | ||
z-index: 1; | ||
display: flex; | ||
transform: skew(-20deg); | ||
} | ||
#leftText { | ||
color: #208ef7; | ||
} | ||
#rightText { | ||
color: #2b2b2b; | ||
} | ||
#halo, | ||
#crossGroup { | ||
position: absolute; | ||
top: calc(50% - 0.1em); | ||
transform: translateY(-50%); | ||
--size: 3.5em; | ||
height: var(--size); | ||
width: var(--size); | ||
left: calc(var(--left-width) - 0.8em); | ||
} | ||
#halo { | ||
position: absolute; | ||
z-index: 0; | ||
} | ||
#crossGroup { | ||
z-index: 2; | ||
} | ||
#crossGroup img { | ||
position: relative; | ||
width: 100%; | ||
height: 100%; | ||
z-index: 2; | ||
} | ||
#crossGroup svg { | ||
position: absolute; | ||
height: 3.5em; | ||
width: 3.5em; | ||
top: 0.5em; | ||
left: -0.95em; | ||
} | ||
|
||
#controller { | ||
margin-top: 4em; | ||
display: flex; | ||
gap: 1em; | ||
justify-content: center; | ||
} | ||
</style> | ||
|
||
<script> | ||
const url = new URL(window.location.href) | ||
const ltInit = url.searchParams.get('leftText') || 'Blue' | ||
const rtInit = url.searchParams.get('rightText') || 'Archive' | ||
|
||
const logoEl = document.getElementById('logo') | ||
const ltEl = document.getElementById('leftText') | ||
const rtEl = document.getElementById('rightText') | ||
const ltInput = document.getElementById('ltInput') | ||
const rtInput = document.getElementById('rtInput') | ||
|
||
ltInput.addEventListener('input', (e) => { | ||
ltEl.innerText = e.target.value | ||
logoEl.style.setProperty('--left-width', `${ltEl.offsetWidth}px`) | ||
}) | ||
rtInput.addEventListener('input', (e) => { | ||
rtEl.innerText = e.target.value | ||
logoEl.style.setProperty('--right-width', `${rtEl.offsetWidth}px`) | ||
}) | ||
|
||
if (ltInit) { | ||
ltInput.value = ltInit | ||
const event = new Event('input') | ||
ltInput.dispatchEvent(event) | ||
} | ||
if (rtInit) { | ||
rtInput.value = rtInit | ||
const event = new Event('input') | ||
rtInput.dispatchEvent(event) | ||
} | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { Context, h } from 'koishi' | ||
|
||
import { resolve } from 'node:path' | ||
import { URL, fileURLToPath, pathToFileURL } from 'node:url' | ||
|
||
import { BaseSticker } from '../_base' | ||
|
||
const __dirname = fileURLToPath(new URL('.', import.meta.url)) | ||
|
||
export class 蔚蓝档案 extends BaseSticker { | ||
constructor(public ctx: Context) { | ||
super(ctx) | ||
|
||
ctx | ||
.command('sticker.蔚蓝档案 <text:text>', '蔚蓝档案LOGO') | ||
.alias('sticker.blue-archive', 'sticker.ba') | ||
.shortcut('BA', { fuzzy: true }) | ||
.action(async ({ session }, text) => { | ||
const [leftText, rightText] = this.splitText(text) | ||
const image = await this.shot(leftText, rightText) | ||
return image | ||
}) | ||
} | ||
|
||
splitText(text: string) { | ||
// 如果有空格,就按空格切 | ||
if (text.includes(' ')) { | ||
const [leftText, rightText] = text.split(' ') | ||
return [leftText, rightText] | ||
} | ||
|
||
// 查询大写字母是否为两个,例如 BlueArchive 就切成 Blue Archive | ||
const ucLetters = text.match(/[A-Z]/g) | ||
if (ucLetters?.length === 2) { | ||
const [leftText, rightText] = text.split(ucLetters[1]) | ||
return [leftText, ucLetters[1] + rightText] | ||
} | ||
|
||
// 如果都不是,就对半切,如果是单数,中间的归右边 | ||
const middleIndex = Math.floor(text.length / 2) | ||
const leftText = text.slice(0, middleIndex) | ||
const rightText = text.slice(middleIndex) | ||
return [leftText, rightText] | ||
} | ||
|
||
async shot(leftText: string, rightText: string) { | ||
const page = await this.ctx.puppeteer.page() | ||
try { | ||
const url = pathToFileURL(resolve(__dirname, 'index.html')) | ||
url.searchParams.set('leftText', leftText) | ||
url.searchParams.set('rightText', rightText) | ||
await page.goto(url.toString(), { | ||
waitUntil: 'load', | ||
timeout: 3 * 1000, | ||
}) | ||
await page.waitForNetworkIdle({ timeout: 5 * 1000 }) | ||
const logo = await page.$('#logo') | ||
const buffer = await logo?.screenshot({ | ||
type: 'png', | ||
omitBackground: true, | ||
}) | ||
return h.image(buffer, 'image/jpeg') | ||
} catch (e) { | ||
return '' | ||
} finally { | ||
await page.close() | ||
} | ||
} | ||
} |