Skip to content

Commit c261d55

Browse files
committed
Inline path coordinate calculation and use ctx.rect instead of path
1 parent 3d79134 commit c261d55

1 file changed

Lines changed: 31 additions & 12 deletions

File tree

src/draw.ts

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,21 @@ const COLORS = '0123456789abcdef'
2727

2828
const MIN_DEPTH = 3
2929
const MAX_DEPTH = Infinity
30-
const MAX_DRAW_CALLS = 1e4 // number of shapes to draw per frame
30+
const MAX_PREVIEW_DRAW_CALLS = 1e4 // number of shapes to draw per preview frame
3131
const MAX_DRAW_TIME_MS = 15 // how long to draw a frame in ms
3232
const MAX_QUEUE_SIZE = 1e6
3333
const MIN_PATTERN_SIZE = 0.0005 // ignore patterns where either side is smaller than this
3434
const DEBUG = true as boolean
3535

3636
// -- helper functions
3737

38+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
3839
const mapPatternToViewportSpace = (pattern: AbsolutePattern, screenSize: Size): ViewportPattern => ({
3940
anchor: mapPointToViewportSpace(pattern.anchor, screenSize),
4041
target: mapPointToViewportSpace(pattern.target, screenSize),
4142
})
4243

44+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
4345
const getPatternPoints = <N extends PatternNumber>(
4446
pattern: Pattern<N>
4547
): [Point<N>, Point<N>, Point<N>, Point<N>] => {
@@ -235,25 +237,42 @@ export function* drawFrameIncrementally(
235237
// Draw screen
236238
ctx.strokeStyle = COLORS[Math.min(COLORS.length - 1, depth)]!
237239
ctx.beginPath()
238-
240+
241+
// Optimization: Only allocate variables once.
242+
let xMin: number
243+
let yMin: number
244+
let xMax: number
245+
let yMax: number
246+
let x1: number
247+
let y1: number
248+
let x2: number
249+
let y2: number
250+
239251
for (const absolutePattern of patterns) {
240-
const viewportPattern = mapPatternToViewportSpace(absolutePattern, screenSize)
241-
const [p1, p2, p3, p4] = getPatternPoints(viewportPattern)
242-
243-
ctx.moveTo(...p1)
244-
ctx.lineTo(...p2)
245-
ctx.lineTo(...p3)
246-
ctx.lineTo(...p4)
247-
ctx.closePath()
252+
// Convert to viewport space.
253+
x1 = Math.round(absolutePattern.anchor[0] * screenSize[0])
254+
y1 = Math.round(absolutePattern.anchor[1] * screenSize[1])
255+
x2 = Math.round(absolutePattern.target[0] * screenSize[0])
256+
y2 = Math.round(absolutePattern.target[1] * screenSize[1])
257+
258+
// Get boundaries.
259+
// Optimization: Do not use getBoundariesFromPattern because it creates too many objects.
260+
xMin = Math.min(x1, x2)
261+
yMin = Math.min(y1, y2)
262+
xMax = Math.max(x1, x2)
263+
yMax = Math.max(y1, y2)
264+
265+
// Draw rectangle.
266+
ctx.rect(xMin, yMin, xMax - xMin, yMax - yMin)
248267
}
249268

250269
ctx.fill()
251270
ctx.stroke()
252271

253272
if (iterations === 1) {
254273
// On the first iteration, draw until passing both MIN_DEPTH and MAX_DRAW_CALLS.
255-
// We don't want to use a time-based limit here because it would cause flickering.
256-
if (depth > MIN_DEPTH && drawScreenCalls >= MAX_DRAW_CALLS) {
274+
// We don't want to use a time-based limit here because it could cause flickering.
275+
if (depth > MIN_DEPTH && drawScreenCalls >= MAX_PREVIEW_DRAW_CALLS) {
257276
break
258277
}
259278
} else {

0 commit comments

Comments
 (0)