图片渲染器
若你的插件中有存在发送自定义图片的指令,那么你可能需要用到图片渲染器这个功能。
注册图片渲染器
图片渲染器本质为通过 Puppeteer 来打开指定路径的网页,并对指定的元素进行截图,并得到图片的 base64
格式内容。
常规注册方式
可通过 renderer.register
来注册得到一个图片渲染器,它的类型与使用方式如下:
interface RenderMethods {
register( route: string, defaultSelector: string ): Renderer;
}
// 注册渲染器
const renderer = bot.renderer.register( "/test-plugin", "#app" );
// 截取路径 /test-plugin/test.html 的网页中 id 为 app 的元素,并得到图片的 base64 格式
renderer.asBase64( "/test.html" );
- route: 渲染器基地址,若你的所有待渲染页面均存在一个共同的基地址,可将其配置在此项,避免后续编写重复内容。反之请设置为
/
; - defaultSelector: 渲染器的默认 css 选择器,用于指定要在页面中截图的内容。
对于 route
参数,分为两种情况:
- 当使用框架集成的 vue-router 时,建议传递插件名称
- 当使用框架集成的静态资源服务器时,建议传递以
plugins
目录为基准的页面所在的目录路径,如/genshin/views
renderRegister
我们还为插件提供了更方便的渲染器注册方法,你可以在插件的 mounted
生命周期钩子中使用 params.renderRegister
来直接注册渲染器。
该方法仅需要 defaultSelector
一个参数,它将会自动获取插件根目录名称,以 /插件目录名
的格式作为基地址参数 route
向 bot.renderer.register
传递。
示例如下:
/* test-plugin 插件 */
export default definePlugin( {
mounted( params ) {
renderer = params.renderRegister( "#app" );
// 等同于
render = params.renderer.register( "/test-plugin", "#app" );
}
} );
渲染器方法
我们为渲染器提供了三种渲染方法,类型如下:
interface ScreenshotRendererMethods {
asBase64( route: string, params?: Record<string, any>, viewPort?: puppeteer.Viewport | null, selector?: string ): Promise<RenderResult>;
asSegment( route: string, params?: Record<string, any>, viewPort?: puppeteer.Viewport | null, selector?: string ): Promise<RenderResult>;
asForFunction( route: string, pageFunction: PageFunction, viewPort?: puppeteer.Viewport | null, params?: Record<string, any> ): Promise<RenderResult>;
}
这里对三种方法共同拥有的参数做出说明:
- route: 要打开的目标网站地址,相对于上面注册渲染器时提供的基地址而定。如目标地址为
/test-plugin/test.html
,基地中定义了/test-plugin
,那么这里只需要指定为/test.html
即可。 - viewPort: 可选参数,用于设置页面的视口,详见 Viewport interface。
- params: 可选参数,对象格式,将被格式化为
a=x&b=x
的键值对格式跟随在route
后,作为查询参数使用。
需要注意的是,对于
viewPort
参数,由于存在 directive.yml/imageQuality 配置项, 如果您设置了viewport.deviceScaleFactor
,框架将会把这两者的值做相乘处理并应用于最终的缩放倍数。若最终计算结果超过了5
,则会以5
作为最终值。这在代码中是这样实现的(src/modules/renderer.ts:206):
typescript// 若开发者指定了缩放比例,则将开发者指定的缩放比例乘以用户方所配置的缩放比例,考虑到设备承受能力问题,结果最大不能超过 5 private getViewport( viewPort: puppeteer.Viewport ): puppeteer.Viewport { const factor = ( viewPort.deviceScaleFactor || 1 ) * this.config.imageQuality; return { ...viewPort, deviceScaleFactor: factor > 5 ? 5 : factor } }
三者存在共同的返回值类型 RenderResult
:
interface RenderSuccess {
code: "ok";
data: Sendable;
}
interface RenderError {
code: "error";
error: string;
}
export type RenderResult = RenderSuccess | RenderError;
即当渲染成功时,返回包含 code
与 截图内容 data
的对象,code
值为 ok
。反之为包含 code
与 错误提示消息 error
的对象,code
值为 error
。
asBase64
存在 selector
参数,用于覆盖注册渲染器时所设置的默认 css 选择器。
当截图成功时,其返回的 data
永远为 string
类型,即 base64 字符串。
asSegment
参数与 asBase64 完全一直,返回值类型有所不同。
此方法返回的 data
为 ImageElem
类型数据,可直接使用 sendMessage
发送或填入数组与其他可发送类型组合后使用 sendMessage
发送。
asForFunction
此方法旨在满足开发者开放式的截图渲染需求,其接受一个允许开发者进行自定义行为的方法 pageFunction
:
interface PageFunction {
( page: puppeteer.Page ): Promise<Buffer | string | void>
}
该方法接受一个 puppeteer.Page 类型的参数 page
,该参数是 puppeteer 中的页面对象,支持对当前页面进行几乎所有人工可以完成的操作。
当执行完编写的自定义行为后,你需要在此参数方法中返回一个 Buffer | string | void
类型的数据,这个数据将会通过 toString
处理后,作为 asForFunction
的返回值中的 data
内容进行返回。
若你未在 pageFunction 方法中返回任何内容,即
void
返回值类型,那么在最终的data
属性中你将得到一个空字符串值""
。