UNPKG

@leafer/canvas-miniapp

Version:
130 lines (101 loc) 4.17 kB
import { IResizeEventListener, IAutoBounds, IScreenSizeData, IFunction, IMiniappSelect, IObject, ICanvasContext2D } from '@leafer/interface' import { LeaferCanvasBase, canvasPatch, canvasSizeAttrs, Platform, DataHelper, ResizeEvent, isString, isNumber, isUndefined } from '@leafer/core' export class LeaferCanvas extends LeaferCanvasBase { public get allowBackgroundColor(): boolean { return false } public viewSelect: IMiniappSelect public resizeListener: IResizeEventListener public testView: any public testContext: ICanvasContext2D public init(): void { const { config } = this let view = config.view || config.canvas if (view) { if (isString(view)) { if (view[0] !== '#') view = '#' + view this.viewSelect = Platform.miniapp.select(view) } else if (view.fields) { this.viewSelect = view } else { this.initView(view) } if (this.viewSelect) Platform.miniapp.getSizeView(this.viewSelect).then(sizeView => { this.initView(sizeView) }) } else { this.initView() } } protected initView(view?: IObject): void { if (!view) { view = {} this.__createView() } else { this.view = view.view || view } this.view.getContext ? this.__createContext() : this.unrealCanvas() const { width, height, pixelRatio } = this.config const size = { width: width || view.width, height: height || view.height, pixelRatio } this.resize(size) if (this.context) { if (this.viewSelect) Platform.renderCanvas = this // fix roundRect if (this.context.roundRect) { this.roundRect = function (x: number, y: number, width: number, height: number, radius?: number | number[]): void { this.context.roundRect(x, y, width, height, isNumber(radius) ? [radius] : radius) } } canvasPatch((this.context as IObject).__proto__) } } protected __createView(): void { this.view = Platform.origin.createCanvas(1, 1) } public updateViewSize(): void { if (this.unreal) return const { width, height, pixelRatio } = this this.view.width = Math.ceil(width * pixelRatio) this.view.height = Math.ceil(height * pixelRatio) } public updateClientBounds(callback?: IFunction): void { if (this.viewSelect) Platform.miniapp.getBounds(this.viewSelect).then(bounds => { this.clientBounds = bounds // 抖音小程序 boundingClientRect() 会重置 Canvas 尺寸 this.updateViewSize() if (callback) callback() }) } public startAutoLayout(autoBounds: IAutoBounds, listener: IResizeEventListener): void { if (this.resizeListener) return this.resizeListener = listener if (autoBounds) { this.checkSize = this.checkSize.bind(this) Platform.miniapp.onWindowResize(this.checkSize) } } public checkSize(): void { if (this.viewSelect) { setTimeout(() => { this.updateClientBounds(() => { const { width, height } = this.clientBounds const { pixelRatio } = this const size = { width, height, pixelRatio } if (!this.isSameSize(size)) this.emitResize(size) }) }, 500) } } public stopAutoLayout(): void { this.autoLayout = false this.resizeListener = null Platform.miniapp.offWindowResize(this.checkSize) } public unrealCanvas(): void { // App needs to use this.unreal = true } protected emitResize(size: IScreenSizeData): void { const oldSize = {} as IScreenSizeData DataHelper.copyAttrs(oldSize, this, canvasSizeAttrs) this.resize(size) if (!isUndefined(this.width)) this.resizeListener(new ResizeEvent(size, oldSize)) } }