Skip to content

Commit

Permalink
opt: render
Browse files Browse the repository at this point in the history
  • Loading branch information
liihuu committed Jan 9, 2024
1 parent 68a1954 commit bbad15d
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 38 deletions.
54 changes: 40 additions & 14 deletions src/common/Canvas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -28,6 +29,8 @@ async function isSupportedDevicePixelContentBox (): Promise<boolean> {
}).catch(() => false)
}

const DEFAULT_REQUEST_ANIMATION_ID = -1

export default class Canvas {
private readonly _element: HTMLCanvasElement
private _resizeObserver: ResizeObserver
Expand All @@ -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()
Expand Down Expand Up @@ -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 {
Expand Down
30 changes: 6 additions & 24 deletions src/widget/DrawWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<P extends DrawPane = DrawPane> extends Widget<P> {
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({
Expand All @@ -42,13 +36,7 @@ export default abstract class DrawWidget<P extends DrawPane = DrawPane> 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',
Expand All @@ -57,13 +45,7 @@ export default abstract class DrawWidget<P extends DrawPane = DrawPane> 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())
Expand Down Expand Up @@ -95,17 +77,17 @@ export default abstract class DrawWidget<P extends DrawPane = DrawPane> 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
}
}
Expand Down

0 comments on commit bbad15d

Please sign in to comment.