@@ -27,19 +27,21 @@ const COLORS = '0123456789abcdef'
2727
2828const MIN_DEPTH = 3
2929const 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
3131const MAX_DRAW_TIME_MS = 15 // how long to draw a frame in ms
3232const MAX_QUEUE_SIZE = 1e6
3333const MIN_PATTERN_SIZE = 0.0005 // ignore patterns where either side is smaller than this
3434const DEBUG = true as boolean
3535
3636// -- helper functions
3737
38+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
3839const 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
4345const 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