From bbad15dee23b313d922ff3765f8cc84c1ebd3649 Mon Sep 17 00:00:00 2001 From: liihuu Date: Wed, 10 Jan 2024 00:21:27 +0800 Subject: [PATCH] opt: render --- src/common/Canvas.ts | 54 +++++++++++++++++++++++++++++----------- src/widget/DrawWidget.ts | 30 +++++----------------- 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/common/Canvas.ts b/src/common/Canvas.ts index 030e875bb..085c7dbd2 100644 --- a/src/common/Canvas.ts +++ b/src/common/Canvas.ts @@ -15,6 +15,7 @@ import { getPixelRatio } from './utils/canvas' import { createDom } from './utils/dom' import { isValid } from './utils/typeChecks' +import { requestAnimationFrame, cancelAnimationFrame } from './utils/compatible' type DrawListener = () => void @@ -28,6 +29,8 @@ async function isSupportedDevicePixelContentBox (): Promise { }).catch(() => false) } +const DEFAULT_REQUEST_ANIMATION_ID = -1 + export default class Canvas { private readonly _element: HTMLCanvasElement private _resizeObserver: ResizeObserver @@ -39,9 +42,14 @@ export default class Canvas { private _supportedDevicePixelContentBox = false + private _width = 0 + private _height = 0 + private _pixelWidth = 0 private _pixelHeight = 0 + private _requestAnimationId = DEFAULT_REQUEST_ANIMATION_ID + private readonly _mediaQueryListener: () => void = () => { const pixelRatio = getPixelRatio(this._element) const { width, height } = this._element.getBoundingClientRect() @@ -86,28 +94,46 @@ export default class Canvas { horizontalPixelRatio: number, verticalPixelRatio: number ): void { - this._pixelWidth = pixelWidth - this._pixelHeight = pixelHeight - this._element.width = pixelWidth - this._element.height = pixelHeight - this._ctx.scale(horizontalPixelRatio, verticalPixelRatio) - this._listener() + this._executeListener(() => { + const { width, height } = this._element.getBoundingClientRect() + this._width = width + this._height = height + this._pixelWidth = pixelWidth + this._pixelHeight = pixelHeight + this._element.width = pixelWidth + this._element.height = pixelHeight + this._ctx.scale(horizontalPixelRatio, verticalPixelRatio) + }) } - setSize (w: number, h: number): void { - const { width, height } = this._element.getBoundingClientRect() - this._ctx.clearRect(0, 0, width, height) - if (w !== width || h !== height) { + private _executeListener (fn?: () => void): void { + if (this._requestAnimationId !== DEFAULT_REQUEST_ANIMATION_ID) { + cancelAnimationFrame(this._requestAnimationId) + this._requestAnimationId = DEFAULT_REQUEST_ANIMATION_ID + } + this._requestAnimationId = requestAnimationFrame(() => { + this._ctx.clearRect(0, 0, this._width, this._height) + fn?.() + this._listener() + }) + } + + update (w: number, h: number): void { + if (this._width !== w || this._height !== h) { this._element.style.width = `${w}px` this._element.style.height = `${h}px` if (!this._supportedDevicePixelContentBox) { const pixelRatio = getPixelRatio(this._element) - this._element.width = Math.round(w * pixelRatio) - this._element.height = Math.round(h * pixelRatio) - this._ctx.scale(pixelRatio, pixelRatio) + this._resetPixelRatio( + Math.round(w * pixelRatio), + Math.round(h * pixelRatio), + pixelRatio, + pixelRatio + ) } + } else { + this._executeListener() } - this._listener() } getElement (): HTMLCanvasElement { diff --git a/src/widget/DrawWidget.ts b/src/widget/DrawWidget.ts index 327eddb79..9f55df558 100644 --- a/src/widget/DrawWidget.ts +++ b/src/widget/DrawWidget.ts @@ -22,17 +22,11 @@ import Widget from './Widget' import { createDom } from '../common/utils/dom' import { getPixelRatio } from '../common/utils/canvas' -import { requestAnimationFrame, cancelAnimationFrame } from '../common/utils/compatible' - -const DEFAULT_REQUEST_ID = -1 export default abstract class DrawWidget

extends Widget

{ private _mainCanvas: Canvas private _overlayCanvas: Canvas - private _mainRequestAnimationId: number = DEFAULT_REQUEST_ID - private _overlayRequestAnimationId: number = DEFAULT_REQUEST_ID - override init (rootContainer: HTMLElement): void { super.init(rootContainer) this._mainCanvas = new Canvas({ @@ -42,13 +36,7 @@ export default abstract class DrawWidget

extends zIndex: '2', boxSizing: 'border-box' }, () => { - if (this._mainRequestAnimationId !== DEFAULT_REQUEST_ID) { - cancelAnimationFrame(this._mainRequestAnimationId) - this._mainRequestAnimationId = DEFAULT_REQUEST_ID - } - this._mainRequestAnimationId = requestAnimationFrame(() => { - this.updateMain(this._mainCanvas.getContext()) - }) + this.updateMain(this._mainCanvas.getContext()) }) this._overlayCanvas = new Canvas({ position: 'absolute', @@ -57,13 +45,7 @@ export default abstract class DrawWidget

extends zIndex: '2', boxSizing: 'border-box' }, () => { - if (this._overlayRequestAnimationId !== DEFAULT_REQUEST_ID) { - cancelAnimationFrame(this._overlayRequestAnimationId) - this._overlayRequestAnimationId = DEFAULT_REQUEST_ID - } - this._overlayRequestAnimationId = requestAnimationFrame(() => { - this.updateOverlay(this._overlayCanvas.getContext()) - }) + this.updateOverlay(this._overlayCanvas.getContext()) }) const container = this.getContainer() container.appendChild(this._mainCanvas.getElement()) @@ -95,17 +77,17 @@ export default abstract class DrawWidget

extends } switch (l) { case UpdateLevel.Main: { - this._mainCanvas.setSize(width, height) + this._mainCanvas.update(width, height) break } case UpdateLevel.Overlay: { - this._overlayCanvas.setSize(width, height) + this._overlayCanvas.update(width, height) break } case UpdateLevel.Drawer: case UpdateLevel.All: { - this._mainCanvas.setSize(width, height) - this._overlayCanvas.setSize(width, height) + this._mainCanvas.update(width, height) + this._overlayCanvas.update(width, height) break } }