@anweather/plugin-board-kit

中文文档
1.34.0发布于 2026/11/03MITTypeScriptES Module零依赖近 30 天下载 2183

用于网页游戏平台游戏板的板-UI原始:挂载/更新/卸载处理远程插件的捆绑导出,板壳/TurnIdentity布局,转会/观察/团队帮助,转会时钟显示一半,板相机(pinch,拖放,whie)

中文使用文档
文档目录4 节
  1. 目录
  2. 板子相机
  3. 董事会框架
  4. 发展中国家

@anweather/plugin-board-kit (英语)

网页游戏平台上任意游戏板的棋盘-UI原始:一个远程 插件的前端捆绑( t)boardgame-plugins, (中文(简体) ), tactics-game-plugin,则 平台本身 plugins/tic-tac-toe-remote和仍然在 这个雷波 frontend/一次执行,一次一揽子,公开npm 登记.

在SDK的版本中与SDK一起出版. publish-plugin-sdk.yml 与 @anweather/game-plugin-ssdk 编辑 Kotlin 从一个运行时间 sdk-v* 标记,所以插件的棋盘套件, SSDK 和 运行时标出所有名称 相同的发布 。 见 plugin-protocol/CLAUDE.md, (中文(简体) ), "为跨repo插件配置".

为什么是包裹而不是副本. 插件的前端捆绑自己的反应 (没有标记) external) (中文(简体) ). react 财务报告和审定财务报表 react-dom 为: 端点 这里的依赖,所以消费者自己的 node_modules/react 是那个 此代码绑定为: 每捆完全一个反应实例 。 贝壳标记 卖出这个替换来躲避双反应失败 生成的交叉目录导入( “不能读取无效的属性( 读取) ) '""用"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""".

目录

  • mountReactBoard(Component, { onError?, fallback? }) 返回时 { mount, update, unmount } 操作跨区域远程捆绑输出 影月分界线. 它将棋盘包裹在一个错误的边界:一个渲染 错误显示信件而不是空白矩形,通过 onError,并在下一个 update()。 。 。 .
  • BoardShell (中心栏布局)和 TurnIdentity ("你是 X"行,有旁观者变相. 整个内含样式; TurnIdentity 使用 CSS 软件 color从来没有一个类名, 所以它使同样的内部 影子根,没有尾风到达.
  • computeIsMyTurn 编号 : computeIsAwaiting 编号 : computeIsSpectator 一个以上 最小结构 TurnState (任何与 lifecycle, (中文(简体) ), currentTurnParticipantId, (中文(简体) ), participants 选择 awaitingParticipantIds, (中文(简体) ), GameView (包括中文). computeIsAwaiting 实值 "等着我"在同时期意味着什么.
  • teamOf 编号 : teamMembers 四等座 二等座 二等座 二等座 (模拟平台域名) TeamAssignment) (中文(简体) ).
  • 显示平台域的一半 TurnClock数字 : useClockNow, (中文(简体) ), useClockTimeout, (中文(简体) ), formatClock, (中文(简体) ), remainingMs, (中文(简体) ), clockReading,则 ClockBadge 编号 : StartTurnGate 组件。 或 已经 留下来 引擎的调用.
  • 董事会的相机, useCamera (见下文"板相机"): 剪接, 拖动、 轮子和键盘缩放/ 泛到 a <canvas>,一个 <svg> 视图框或位置 <div>附加时 FitButton 编号 : FitIcon, (中文(简体) ), mergeHandlers在它下面的纯数学paddedWorld, (中文(简体) ), fitWorld, (中文(简体) ), canvasTransform,(......)和 createCamera没有反应的机器. useCanvasCamera 是它堕落的前身,现在是它的包袱.
  • 董事会框架, useBoardFrame (见下文"董事会框架"): 是否在平台的全屏框中,其大小 菜单角以保持清晰和宽/全布局,加平台的 全屏几何作为常数( e)MENU_RESERVE(中文(简体) ).
  • boardTelemetry(props): 主持人 BoardProps.telemetry 记者 (单位:千美元)event(name, attrs), (中文(简体) ), error(err, context)进入平台的法罗, 限定费率,并由平台以游戏类型/id/参与者来盖章), 或者说 NOOP_BOARD_TELEMETRY 在一个没有主机。 永不掷出.

不是故意在这里的 nameplateAccent.ts (这首歌) frontend/src/plugins/硬码每 -gameType 整个本地颜色 编目,是站台逻辑,不是棋盘原始.

板子相机

每板一相相机. 它聚集在棋盘-插座中 @boardgame-plugins/game-ui 从四块板上取出胶水 useCanvasCamera (原始内容存档于2012-10-12). spirit- island, catan, vititum and complete, svg 然后把帆布板移到这里 所以画布板(危险、斑点), 口袋战术)运行同一个. 三层,每层可单独使用: camera.ts (纯粹的数学:一个世界,一个缩放,一个被夹在内部的抵消) (世界), cameraController.ts (单位:千美元)createCamera:指针机,不 反应,在它交接的窗外没有DOM)和 useCamera.tsx (单位:千美元) 钩子, FitButton) (中文(简体) ).

// An svg: the drawing is lw x lh; the world is it padded to the
// element's shape, so the svg's `meet` and the pointer mapping agree.
const cam = useCamera({ world: paddedWorld(lw, lh, elW, elH), label: 'Map' })
<svg ref={cam.ref} {...cam.props} viewBox={cam.viewBoxAttr} style={{ touchAction: 'none' }}>...</svg>
{cam.zoomed && <FitButton onFit={cam.fit} />}

// A canvas: map the world at zoom 1 onto the canvas, then the camera,
// then draw in drawing coordinates.
const cam = useCamera<HTMLCanvasElement>({ world: paddedWorld(w, h), onTap: (p) => select(cam.toLayout(p.x, p.y)) })
ctx.setTransform(canvas.width / cam.world.w, 0, 0, canvas.height / cam.world.h, 0, 0)
cam.applyTransform(ctx)
<canvas ref={cam.ref} {...cam.props} style={{ touchAction: 'none' }} />

选项( E)CameraOptions),除此之外,没有其他 world 选项:

  • world (单位:千美元)paddedWorld,或 fitWorld 以保持图解 浮在地上的东西, origin (这里的画盒) 开始), minZoom 编号 : maxZoom (第1/4条).
  • opening(): 以缩放和世界点为中心, 以山为框架 以及何时 frameKey 更改;任何时候 settleKey 变化也一样, 直到玩家首先触摸相机. 放大了一个新的 world 不被带走(它会把板子移到手指下) 除非元素改变形状.
  • 磁带: 默认情况下, 未移动的相机点击到达下方的元素 这个. onTap(clientPoint) (一个撞击测试自己的板:一张帆布) 换成是用 tapSlop (6个px), tapMaxMs 财务报告和审定财务报表 onDoubleTap (320ms, 30px) (英语). 媒体走过斜坡,长出一副手指 或被声称吞下它的点击.
  • singlePointerPan (默认为真):对自己的董事会不实 一指手势是一种拖动;然后两个手指移动相机和 onDrag (单位:千美元)start 编号 : move 编号 : end 编号 : cancel,绘图坐标) 得到拖曳, 被第二个手指取消。 每个媒体都读.
  • keyboard (默认为: 表面可聚焦) role="group" 名称 label;箭头为视图的八分之一,+ / - 缩放 x1.25, (第3条).

其回报( W)Camera: view (单位:千美元)zoom, (中文(简体) ), offsetX, (中文(简体) ), offsetY, (中文(简体) ), world, (中文(简体) ), viewBox 编号 : viewBoxAttr, (中文(简体) ), transform 编号 : applyTransform(ctx), (中文(简体) ), zoomed, (中文(简体) ), pressing, (中文(简体) ), fit, (中文(简体) ), zoomTo, (中文(简体) ), zoomBy, (中文(简体) ), centerOn, (中文(简体) ), toWorld, (中文(简体) ), toLayout, (中文(简体) ), toClient, (中文(简体) ), claim 编辑 controller。 。 。 . useCameraOn(ref, opts) 和打电话的人一样.

没有捕捉到指针:在向窗口发泡时听到动作 (某事阻止了一个人的手势) 在下行的路上, 所以,一个离开板子的平板 继续前进,一个升降机在任何地方结束 指针; PointerBook 修理升降机 从来没有到达。 中学 鼠标按钮从不平板;侧道滚动从不缩放. 一个长压 以解释发送 CAMERA_CLAIM_EVENT 一、导 言 它下面的相机 放弃了其余的媒体(没有锅,没有水龙头).

@anweather/plugin-board-kit/testing是因为 rigCamera(config) 驱动 装入假窗口的机器 node:test (这个包裹) test/cameraController.test.ts) (中文(简体) ).

useCanvasCamera (折旧) 保持其签字和合同 游戏本身 onPointerDown/Move/Up/Cancel (世界坐标, 反应事件, 声称其余的序列) 作为包装 结束 useCamera。改变了的是相机本身的行为:修正 车轮的出站正好是1分之1的倒数, (没有0.9个).

董事会框架

全屏为克能游戏布局. 登记条目 fullScreenBoard: true 获得 FullScreenBoard 改为 GamePage是因为 列: 100dvh 感觉根被安全区域插件加入一次,一个框 标记 data-fullscreen-board 这是董事会的整个区域及其 滚动容器, qq BoardCornerMenu 浮在那个盒子上 左上方,在56px侧设置和结果之间沿上方注意 底部的卡片. useBoardFrame 董事会如何理解合同 (它取代灵岛) useFrame 及其在卡坦语和 阴道和战术 fullScreen.ts:

const [el, ref] = useState<HTMLDivElement | null>(null)
const frame = useBoardFrame(el, { wideAspect: 1.15, minHeight: 360 })
<div ref={ref} style={{ height: frame.height ?? 560, flexDirection: frame.wide ? 'row' : 'column' }}>
  <Header style={{ paddingLeft: frame.menuReserve }} />
</div>

将元件本身传递(回调回调为状态),而非回调对象, 钩子一旦存在就会运行 它返回( E)BoardFrame:

  • full:在站台的盒子内. 礛 height 这正是盒子的 (a) 调整观察员的大小使其保持当前:电话转接、工具栏 崩溃、 框卷轴和套件已经应用: 永远 再给他们一个垫子.
  • menuReserve数字 : MENU_RESERVE (48) 而平台的qq浮出水面 盒子是左上方的, 否则0。 保持48px平方块(MENU_CORNER_RECT, (中文(简体) ), overlapsMenuCorner(rect)没有任何可挖掘的、可长压的 或必须读取。 默认是... ... 坐在平台上方 栏 上文 盒子(盒子说: data-fullscreen-menu="bar", (中文(简体) ), menuInBar(box)),且保留地为 0;只有选择退出的游戏 栏(登记) fullScreenTopBar: false)得到浮起相角. 读取 frame.menuReserve 而不是说 MENU_RESERVE 自己,所以一个板 随其所入.
  • width, (中文(简体) ), height: 元素的宽度; 在普通页面上的高度 从它的顶端到取景口的底部(平台的铬) 上面算着 topCap,至少40%的取景点) minHeight (数目,或 { tall, wide }) (中文(简体) ).
  • layout 编号 : wide: 宽度/ 高时宽度 > wideAspect (默认) 1.2)和宽度 minWideWidth (默认为0). 灵岛1.2, catan 1.15,葡萄栽培1.05与900px.
  • insets: 仅与 viewportFallback: true,固定在 没有平台框的赤色取景口——全屏和板垫 SAFE_AREA 自己来 没有平台布局产生一个.
  • box:盒子元素,一旦找到.

在测量前(静态渲染, 第一种颜料),它是 UNMEASURED_FRAME:不满而高也,无大小也. 在盒子里,它变成一个 阴影山主机 overflow-x: hidden 输入 clip 挂载时 (单位:千美元)clipHost,默认在),所以粘贴头会粘住盒子,而不是 永不滚动的主机; 通过的注册项 hostOverflowX="clip" 已经拥有了.

纯净的一半是 boardFrame.ts (单位:千美元)computeFrame, (中文(简体) ), frameLayout, (中文(简体) ), findFullScreenBox,常数),所有可测试的节点. 常数 是平台本身的编号: MENU_BUTTON_INSET 8号, MENU_BUTTON_SIZE 40 (中文(简体) )BoardCornerMenu, (中文(简体) ), NOTICE_SIDE_INSET 页:1 RESULT_CARD_INSET 第12条 (单位:千美元)FullScreenBoard) (中文(简体) ). test/boardFrame.test.ts 阅读这两个平台 文件如果停止匹配则失败, 因此移动菜单意味着 改变两个都在一个公关.

不是这里(yet):一个"这是电话"的断点. 其他董事会的支票 不同的问题(520px和 (pointer: coarse)760px以下的三行窗口 垄断 900px以下的容器,q-blood的连续尺度; 将其折叠成 一个帮手会改变每个人的工作 让他们留在自己的董事会里 直到每个移动到全屏幕. frameLayout(w, h, { wideAspect: 0, minWideWidth: 900 }) 已经说垄断.

发展中国家

npm ci && npm run build && npm test && npm run typecheck

npm test 包括纯助行者(转弯、团队和时钟算术)、 相机的数学和指针机,相机框的算术(及其 常数与平台本身的FullScreenBoard和BoardCornerMenu相对应, 钩子变成静止 标记,带有 node:test; 组件按键检查并使用 消费者拥有Playwright套房. 尝试一个未公布的更改 消费者, npm pack 在这里安装柏油球,消费者的 package.json 永远不要用路径指向这个目录,因为 file: 链接解析 react 通过此目录本身 node_modules 并重新引入两反应包.

版本与发布记录

@anweather/plugin-board-kit 共发布 33 个版本,首次发布于 2026/09/29;过去 12 个月发布了 33 个版本。

版本发布日期距今
1.34.0latest2026/11/034 天前
1.33.02026/10/2513 天前
1.32.02026/10/2513 天前
1.31.02026/10/2513 天前
1.30.02026/10/2414 天前
1.29.22026/10/2414 天前

关于 @anweather/plugin-board-kit 的常见问题

@anweather/plugin-board-kit 是什么?

用于网页游戏平台游戏板的板-UI原始:挂载/更新/卸载处理远程插件的捆绑导出,板壳/TurnIdentity布局,转会/观察/团队帮助,转会时钟显示一半,板相机(pinch,拖放,whie)

如何安装 @anweather/plugin-board-kit?

在项目目录运行 npm install @anweather/plugin-board-kit,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:react(^19.0.0)、react-dom(^19.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@anweather/plugin-board-kit 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@anweather/plugin-board-kit 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@anweather/plugin-board-kit 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@anweather/plugin-board-kit 可以商用吗?

@anweather/plugin-board-kit 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@anweather/plugin-board-kit 的下载量有多少?

根据 npm 官方下载统计,@anweather/plugin-board-kit 在 2026/10/06 – 2026/11/04 这 30 天内被下载 2,183 次,日均约 73 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@anweather/plugin-board-kit 还在维护吗?

最新版本 1.34.0 发布于 2026/11/03(4 天前);至今共发布 33 个版本,其中过去 12 个月发布了 33 个;首次发布于 2026/09/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。