@yyyu-star/arcade-kit 0.11.2 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # 更新日志
2
2
 
3
+ ## 0.12.0
4
+
5
+ 社交第一期的两个部件(仓库根 `docs/social.md` 1.1–1.3;接口形状主线定、平台实现)。都只在调用时碰 DOM,import 时不碰;已有入口没改。
6
+ - **分享卡** `arcade-kit/share`:`drawShareCard` 用 Canvas 画 1080×1350 的战绩图(游戏给 `{ game, title, big, stats≤3, line, accent, art?, player?, date? }`),
7
+ `shareCard` 能带文件就调 `navigator.share`,不能就出预览(保存图片、复制链接、关闭)。不上传、0 行写入。
8
+ `art` 接受一个 `CanvasImageSource`,或者 `{ image, crop?, fit?: 'contain' | 'cover' }` 从图集切一块;是 img 时先 `decode()`,失败就不画 art、照常出卡。
9
+ - **报位置、收邀请** `arcade-kit/social`:`mountSocial` 只在有平台、已登录时挂;页面在前台时每 2 分钟 `POST /api/presence`、每 30 秒 `GET /api/invites`,
10
+ 顶上弹"老王叫你来<游戏> [去] [不了]",过期不弹、已经在那个房间的不弹,"去""不了"都 `POST /api/invites/<id>/dismiss`;401 自己停。
11
+ 接口小函数 `postPresence`、`fetchInvites`、`dismissInvite`、`sendInvite`(429 → `limit`)、`fetchFriends`、`setShowWhere`,写的请求带 `x-arcade: 1`、同源 cookie。
12
+ - 测试:`test/share.test.ts`(截短、颜色、日期、折行、图集切片和 contain/cover 的位置)、`test/social.test.ts`(假 fetch 查每个接口的方法、地址、头、请求体和各种状态码,挑哪条邀请弹)。
13
+ 浏览器里用演示页 `demo/share.html`、`demo/social.html` 核对过:三种卡(图标、图集切片、坏图)都出 1080×1350,切片取到对的那格;无头 Chromium 没有带文件的分享,走预览,保存和复制都通;
14
+ 横条按到期先后弹、过期收起、"去""不了"各发一次 dismiss、和自己同房间的那条不弹,控制台零报错。
15
+
3
16
  ## 0.11.2
4
17
 
5
18
  - **table-fun 窄屏**:互动面板(440 宽)、点头像的菜单(432 宽)在 390 竖屏上伸出屏幕(麻将接入时发现,先用 CSS 收窄了)。盒子宽度改成 `min(<宽度>px, calc(100vw - 16px))`,
package/README.md CHANGED
@@ -43,6 +43,8 @@ a daily write-quota meter (`arcade-kit/meter`), a seeded ChaCha20 RNG (`arcade-k
43
43
  | `arcade-kit/client` | 浏览器 | `RoomClient`:退避加抖动重连、切回前台和网络恢复时马上连、认得出静默死掉的连接(0.11.1)、按 seq 去重、没确认的操作按原 moveId 和 baseSeq 重发、一直连不上就停下等用户点重试;`createRoom`、`createText`、`closeText`(0.8.0):开房和给玩家看的默认文案;`detectPlatform`、`withNickname`(0.10.0):独立部署时页面降级、带昵称 |
44
44
  | `arcade-kit/testing` | 游戏的测试、本地开发 | 假平台钱包(0.8.0):`WalletService`、`FakeBank`、`walletHttp`,只复刻接口形状和关键规则;不进线上代码 |
45
45
  | `arcade-kit/protocol` | 两边 | 消息类型、协议版本、关闭码、房间码格式 |
46
+ | `arcade-kit/share` | 浏览器 | 分享卡(0.12.0):`drawShareCard` 画 1080×1350 的战绩图,`shareCard` 带文件调系统分享,不支持就出预览(保存图片、复制链接);不上传、0 行写入 |
47
+ | `arcade-kit/social` | 浏览器 | 社交第一期(0.12.0):`mountSocial` 报位置、收好友邀请并在顶上弹横条;`sendInvite`、`fetchFriends`、`setShowWhere` 等接口小函数;只在有平台且已登录时挂 |
46
48
 
47
49
  **发布和仓库内引用是两种形态**(0.10.0):
48
50
  - npm 上的包是编译好的 `dist/`(JS + `.d.ts`),`exports` 每个入口给 `types` 和 `default`;
@@ -343,6 +345,59 @@ protected override onEmote(from: number, id: number, to?: number): void {
343
345
  - 电脑的反应只是画面,**出牌决策绝不读它**;真人的短语、道具不记进牌局状态(见上面 `onEmote` 的规矩)。
344
346
  - 其他纯函数:`stickerMood`(表情对应的情绪)、`FunCooldown`(冷却)、`FunTally`(护盾、连击、回敬)、`placeMenu`(菜单放哪,避开禁区;窄屏按 `fitMenuWidth` 收窄到屏幕宽减 16px,0.11.2)、`funItem`/`stickerId`/`propId`(编号换算),测试在 `test/fun-logic.test.ts`。
345
347
 
348
+ ## 分享卡和邀请(share、social,0.12.0)
349
+
350
+ 规范是仓库根 `docs/social.md` 1.1–1.3。两个入口都只在调用时碰 DOM,import 时不碰;纯的部分测试在 `test/share.test.ts`、`test/social.test.ts`。
351
+
352
+ ### 分享卡
353
+
354
+ 游戏只交数据,画法统一(主题色渐变底、图标、游戏名、一个大数字、最多 3 条小数据、一句名场面、昵称和称号、北京时间日期):
355
+
356
+ ```ts
357
+ import { shareCard } from 'arcade-kit/share';
358
+
359
+ const r = await shareCard(
360
+ {
361
+ game: '游戏名', title: '实盘小档 · 8 副', accent: '#b03a2e',
362
+ big: { value: '+3.5', label: '份筹码' },
363
+ stats: [{ label: '头游', value: '4 次' }, { label: '炸弹', value: '6 个' }], // 最多 3 条,多的不画
364
+ line: '最后一手四个 A 炸穿全场', // 模板拼的,不收玩家自由文字
365
+ art: { image: atlasImg, crop: { x: 128, y: 0, w: 128, h: 128 }, fit: 'contain' },
366
+ player: { name: '小明', badge: '炸弹狂人' },
367
+ },
368
+ { url: location.href /* 好友房结算带房间码 */, log: (l) => smokeLog.push(l) },
369
+ ); // 'shared' | 'preview' | 'cancelled'
370
+ ```
371
+
372
+ - `art` 可以直接给一个 `CanvasImageSource`(img、canvas、ImageBitmap),或者 `{ image, crop?, fit? }` 从图集里切一块(`crop` 是源图像素,`fit` 默认 `contain`,`cover` 铺满裁中间)。
373
+ 是 img 时先 `await img.decode()`,没加载完、坏图、跨域画不上都**不画 art、照常出卡**。
374
+ - 系统分享要 `navigator.canShare({ files })` 为真(手机浏览器);不支持、或出错(用户取消除外)就出预览层:图 + "保存图片"(下载 `share.png`)+ "复制链接" + "关闭"。
375
+ 预览层 z-index 默认 2000,按钮的 `data-key` 是 `share:save`、`share:copy`、`share:close`,冒烟点这些;`log` 给 `分享 系统`、`分享 预览`、`分享 保存`、`分享 复制`。
376
+ - 只要图不分享:`drawShareCard(card, canvas?)` 返回画好的 canvas,`shareCardBlob(card)` 返回 PNG。
377
+ - **图上只有游戏给的数据**:别人没摊的牌、手牌这类隐藏信息游戏自己别放进来。
378
+
379
+ ### 报位置、收邀请
380
+
381
+ ```ts
382
+ import { mountSocial, sendInvite } from 'arcade-kit/social';
383
+
384
+ const social = await mountSocial({
385
+ platform, // 启动时 detectPlatform 的结果,不给就自己问一次 /api/me
386
+ where: () => (room ? { place: 'room', game: 'mygame', room: room.code, seats: `${room.humans}/4` } : { place: 'game', game: 'mygame' }),
387
+ gameName: (id) => GAME_NAMES[id], // 横条上"老王叫你来<名字>";kit 不认识任何游戏,不给就说"一起玩"
388
+ onGo: (inv) => confirmLeave(() => location.assign(`/games/${inv.game}/?room=${inv.room}`)), // 可选:打到一半先确认
389
+ });
390
+ // 没平台、没登录:social 是 null,一个请求都不发
391
+ social?.presenceNow(true); // 进房、换房时马上报一次
392
+ ```
393
+
394
+ - 页面在前台时每 2 分钟 `POST /api/presence`(`where()` 现问,返回 null 这次不报),每 30 秒 `GET /api/invites`;切后台就停,回到前台到点马上补。平台回 401 就自己停。
395
+ - 横条在页面顶上(让出刘海),一次一条,先到期的先弹;过期的、已经在那个房间里的不弹。"去"先 `dismiss`(keepalive)再跳 `/games/<id>/?room=<码>`,
396
+ "不了"`dismiss` 后弹下一条,到期自己收起。按钮 `data-key` 是 `invite:go`、`invite:no`;`log` 给 `位置 204`、`邀请 弹 <id>`、`邀请 去`、`邀请 不了`、`邀请 过期`。
397
+ - 发邀请 `sendInvite({ to, game, room })` → `{ ok: true, id }` 或 `{ ok: false, error: 'limit' | 'blocked' | 'login' | 'failed', retryAfter? }`(429 是每天 50 条、同一好友 1 分钟 1 条超了)。
398
+ `fetchFriends()` 带 `online`、`where`(对方关了开关就没有),`setShowWhere(bool)` 改"让好友看到我在哪"。都带同源 cookie,写的请求带 `x-arcade: 1`。
399
+ - 演示页 `demo/share.html`、`demo/social.html`(`npx vite` 后打开;社交用假 fetch,一进来就有几条邀请)。
400
+
346
401
  ## 房间怎么守规矩
347
402
 
348
403
  - **只用 `ctx.acceptWebSocket`、一个闹钟**:所有到期时间(房间寿命 3 小时、没人 10 分钟、这一手 30 秒、掉线宽限 60 秒、电脑没算完、停够了(0.5.0))取最早的;
@@ -510,6 +565,8 @@ packages/arcade-kit/
510
565
  │ ├─ fun.ts、fun-art.ts 快捷短语、表情、道具的画面层
511
566
  │ ├─ fun-logic.ts 牌桌互动的规则:冷却、护盾、连击、回敬、电脑反应、菜单位置(纯函数)
512
567
  │ ├─ table-fun.ts 牌桌互动组件 TableFun(DOM:头像菜单、面板、提示)
568
+ │ ├─ share.ts 分享卡(Canvas 画战绩图、系统分享或预览)
569
+ │ ├─ social.ts 报位置、收邀请的横条、好友和邀请的接口小函数
513
570
  │ ├─ testing.ts 假平台钱包(只给测试和本地开发)
514
571
  │ └─ internal.ts 内部地址、身份头(不在 exports 里)
515
572
  ├─ scripts/manifest.mjs 打包时把 exports 换成 dist 版、换回来、检查 dist
@@ -0,0 +1,106 @@
1
+ /**
2
+ * 分享卡(0.12.0,仓库根 docs/social.md 1.1):结算页的"分享"按钮生成一张 1080×1350 的战绩图(Canvas 画,不经服务器,0 行写入),
3
+ * 手机上支持带文件的 navigator.share 就直接调系统分享,不支持的出预览,"保存图片""复制链接"两个按钮。
4
+ *
5
+ * - 游戏只交数据(`ShareCard`),画法统一在这里,几个游戏风格一致;kit 不认识任何游戏,名字、图标、主题色都由游戏给。
6
+ * - 这个文件只在调用时碰 DOM,import 时不碰(房间、测试里 import 没事);排版的算法是纯函数,测试在 test/share.test.ts。
7
+ * - 图上只有游戏给的数据:别人的隐藏信息(没摊的底牌、手牌)游戏自己别放进来。
8
+ */
9
+ /** 卡的尺寸:竖版 4:5,社交软件里不被裁 */
10
+ export declare const CARD_W = 1080;
11
+ export declare const CARD_H = 1350;
12
+ /** 小数据最多三条,多的不画 */
13
+ export declare const MAX_STATS = 3;
14
+ /** 图标、插画:一个能画的图(img / canvas / ImageBitmap),或者从图集里切一块(crop 是源图的像素) */
15
+ export type ShareArt = CanvasImageSource | {
16
+ image: CanvasImageSource;
17
+ crop?: {
18
+ x: number;
19
+ y: number;
20
+ w: number;
21
+ h: number;
22
+ };
23
+ fit?: 'contain' | 'cover';
24
+ };
25
+ export interface ShareCard {
26
+ /** 游戏名(显示用,比如游戏自己的中文名) */
27
+ game: string;
28
+ /** 这一张是什么:比如"实盘小档 · 8 副"、"每日挑战" */
29
+ title: string;
30
+ /** 一个大数字和它的说明:守了多久、赚了多少、名次 */
31
+ big: {
32
+ value: string;
33
+ label: string;
34
+ };
35
+ /** 两三条小数据,最多 3 条 */
36
+ stats?: readonly {
37
+ label: string;
38
+ value: string;
39
+ }[];
40
+ /** 一句名场面(模板拼的,不收玩家的自由文字) */
41
+ line?: string;
42
+ /** 主题色 #rrggbb,底色按它渐变 */
43
+ accent: string;
44
+ /** 游戏图标或插画(可选);是 img 时先 decode,失败就不画,照常出卡 */
45
+ art?: ShareArt;
46
+ /** 玩家昵称和称号(可选) */
47
+ player?: {
48
+ name: string;
49
+ badge?: string;
50
+ };
51
+ /** 日期,默认现在(按北京时间写成 2026.10.16) */
52
+ date?: Date;
53
+ }
54
+ /** 截短:超过 max 个字符的截掉、补省略号(按码点算,不切坏表情) */
55
+ export declare function clip(s: string, max: number): string;
56
+ /** 游戏给的主题色只认 #rrggbb,不认的用一个中性的深红 */
57
+ export declare function accentOf(x: string): string;
58
+ /** 颜色变深 / 变浅:k < 0 往黑走,k > 0 往白走(-1..1) */
59
+ export declare function shade(hex: string, k: number): string;
60
+ /** 日期按北京时间写:2026.10.16 */
61
+ export declare function cardDate(d: Date): string;
62
+ /** 卡上真正要画的字:截短、最多三条小数据、颜色认好 */
63
+ export declare function normalizeCard(card: ShareCard): Required<Omit<ShareCard, 'art' | 'player'>> & Pick<ShareCard, 'art' | 'player'>;
64
+ /**
65
+ * 按宽度折行(中文逐字、英文按词),最多 maxLines 行,放不下的最后一行补省略号。measure 由调用方给(Canvas 的 measureText),测试给假的
66
+ */
67
+ export declare function wrapLines(text: string, maxW: number, measure: (s: string) => number, maxLines: number): string[];
68
+ /** 图怎么放进框:contain 整张放进去、居中;cover 铺满框、裁掉多的(中间那块)。返回 drawImage 的九个参数里后八个 */
69
+ export declare function artRect(src: {
70
+ w: number;
71
+ h: number;
72
+ }, box: {
73
+ x: number;
74
+ y: number;
75
+ w: number;
76
+ h: number;
77
+ }, fit?: 'contain' | 'cover', crop?: {
78
+ x: number;
79
+ y: number;
80
+ w: number;
81
+ h: number;
82
+ }): [number, number, number, number, number, number, number, number];
83
+ /** 画一张卡。canvas 不给就新建一个 1080×1350 的 */
84
+ export declare function drawShareCard(input: ShareCard, canvas?: HTMLCanvasElement): Promise<HTMLCanvasElement>;
85
+ /** 画成 PNG */
86
+ export declare function shareCardBlob(card: ShareCard): Promise<Blob>;
87
+ export interface ShareOptions {
88
+ /** 分享出去的链接:游戏地址,好友房结算带房间码 */
89
+ url: string;
90
+ /** 系统分享里的一句话,默认用卡的游戏名和大数字拼 */
91
+ text?: string;
92
+ /** 存图的文件名,默认 share.png */
93
+ fileName?: string;
94
+ /** 预览层的 z-index,默认 2000(要比游戏的弹窗高) */
95
+ zIndex?: number;
96
+ /** 冒烟、调试看的流水:`分享 系统`、`分享 预览`、`分享 保存`、`分享 复制` */
97
+ log?(line: string): void;
98
+ }
99
+ /** 结果:调了系统分享 / 出了预览 / 用户在系统分享里取消了 */
100
+ export type ShareResult = 'shared' | 'preview' | 'cancelled';
101
+ /**
102
+ * 点"分享":画卡,能带文件调系统分享就调,不能就出预览(保存图片、复制链接)。
103
+ * 系统分享出错(不是用户取消)也退回预览,总能拿到图。
104
+ */
105
+ export declare function shareCard(card: ShareCard, opts: ShareOptions): Promise<ShareResult>;
106
+ //# sourceMappingURL=share.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"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"}
package/dist/share.js ADDED
@@ -0,0 +1,378 @@
1
+ /**
2
+ * 分享卡(0.12.0,仓库根 docs/social.md 1.1):结算页的"分享"按钮生成一张 1080×1350 的战绩图(Canvas 画,不经服务器,0 行写入),
3
+ * 手机上支持带文件的 navigator.share 就直接调系统分享,不支持的出预览,"保存图片""复制链接"两个按钮。
4
+ *
5
+ * - 游戏只交数据(`ShareCard`),画法统一在这里,几个游戏风格一致;kit 不认识任何游戏,名字、图标、主题色都由游戏给。
6
+ * - 这个文件只在调用时碰 DOM,import 时不碰(房间、测试里 import 没事);排版的算法是纯函数,测试在 test/share.test.ts。
7
+ * - 图上只有游戏给的数据:别人的隐藏信息(没摊的底牌、手牌)游戏自己别放进来。
8
+ */
9
+ /** 卡的尺寸:竖版 4:5,社交软件里不被裁 */
10
+ export const CARD_W = 1080;
11
+ export const CARD_H = 1350;
12
+ /** 小数据最多三条,多的不画 */
13
+ export const MAX_STATS = 3;
14
+ /** 截短:超过 max 个字符的截掉、补省略号(按码点算,不切坏表情) */
15
+ export function clip(s, max) {
16
+ const cs = [...s.trim()];
17
+ return cs.length <= max ? cs.join('') : `${cs.slice(0, Math.max(1, max - 1)).join('')}…`;
18
+ }
19
+ /** 游戏给的主题色只认 #rrggbb,不认的用一个中性的深红 */
20
+ export function accentOf(x) {
21
+ return /^#[0-9a-f]{6}$/i.test(x) ? x.toLowerCase() : '#9b2f24';
22
+ }
23
+ /** 颜色变深 / 变浅:k < 0 往黑走,k > 0 往白走(-1..1) */
24
+ export function shade(hex, k) {
25
+ const c = accentOf(hex);
26
+ const ch = [1, 3, 5].map((i) => parseInt(c.slice(i, i + 2), 16));
27
+ const out = ch.map((v) => Math.round(k < 0 ? v * (1 + k) : v + (255 - v) * k));
28
+ return `#${out.map((v) => Math.max(0, Math.min(255, v)).toString(16).padStart(2, '0')).join('')}`;
29
+ }
30
+ /** 日期按北京时间写:2026.10.16 */
31
+ export function cardDate(d) {
32
+ const p = new Intl.DateTimeFormat('en-CA', { timeZone: 'Asia/Shanghai', year: 'numeric', month: '2-digit', day: '2-digit' }).formatToParts(d);
33
+ const get = (t) => p.find((x) => x.type === t)?.value ?? '';
34
+ return `${get('year')}.${get('month')}.${get('day')}`;
35
+ }
36
+ /** 卡上真正要画的字:截短、最多三条小数据、颜色认好 */
37
+ export function normalizeCard(card) {
38
+ return {
39
+ game: clip(card.game, 12),
40
+ title: clip(card.title, 20),
41
+ big: { value: clip(card.big.value, 10), label: clip(card.big.label, 16) },
42
+ stats: (card.stats ?? []).slice(0, MAX_STATS).map((s) => ({ label: clip(s.label, 8), value: clip(s.value, 10) })),
43
+ line: clip(card.line ?? '', 60),
44
+ accent: accentOf(card.accent),
45
+ date: card.date ?? new Date(),
46
+ art: card.art,
47
+ player: card.player ? { name: clip(card.player.name, 12), ...(card.player.badge ? { badge: clip(card.player.badge, 10) } : {}) } : undefined,
48
+ };
49
+ }
50
+ /**
51
+ * 按宽度折行(中文逐字、英文按词),最多 maxLines 行,放不下的最后一行补省略号。measure 由调用方给(Canvas 的 measureText),测试给假的
52
+ */
53
+ export function wrapLines(text, maxW, measure, maxLines) {
54
+ const tokens = text.match(/[A-Za-z0-9.,'%+\-]+|\s+|./gu) ?? [];
55
+ const lines = [];
56
+ let cur = '';
57
+ let cut = false;
58
+ for (const t of tokens) {
59
+ const space = /^\s+$/.test(t);
60
+ if (!cur && space)
61
+ continue;
62
+ // 行满了还有字没放:截断
63
+ if (lines.length === maxLines) {
64
+ cut = true;
65
+ break;
66
+ }
67
+ const next = cur + t;
68
+ if (measure(next) <= maxW || !cur) {
69
+ cur = next;
70
+ continue;
71
+ }
72
+ lines.push(cur.trimEnd());
73
+ cur = space ? '' : t;
74
+ if (cur && lines.length === maxLines) {
75
+ cut = true;
76
+ break;
77
+ }
78
+ }
79
+ if (!cut && cur)
80
+ lines.push(cur.trimEnd());
81
+ if (cut) {
82
+ let last = lines[maxLines - 1];
83
+ while (last && measure(`${last}…`) > maxW)
84
+ last = [...last].slice(0, -1).join('');
85
+ lines[maxLines - 1] = `${last}…`;
86
+ }
87
+ return lines;
88
+ }
89
+ /** 图怎么放进框:contain 整张放进去、居中;cover 铺满框、裁掉多的(中间那块)。返回 drawImage 的九个参数里后八个 */
90
+ export function artRect(src, box, fit = 'contain', crop) {
91
+ let sx = crop?.x ?? 0;
92
+ let sy = crop?.y ?? 0;
93
+ let sw = crop?.w ?? src.w;
94
+ let sh = crop?.h ?? src.h;
95
+ if (fit === 'cover') {
96
+ const k = Math.max(box.w / sw, box.h / sh);
97
+ const vw = box.w / k;
98
+ const vh = box.h / k;
99
+ sx += (sw - vw) / 2;
100
+ sy += (sh - vh) / 2;
101
+ sw = vw;
102
+ sh = vh;
103
+ return [sx, sy, sw, sh, box.x, box.y, box.w, box.h];
104
+ }
105
+ const k = Math.min(box.w / sw, box.h / sh);
106
+ const dw = sw * k;
107
+ const dh = sh * k;
108
+ return [sx, sy, sw, sh, box.x + (box.w - dw) / 2, box.y + (box.h - dh) / 2, dw, dh];
109
+ }
110
+ // ───────────── 画(只在调用时碰 DOM) ─────────────
111
+ const FONT = '"PingFang SC","Hiragino Sans GB","Microsoft YaHei","Noto Sans CJK SC","Source Han Sans SC",system-ui,sans-serif';
112
+ function sizeOf(img) {
113
+ const o = img;
114
+ const num = (v) => (typeof v === 'number' ? v : typeof v === 'object' && v && 'baseVal' in v ? Number(v.baseVal.value) : 0);
115
+ const w = o.naturalWidth || o.videoWidth || o.displayWidth || num(o.width);
116
+ const h = o.naturalHeight || o.videoHeight || o.displayHeight || num(o.height);
117
+ return { w, h };
118
+ }
119
+ /** art 的两种写法拆开;是 img 就先 decode(没加载完、坏图都在这里失败),失败返回 null,卡照常出 */
120
+ async function readyArt(art) {
121
+ if (!art)
122
+ return null;
123
+ const spec = typeof art === 'object' && art !== null && 'image' in art && !('naturalWidth' in art) ? art : { image: art };
124
+ const img = spec.image;
125
+ if (typeof img.decode === 'function' && 'naturalWidth' in img) {
126
+ try {
127
+ await img.decode();
128
+ }
129
+ catch {
130
+ return null;
131
+ }
132
+ }
133
+ const { w, h } = sizeOf(spec.image);
134
+ if (!w || !h)
135
+ return null;
136
+ return { image: spec.image, crop: spec.crop, fit: spec.fit ?? 'contain' };
137
+ }
138
+ function round(ctx, x, y, w, h, r) {
139
+ ctx.beginPath();
140
+ ctx.moveTo(x + r, y);
141
+ ctx.arcTo(x + w, y, x + w, y + h, r);
142
+ ctx.arcTo(x + w, y + h, x, y + h, r);
143
+ ctx.arcTo(x, y + h, x, y, r);
144
+ ctx.arcTo(x, y, x + w, y, r);
145
+ ctx.closePath();
146
+ }
147
+ /** 字太宽就缩小字号,最小到 min */
148
+ function fitFont(ctx, text, weight, size, maxW, min) {
149
+ let s = size;
150
+ for (; s > min; s -= 4) {
151
+ ctx.font = `${weight} ${s}px ${FONT}`;
152
+ if (ctx.measureText(text).width <= maxW)
153
+ break;
154
+ }
155
+ ctx.font = `${weight} ${s}px ${FONT}`;
156
+ return s;
157
+ }
158
+ /** 画一张卡。canvas 不给就新建一个 1080×1350 的 */
159
+ export async function drawShareCard(input, canvas) {
160
+ const c = normalizeCard(input);
161
+ const cv = canvas ?? document.createElement('canvas');
162
+ cv.width = CARD_W;
163
+ cv.height = CARD_H;
164
+ const ctx = cv.getContext('2d');
165
+ const art = await readyArt(c.art);
166
+ const W = CARD_W;
167
+ const M = 72;
168
+ // 底:主题色从上往下变深,再压一层很淡的斜纹
169
+ const bg = ctx.createLinearGradient(0, 0, W * 0.4, CARD_H);
170
+ bg.addColorStop(0, shade(c.accent, 0.12));
171
+ bg.addColorStop(1, shade(c.accent, -0.55));
172
+ ctx.fillStyle = bg;
173
+ ctx.fillRect(0, 0, W, CARD_H);
174
+ ctx.save();
175
+ ctx.globalAlpha = 0.06;
176
+ ctx.strokeStyle = '#ffffff';
177
+ ctx.lineWidth = 28;
178
+ for (let x = -CARD_H; x < W; x += 110) {
179
+ ctx.beginPath();
180
+ ctx.moveTo(x, CARD_H);
181
+ ctx.lineTo(x + CARD_H, 0);
182
+ ctx.stroke();
183
+ }
184
+ ctx.restore();
185
+ // 顶:图标 + 游戏名 + 这一张是什么
186
+ let tx = M;
187
+ if (art) {
188
+ const box = { x: M, y: 70, w: 180, h: 180 };
189
+ ctx.save();
190
+ round(ctx, box.x, box.y, box.w, box.h, 36);
191
+ ctx.fillStyle = 'rgba(255,255,255,0.16)';
192
+ ctx.fill();
193
+ ctx.clip();
194
+ try {
195
+ ctx.drawImage(art.image, ...artRect(sizeOf(art.image), box, art.fit, art.crop));
196
+ }
197
+ catch {
198
+ // 跨域的图、坏图:不画,卡照常出
199
+ }
200
+ ctx.restore();
201
+ tx = M + 180 + 36;
202
+ }
203
+ ctx.fillStyle = '#ffffff';
204
+ ctx.textBaseline = 'alphabetic';
205
+ ctx.textAlign = 'left';
206
+ fitFont(ctx, c.game, '800', 84, W - tx - M, 48);
207
+ ctx.fillText(c.game, tx, 160);
208
+ ctx.fillStyle = 'rgba(255,255,255,0.82)';
209
+ fitFont(ctx, c.title, '600', 44, W - tx - M, 30);
210
+ ctx.fillText(c.title, tx, 228);
211
+ // 中:大数字
212
+ ctx.textAlign = 'center';
213
+ ctx.fillStyle = '#ffffff';
214
+ ctx.shadowColor = 'rgba(0,0,0,0.25)';
215
+ ctx.shadowBlur = 24;
216
+ ctx.shadowOffsetY = 8;
217
+ fitFont(ctx, c.big.value, '900', 230, W - 2 * M, 96);
218
+ ctx.fillText(c.big.value, W / 2, 600);
219
+ ctx.shadowColor = 'transparent';
220
+ ctx.fillStyle = 'rgba(255,255,255,0.88)';
221
+ fitFont(ctx, c.big.label, '700', 54, W - 2 * M, 34);
222
+ ctx.fillText(c.big.label, W / 2, 690);
223
+ // 小数据:一排最多三格
224
+ const n = c.stats.length;
225
+ if (n) {
226
+ const gap = 28;
227
+ const cw = (W - 2 * M - gap * (n - 1)) / n;
228
+ c.stats.forEach((s, i) => {
229
+ const x = M + i * (cw + gap);
230
+ round(ctx, x, 770, cw, 190, 28);
231
+ ctx.fillStyle = 'rgba(255,255,255,0.14)';
232
+ ctx.fill();
233
+ ctx.fillStyle = '#ffffff';
234
+ fitFont(ctx, s.value, '800', 76, cw - 32, 40);
235
+ ctx.fillText(s.value, x + cw / 2, 870);
236
+ ctx.fillStyle = 'rgba(255,255,255,0.78)';
237
+ fitFont(ctx, s.label, '600', 36, cw - 32, 26);
238
+ ctx.fillText(s.label, x + cw / 2, 925);
239
+ });
240
+ }
241
+ // 一句名场面:最多两行
242
+ if (c.line) {
243
+ ctx.fillStyle = '#ffffff';
244
+ ctx.font = `700 50px ${FONT}`;
245
+ const lines = wrapLines(`“${c.line}”`, W - 2 * M - 40, (s) => ctx.measureText(s).width, 2);
246
+ lines.forEach((l, i) => ctx.fillText(l, W / 2, 1065 + i * 66));
247
+ }
248
+ // 底:昵称、称号、日期
249
+ ctx.fillStyle = 'rgba(0,0,0,0.22)';
250
+ ctx.fillRect(0, CARD_H - 150, W, 150);
251
+ ctx.textAlign = 'left';
252
+ ctx.fillStyle = '#ffffff';
253
+ if (c.player) {
254
+ fitFont(ctx, c.player.name, '800', 50, W * 0.5, 32);
255
+ ctx.fillText(c.player.name, M, CARD_H - 62);
256
+ if (c.player.badge) {
257
+ const nw = ctx.measureText(c.player.name).width;
258
+ ctx.font = `700 34px ${FONT}`;
259
+ const bw = ctx.measureText(c.player.badge).width + 36;
260
+ const bx = M + nw + 24;
261
+ if (bx + bw < W * 0.72) {
262
+ round(ctx, bx, CARD_H - 104, bw, 54, 27);
263
+ ctx.fillStyle = shade(c.accent, 0.75);
264
+ ctx.fill();
265
+ ctx.fillStyle = shade(c.accent, -0.5);
266
+ ctx.fillText(c.player.badge, bx + 18, CARD_H - 66);
267
+ }
268
+ }
269
+ }
270
+ ctx.textAlign = 'right';
271
+ ctx.fillStyle = 'rgba(255,255,255,0.8)';
272
+ ctx.font = `600 38px ${FONT}`;
273
+ ctx.fillText(cardDate(c.date), W - M, CARD_H - 62);
274
+ return cv;
275
+ }
276
+ /** 画成 PNG */
277
+ export async function shareCardBlob(card) {
278
+ const cv = await drawShareCard(card);
279
+ return new Promise((resolve, reject) => cv.toBlob((b) => (b ? resolve(b) : reject(new Error('toBlob failed'))), 'image/png'));
280
+ }
281
+ const PREVIEW_ID = 'arcade-share-preview';
282
+ /**
283
+ * 点"分享":画卡,能带文件调系统分享就调,不能就出预览(保存图片、复制链接)。
284
+ * 系统分享出错(不是用户取消)也退回预览,总能拿到图。
285
+ */
286
+ export async function shareCard(card, opts) {
287
+ const blob = await shareCardBlob(card);
288
+ const name = opts.fileName ?? 'share.png';
289
+ const text = opts.text ?? `${card.game} · ${card.big.label} ${card.big.value}`;
290
+ const nav = navigator;
291
+ if (typeof File === 'function' && typeof nav.share === 'function') {
292
+ const file = new File([blob], name, { type: 'image/png' });
293
+ const data = { files: [file], title: card.game, text, url: opts.url };
294
+ if (nav.canShare?.(data)) {
295
+ try {
296
+ await nav.share(data);
297
+ opts.log?.('分享 系统');
298
+ return 'shared';
299
+ }
300
+ catch (e) {
301
+ if (e.name === 'AbortError')
302
+ return 'cancelled';
303
+ // 别的错(权限、不支持的类型):退回预览
304
+ }
305
+ }
306
+ }
307
+ showPreview(blob, name, opts);
308
+ return 'preview';
309
+ }
310
+ /** 不支持系统分享时:预览图 + "保存图片""复制链接";点空白处或"关闭"收起 */
311
+ function showPreview(blob, name, opts) {
312
+ document.getElementById(PREVIEW_ID)?.remove();
313
+ const url = URL.createObjectURL(blob);
314
+ const root = document.createElement('div');
315
+ root.id = PREVIEW_ID;
316
+ root.setAttribute('role', 'dialog');
317
+ root.style.cssText = `position:fixed;inset:0;z-index:${opts.zIndex ?? 2000};display:flex;flex-direction:column;align-items:center;justify-content:center;gap:16px;padding:16px;box-sizing:border-box;background:rgba(0,0,0,.72);font:600 16px ${FONT};color:#fff`;
318
+ const close = () => {
319
+ root.remove();
320
+ URL.revokeObjectURL(url);
321
+ };
322
+ root.addEventListener('click', (e) => {
323
+ if (e.target === root)
324
+ close();
325
+ });
326
+ const img = document.createElement('img');
327
+ img.src = url;
328
+ img.alt = '战绩图';
329
+ img.style.cssText = 'max-width:min(92vw,540px);max-height:calc(100% - 140px);border-radius:16px;box-shadow:0 8px 32px rgba(0,0,0,.5)';
330
+ const tip = document.createElement('div');
331
+ tip.textContent = '手机上也可以长按图片保存';
332
+ tip.style.cssText = 'font-size:13px;opacity:.75';
333
+ const row = document.createElement('div');
334
+ row.style.cssText = 'display:flex;gap:12px;flex-wrap:wrap;justify-content:center';
335
+ const btn = (label, key, fn, primary = false) => {
336
+ const b = document.createElement('button');
337
+ b.type = 'button';
338
+ b.textContent = label;
339
+ b.dataset['key'] = key;
340
+ b.style.cssText = `min-width:120px;min-height:48px;padding:0 20px;border-radius:24px;border:2px solid #fff;font:inherit;cursor:pointer;${primary ? 'background:#fff;color:#222' : 'background:transparent;color:#fff'}`;
341
+ b.addEventListener('click', (e) => {
342
+ e.stopPropagation();
343
+ fn();
344
+ });
345
+ return b;
346
+ };
347
+ const save = btn('保存图片', 'share:save', () => {
348
+ const a = document.createElement('a');
349
+ a.href = url;
350
+ a.download = name;
351
+ document.body.appendChild(a);
352
+ a.click();
353
+ a.remove();
354
+ opts.log?.('分享 保存');
355
+ }, true);
356
+ const copy = btn('复制链接', 'share:copy', () => {
357
+ const done = (ok) => {
358
+ copy.textContent = ok ? '已复制' : '复制不了,链接:';
359
+ if (!ok)
360
+ tip.textContent = opts.url;
361
+ opts.log?.(ok ? '分享 复制' : '分享 复制失败');
362
+ };
363
+ if (navigator.clipboard?.writeText)
364
+ navigator.clipboard.writeText(opts.url).then(() => done(true), () => done(false));
365
+ else
366
+ done(false);
367
+ });
368
+ const shut = btn('关闭', 'share:close', close);
369
+ row.appendChild(save);
370
+ row.appendChild(copy);
371
+ row.appendChild(shut);
372
+ root.appendChild(img);
373
+ root.appendChild(tip);
374
+ root.appendChild(row);
375
+ document.body.appendChild(root);
376
+ opts.log?.('分享 预览');
377
+ }
378
+ //# sourceMappingURL=share.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share.js","sourceRoot":"","sources":["../src/share.ts"],"names":[],"mappings":"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"}