packages/core/src/canvas/picture-recorder.ts (50 lines of code) (raw):

import { assert } from '@canvas-ui/assert' import { Rect } from '../math' import type { Canvas } from './canvas' import { Picture } from './picture' import { RecorderCanvas } from './recorder-canvas' export class PictureRecoder { private canvas?: RecorderCanvas private cullRect?: Rect begin(cullRect: Rect = Rect.zero): Canvas { assert(!this.canvas) this.cullRect = cullRect this.canvas = new RecorderCanvas() return this.canvas } end() { assert(this.canvas) assert(this.cullRect) const { clipBoundses, drawBoundses, drawOps, hasDrawText, } = this.canvas // 如果没有提供 cullRect // 我们通过 boundses 计算可以容纳所有元素的 cullRect if (Rect.isEmpty(this.cullRect)) { let totalPaintBounds = drawBoundses.length > 0 ? drawBoundses[0] : Rect.zero let totalClipBounds = clipBoundses.length > 0 ? clipBoundses[0] : Rect.zero let i = 1 let n = drawBoundses.length for (i = 1; i < n; i++) { totalPaintBounds = Rect.expandToInclude(totalPaintBounds, drawBoundses[i]) } n = clipBoundses.length for (i = 1; i < n; i++) { totalClipBounds = Rect.expandToInclude(totalClipBounds, clipBoundses[i]) } if (Rect.isEmpty(totalClipBounds)) { this.cullRect = totalPaintBounds } else if (Rect.overlaps(totalPaintBounds, totalClipBounds)) { this.cullRect = Rect.intersect(totalPaintBounds, totalClipBounds) } else { this.cullRect = Rect.zero } } return Picture.from( drawOps, this.cullRect, hasDrawText, ) } }