chat-layout 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.mts CHANGED
@@ -200,6 +200,7 @@ type DrawItem<C extends CanvasRenderingContext2D> = {
200
200
  interface JumpToOptions {
201
201
  animated?: boolean;
202
202
  duration?: number;
203
+ onComplete?: () => void;
203
204
  }
204
205
  declare abstract class VirtualizedRenderer<C extends CanvasRenderingContext2D, T extends {}> extends BaseRenderer<C, {
205
206
  renderItem: (item: T) => Node<C>;
package/index.mjs CHANGED
@@ -640,18 +640,21 @@ var VirtualizedRenderer = class VirtualizedRenderer extends BaseRenderer {
640
640
  if (!(options.animated ?? true)) {
641
641
  this.#cancelJumpAnimation();
642
642
  this._applyAnchor(targetAnchor);
643
+ options.onComplete?.();
643
644
  return;
644
645
  }
645
646
  const startAnchor = this._readAnchor();
646
647
  if (!Number.isFinite(startAnchor)) {
647
648
  this.#cancelJumpAnimation();
648
649
  this._applyAnchor(targetAnchor);
650
+ options.onComplete?.();
649
651
  return;
650
652
  }
651
653
  const duration = clamp(options.duration ?? VirtualizedRenderer.MIN_JUMP_DURATION + Math.abs(targetAnchor - startAnchor) * VirtualizedRenderer.JUMP_DURATION_PER_ITEM, 0, VirtualizedRenderer.MAX_JUMP_DURATION);
652
654
  if (duration <= 0 || Math.abs(targetAnchor - startAnchor) <= Number.EPSILON) {
653
655
  this.#cancelJumpAnimation();
654
656
  this._applyAnchor(targetAnchor);
657
+ options.onComplete?.();
655
658
  return;
656
659
  }
657
660
  this.#jumpAnimation = {
@@ -659,7 +662,8 @@ var VirtualizedRenderer = class VirtualizedRenderer extends BaseRenderer {
659
662
  targetAnchor,
660
663
  startTime: getNow(),
661
664
  duration,
662
- needsMoreFrames: true
665
+ needsMoreFrames: true,
666
+ onComplete: options.onComplete
663
667
  };
664
668
  this.#controlledState = {
665
669
  position: this.position,
@@ -725,8 +729,10 @@ var VirtualizedRenderer = class VirtualizedRenderer extends BaseRenderer {
725
729
  };
726
730
  return true;
727
731
  }
732
+ const onComplete = animation.onComplete;
728
733
  this.#cancelJumpAnimation();
729
- return requestRedraw;
734
+ onComplete?.();
735
+ return requestRedraw || this.#jumpAnimation != null;
730
736
  }
731
737
  _clampItemIndex(index) {
732
738
  return clamp(Number.isFinite(index) ? Math.trunc(index) : 0, 0, this.items.length - 1);
package/index.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["#inner","#top","#bottom","#left","#right","#shift","#width","#lines","#text","#ctx","#lastWidth","#cache","#cancelJumpAnimation","#jumpAnimation","#controlledState"],"sources":["../src/text.ts","../src/utils.ts","../src/registry.ts","../src/nodes.ts","../src/renderer.ts"],"sourcesContent":["import { layoutWithLines, prepareWithSegments } from \"@chenglou/pretext\";\nimport type { Context } from \"./types\";\n\nexport interface TextLayout {\n width: number;\n text: string;\n shift: number;\n}\n\nfunction preprocessSegments(text: string): string[] {\n return text\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean);\n}\n\nexport function layoutFirstLine<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n): TextLayout {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n const segments = preprocessSegments(text);\n const segment = segments[0];\n if (!segment) {\n return { width: 0, text: \"\", shift: 0 };\n }\n const {\n fontBoundingBoxAscent: ascent = 0,\n fontBoundingBoxDescent: descent = 0,\n } = ctx.graphics.measureText(segment);\n const shift = ascent - descent;\n if (maxWidth === 0) {\n return { width: 0, text: \"\", shift };\n }\n const prepared = prepareWithSegments(segment, ctx.graphics.font);\n const { lines } = layoutWithLines(prepared, maxWidth, 0);\n if (lines.length === 0) {\n return { width: 0, text: \"\", shift };\n }\n return { width: lines[0].width, text: lines[0].text, shift };\n}\n\nexport function layoutText<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n): { width: number; lines: TextLayout[] } {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n\n const segments = preprocessSegments(text);\n if (segments.length === 0 || maxWidth === 0) {\n return { width: 0, lines: [] };\n }\n\n const font = ctx.graphics.font;\n let width = 0;\n const lines: TextLayout[] = [];\n\n for (const segment of segments) {\n const {\n fontBoundingBoxAscent: ascent = 0,\n fontBoundingBoxDescent: descent = 0,\n } = ctx.graphics.measureText(segment);\n const shift = ascent - descent;\n const prepared = prepareWithSegments(segment, font);\n const { lines: segLines } = layoutWithLines(prepared, maxWidth, 0);\n for (const segLine of segLines) {\n width = Math.max(width, segLine.width);\n lines.push({ width: segLine.width, text: segLine.text, shift });\n }\n }\n\n return { width, lines };\n}\n","export function shallow<T extends object>(object: T): T {\n return Object.create(object) as T;\n}\n\nexport function shallowMerge<T extends object, R extends object>(object: T, other: R): T & R {\n return { __proto__: object, ...other } as unknown as T & R;\n}\n","import type { Node } from \"./types\";\n\nconst registry = new WeakMap<Node<any>, Node<any>>();\n\nexport function registerNodeParent<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n parent: Node<C>,\n): void {\n registry.set(node, parent);\n}\n\nexport function unregisterNodeParent<C extends CanvasRenderingContext2D>(node: Node<C>): void {\n registry.delete(node);\n}\n\nexport function getNodeParent<C extends CanvasRenderingContext2D>(node: Node<C>): Node<C> | undefined {\n return registry.get(node);\n}\n","import type { Alignment, Box, Context, DynValue, HitTest, Node } from \"./types\";\nimport { layoutFirstLine, layoutText, type TextLayout } from \"./text\";\nimport { shallow, shallowMerge } from \"./utils\";\nimport { registerNodeParent, unregisterNodeParent } from \"./registry\";\n\nexport abstract class Group<C extends CanvasRenderingContext2D> implements Node<C> {\n constructor(readonly children: Node<C>[]) {\n for (const child of children) {\n registerNodeParent(child, this);\n }\n }\n\n abstract measure(ctx: Context<C>): Box;\n abstract draw(ctx: Context<C>, x: number, y: number): boolean;\n abstract hittest(ctx: Context<C>, test: HitTest): boolean;\n\n get flex(): boolean {\n return this.children.some((item) => item.flex);\n }\n}\n\nexport class VStack<C extends CanvasRenderingContext2D> extends Group<C> {\n constructor(\n children: Node<C>[],\n readonly options: { gap?: number; alignment?: \"left\" | \"center\" | \"right\" } = {},\n ) {\n super(children);\n }\n\n measure(ctx: Context<C>): Box {\n let width = 0;\n let height = 0;\n if (this.options.alignment != null) {\n ctx.alignment = this.options.alignment;\n }\n\n for (const [index, child] of this.children.entries()) {\n if (this.options.gap != null && index !== 0) {\n height += this.options.gap;\n }\n const result = shallow(ctx).measureNode(child);\n height += result.height;\n width = Math.max(width, result.width);\n }\n ctx.remainingWidth -= width;\n return { width, height };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n let result = false;\n const fullWidth = ctx.measureNode(this).width;\n const alignment = this.options.alignment ?? ctx.alignment;\n if (this.options.alignment != null) {\n ctx.alignment = this.options.alignment;\n }\n\n for (const [index, child] of this.children.entries()) {\n if (this.options.gap != null && index !== 0) {\n y += this.options.gap;\n }\n const { width, height } = shallow(ctx).measureNode(child);\n const curCtx = shallow(ctx);\n let requestRedraw: boolean;\n if (alignment === \"right\") {\n requestRedraw = child.draw(curCtx, x + fullWidth - width, y);\n } else if (alignment === \"center\") {\n requestRedraw = child.draw(curCtx, x + (fullWidth - width) / 2, y);\n } else {\n requestRedraw = child.draw(curCtx, x, y);\n }\n result ||= requestRedraw;\n y += height;\n }\n return result;\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n let y = 0;\n const fullWidth = ctx.measureNode(this).width;\n const alignment = this.options.alignment ?? ctx.alignment;\n if (this.options.alignment != null) {\n ctx.alignment = this.options.alignment;\n }\n\n for (const [index, child] of this.children.entries()) {\n if (this.options.gap != null && index !== 0) {\n y += this.options.gap;\n }\n\n const { width, height } = shallow(ctx).measureNode(child);\n const curCtx = shallow(ctx);\n if (test.y >= y && test.y < y + height) {\n let x: number;\n if (alignment === \"right\") {\n x = test.x - fullWidth + width;\n } else if (alignment === \"center\") {\n x = test.x - (fullWidth - width) / 2;\n } else {\n x = test.x;\n }\n if (x < 0 || x >= width) {\n return false;\n }\n return child.hittest(\n curCtx,\n shallowMerge(test, {\n x,\n y: test.y - y,\n }),\n );\n }\n y += height;\n }\n return false;\n }\n}\n\nexport class HStack<C extends CanvasRenderingContext2D> extends Group<C> {\n constructor(\n readonly children: Node<C>[],\n readonly options: { reverse?: boolean; gap?: number } = {},\n ) {\n super(children);\n }\n\n measure(ctx: Context<C>): Box {\n let width = 0;\n let height = 0;\n let firstFlex: Node<C> | undefined;\n\n for (const [index, child] of this.children.entries()) {\n if (this.options.gap != null && index !== 0) {\n width += this.options.gap;\n }\n if (firstFlex == null && child.flex) {\n firstFlex = child;\n continue;\n }\n const curCtx = shallow(ctx);\n curCtx.remainingWidth = ctx.remainingWidth - width;\n const result = curCtx.measureNode(child);\n width += result.width;\n height = Math.max(height, result.height);\n }\n\n if (firstFlex != null) {\n const curCtx = shallow(ctx);\n curCtx.remainingWidth = ctx.remainingWidth - width;\n const result = curCtx.measureNode(firstFlex);\n width += result.width;\n height = Math.max(height, result.height);\n }\n\n return { width, height };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n let result = false;\n const reverse = this.options.reverse ?? ctx.reverse;\n if (this.options.reverse) {\n ctx.reverse = this.options.reverse;\n }\n\n if (reverse) {\n x += ctx.measureNode(this).width;\n for (const [index, child] of this.children.entries()) {\n const gap = this.options.gap != null && index !== 0 ? this.options.gap : undefined;\n if (gap) {\n x -= gap;\n ctx.remainingWidth -= gap;\n }\n const { width } = shallow(ctx).measureNode(child);\n x -= width;\n const requestRedraw = child.draw(shallow(ctx), x, y);\n result ||= requestRedraw;\n ctx.remainingWidth -= width;\n }\n } else {\n for (const [index, child] of this.children.entries()) {\n const gap = this.options.gap != null && index !== 0 ? this.options.gap : undefined;\n if (gap) {\n x += gap;\n ctx.remainingWidth -= gap;\n }\n const requestRedraw = child.draw(shallow(ctx), x, y);\n result ||= requestRedraw;\n const { width } = shallow(ctx).measureNode(child);\n ctx.remainingWidth -= width;\n x += width;\n }\n }\n\n return result;\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n const reverse = this.options.reverse ?? ctx.reverse;\n if (this.options.reverse) {\n ctx.reverse = this.options.reverse;\n }\n\n if (reverse) {\n let x = ctx.measureNode(this).width;\n for (const [index, child] of this.children.entries()) {\n const gap = this.options.gap != null && index !== 0 ? this.options.gap : undefined;\n if (gap) {\n x -= gap;\n ctx.remainingWidth -= gap;\n }\n const { width, height } = shallow(ctx).measureNode(child);\n x -= width;\n if (x <= test.x && test.x < x + width) {\n if (test.y >= height) {\n return false;\n }\n return child.hittest(\n shallow(ctx),\n shallowMerge(test, {\n x: test.x - x,\n }),\n );\n }\n ctx.remainingWidth -= width;\n }\n } else {\n let x = 0;\n for (const [index, child] of this.children.entries()) {\n const gap = this.options.gap != null && index !== 0 ? this.options.gap : undefined;\n if (gap) {\n x += gap;\n ctx.remainingWidth -= gap;\n }\n const { width, height } = shallow(ctx).measureNode(child);\n if (x <= test.x && test.x < x + width) {\n if (test.y >= height) {\n return false;\n }\n return child.hittest(\n shallow(ctx),\n shallowMerge(test, {\n x: test.x - x,\n }),\n );\n }\n x += width;\n ctx.remainingWidth -= width;\n }\n }\n\n return false;\n }\n}\n\nexport class Wrapper<C extends CanvasRenderingContext2D> implements Node<C> {\n #inner: Node<C>;\n\n constructor(inner: Node<C>) {\n this.#inner = inner;\n registerNodeParent(this.#inner, this);\n }\n\n get inner(): Node<C> {\n return this.#inner;\n }\n\n set inner(newNode: Node<C>) {\n if (newNode === this.#inner) {\n return;\n }\n unregisterNodeParent(this.#inner);\n this.#inner = newNode;\n registerNodeParent(newNode, this);\n }\n\n get flex(): boolean {\n return this.inner.flex;\n }\n\n measure(ctx: Context<C>): Box {\n return this.inner.measure(ctx);\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return this.inner.draw(ctx, x, y);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n return this.inner.hittest(ctx, test);\n }\n}\n\nexport class PaddingBox<C extends CanvasRenderingContext2D> extends Wrapper<C> {\n constructor(\n inner: Node<C>,\n readonly padding: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n } = {},\n ) {\n super(inner);\n }\n\n get #top(): number {\n return this.padding.top ?? 0;\n }\n\n get #bottom(): number {\n return this.padding.bottom ?? 0;\n }\n\n get #left(): number {\n return this.padding.left ?? 0;\n }\n\n get #right(): number {\n return this.padding.right ?? 0;\n }\n\n measure(ctx: Context<C>): Box {\n ctx.remainingWidth -= this.#left + this.#right;\n const { width, height } = ctx.measureNode(this.inner);\n return {\n width: width + this.#left + this.#right,\n height: height + this.#top + this.#bottom,\n };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n ctx.remainingWidth -= this.#left + this.#right;\n return this.inner.draw(ctx, x + this.#left, y + this.#top);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n ctx.remainingWidth -= this.#left + this.#right;\n const { width, height } = shallow(ctx).measureNode(this.inner);\n if (0 <= test.x - this.#left && test.x - this.#left < width && 0 <= test.y - this.#top && test.y - this.#top < height) {\n return this.inner.hittest(\n shallow(ctx),\n shallowMerge(test, {\n x: test.x - this.#left,\n y: test.y - this.#top,\n }),\n );\n }\n return false;\n }\n}\n\nexport class AlignBox<C extends CanvasRenderingContext2D> extends Wrapper<C> {\n #shift = 0;\n\n constructor(\n inner: Node<C>,\n readonly options: {\n alignment: Alignment;\n },\n ) {\n super(inner);\n }\n\n measure(ctx: Context<C>): Box {\n ctx.alignment = this.options.alignment;\n const { width, height } = ctx.measureNode(this.inner);\n switch (this.options.alignment) {\n case \"center\":\n this.#shift = (ctx.remainingWidth - width) / 2;\n break;\n case \"right\":\n this.#shift = ctx.remainingWidth - width;\n break;\n default:\n this.#shift = 0;\n }\n return {\n width: ctx.remainingWidth,\n height,\n };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n ctx.alignment = this.options.alignment;\n return this.inner.draw(ctx, x + this.#shift, y);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n ctx.alignment = this.options.alignment;\n const { width } = shallow(ctx).measureNode(this.inner);\n if (0 <= test.x - this.#shift && test.x - this.#shift < width) {\n return this.inner.hittest(\n shallow(ctx),\n shallowMerge(test, {\n x: test.x - this.#shift,\n }),\n );\n }\n return false;\n }\n}\n\nexport class MultilineText<C extends CanvasRenderingContext2D> implements Node<C> {\n #width = 0;\n #lines: TextLayout[] = [];\n\n constructor(\n readonly text: string,\n readonly options: {\n lineHeight: number;\n font: string;\n alignment: \"left\" | \"center\" | \"right\";\n style: DynValue<C, string>;\n },\n ) {}\n\n get flex(): boolean {\n return true;\n }\n\n measure(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width, lines } = layoutText(ctx, this.text, ctx.remainingWidth);\n this.#width = width;\n this.#lines = lines;\n return { width: this.#width, height: this.#lines.length * this.options.lineHeight };\n });\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return ctx.with((g) => {\n g.font = this.options.font;\n g.fillStyle = ctx.resolveDynValue(this.options.style);\n switch (this.options.alignment) {\n case \"left\":\n for (const { text, shift } of this.#lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n case \"right\":\n x += this.#width;\n g.textAlign = \"right\";\n for (const { text, shift } of this.#lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n case \"center\":\n x += this.#width / 2;\n g.textAlign = \"center\";\n for (const { text, shift } of this.#lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n }\n return false;\n });\n }\n\n hittest(_ctx: Context<C>, _test: HitTest): boolean {\n return false;\n }\n}\n\nexport class Text<C extends CanvasRenderingContext2D> implements Node<C> {\n #width = 0;\n #text = \"\";\n #shift = 0;\n\n constructor(\n readonly text: string,\n readonly options: {\n lineHeight: number;\n font: string;\n style: DynValue<C, string>;\n },\n ) {}\n\n get flex(): boolean {\n return false;\n }\n\n measure(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width, text, shift } = layoutFirstLine(ctx, this.text, ctx.remainingWidth);\n this.#width = width;\n this.#text = text;\n this.#shift = shift;\n return { width: this.#width, height: this.options.lineHeight };\n });\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return ctx.with((g) => {\n g.font = this.options.font;\n g.fillStyle = ctx.resolveDynValue(this.options.style);\n g.fillText(this.#text, x, y + (this.options.lineHeight + this.#shift) / 2);\n return false;\n });\n }\n\n hittest(_ctx: Context<C>, _test: HitTest): boolean {\n return false;\n }\n}\n\nexport class Fixed<C extends CanvasRenderingContext2D> implements Node<C> {\n constructor(\n readonly width: number,\n readonly height: number,\n ) {}\n\n get flex(): boolean {\n return false;\n }\n\n measure(_ctx: Context<C>): Box {\n return { width: this.width, height: this.height };\n }\n\n draw(_ctx: Context<C>, _x: number, _y: number): boolean {\n return false;\n }\n\n hittest(_ctx: Context<C>, _test: HitTest): boolean {\n return false;\n }\n}\n","import type { Box, Context, DynValue, HitTest, Node, RenderFeedback, RendererOptions } from \"./types\";\nimport { shallow, shallowMerge } from \"./utils\";\nimport { getNodeParent } from \"./registry\";\n\nexport class BaseRenderer<C extends CanvasRenderingContext2D, O extends {} = {}> {\n graphics: C;\n #ctx: Context<C>;\n #lastWidth: number;\n #cache = new WeakMap<Node<C>, Box>();\n\n protected get context(): Context<C> {\n return shallow(this.#ctx);\n }\n\n constructor(\n graphics: C,\n readonly options: RendererOptions & O,\n ) {\n this.graphics = graphics;\n this.graphics.textRendering = \"optimizeLegibility\";\n const self = this;\n this.#ctx = {\n graphics: this.graphics,\n get remainingWidth() {\n return this.graphics.canvas.clientWidth;\n },\n set remainingWidth(value: number) {\n Object.defineProperty(this, \"remainingWidth\", { value, writable: true });\n },\n alignment: \"left\",\n reverse: false,\n measureNode(node: Node<C>) {\n return self.measureNode(node, this);\n },\n invalidateNode: this.invalidateNode.bind(this),\n resolveDynValue<T>(value: DynValue<C, T>): T {\n if (typeof value === \"function\") {\n return value(this.graphics);\n }\n return value as T;\n },\n with<T>(cb: (g: C) => T): T {\n this.graphics.save();\n try {\n return cb(this.graphics);\n } finally {\n this.graphics.restore();\n }\n },\n };\n this.#lastWidth = this.graphics.canvas.clientWidth;\n }\n\n invalidateNode(node: Node<C>): void {\n this.#cache.delete(node);\n let it: Node<C> | undefined = node;\n while ((it = getNodeParent(it))) {\n this.#cache.delete(it);\n }\n }\n\n measureNode(node: Node<C>, ctx?: Context<C>): Box {\n if (this.#lastWidth !== this.graphics.canvas.clientWidth) {\n this.#cache = new WeakMap<Node<C>, Box>();\n this.#lastWidth = this.graphics.canvas.clientWidth;\n } else {\n const result = this.#cache.get(node);\n if (result != null) {\n return result;\n }\n }\n const result = node.measure(ctx ?? this.context);\n this.#cache.set(node, result);\n return result;\n }\n}\n\nexport class DebugRenderer<C extends CanvasRenderingContext2D> extends BaseRenderer<C> {\n draw(node: Node<C>): boolean {\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n return node.draw(this.context, 0, 0);\n }\n\n hittest(node: Node<C>, test: HitTest): boolean {\n return node.hittest(this.context, test);\n }\n}\n\nexport function memoRenderItem<C extends CanvasRenderingContext2D, T extends {}>(\n renderItem: (item: T) => Node<C>,\n): ((item: T) => Node<C>) & { reset: (key: T) => boolean } {\n const cache = new WeakMap<object, Node<C>>();\n\n function fn(item: T): Node<C> {\n const key = item as unknown as object;\n const cached = cache.get(key);\n if (cached != null) {\n return cached;\n }\n const result = renderItem(item);\n cache.set(key, result);\n return result;\n }\n\n return Object.assign(fn, {\n reset: (key: T) => cache.delete(key as unknown as object),\n });\n}\n\nexport class ListState<T extends {}> {\n offset = 0;\n position = Number.NaN;\n items: T[] = [];\n\n unshift(...items: T[]): void {\n this.unshiftAll(items);\n }\n\n unshiftAll(items: T[]): void {\n this.position += items.length;\n this.items = items.concat(this.items);\n }\n\n push(...items: T[]): void {\n this.pushAll(items);\n }\n\n pushAll(items: T[]): void {\n this.items.push(...items);\n }\n\n reset(): void {\n this.items = [];\n this.offset = 0;\n this.position = Number.NaN;\n }\n\n resetScroll(): void {\n this.offset = 0;\n this.position = Number.NaN;\n }\n\n applyScroll(delta: number): void {\n this.offset += delta;\n }\n}\n\ntype DrawItem<C extends CanvasRenderingContext2D> = {\n idx: number;\n node: Node<C>;\n offset: number;\n height: number;\n};\n\nexport interface JumpToOptions {\n animated?: boolean;\n duration?: number;\n}\n\ntype ControlledState = {\n position: number;\n offset: number;\n};\n\ntype JumpAnimation = {\n startAnchor: number;\n targetAnchor: number;\n startTime: number;\n duration: number;\n needsMoreFrames: boolean;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction sameState(state: ControlledState, position: number, offset: number): boolean {\n return Object.is(state.position, position) && Object.is(state.offset, offset);\n}\n\nfunction smoothstep(value: number): number {\n return value * value * (3 - 2 * value);\n}\n\nfunction getNow(): number {\n return globalThis.performance?.now() ?? Date.now();\n}\n\nexport abstract class VirtualizedRenderer<C extends CanvasRenderingContext2D, T extends {}> extends BaseRenderer<\n C,\n {\n renderItem: (item: T) => Node<C>;\n list: ListState<T>;\n }\n> {\n static readonly MIN_JUMP_DURATION = 160;\n static readonly MAX_JUMP_DURATION = 420;\n static readonly JUMP_DURATION_PER_ITEM = 28;\n\n #controlledState: ControlledState | undefined;\n #jumpAnimation: JumpAnimation | undefined;\n\n get position(): number {\n return this.options.list.position;\n }\n\n set position(value: number) {\n this.options.list.position = value;\n }\n\n get offset(): number {\n return this.options.list.offset;\n }\n\n set offset(value: number) {\n this.options.list.offset = value;\n }\n\n get items(): T[] {\n return this.options.list.items;\n }\n\n set items(value: T[]) {\n this.options.list.items = value;\n }\n\n abstract render(feedback?: RenderFeedback): boolean;\n abstract hittest(test: HitTest): boolean;\n\n jumpTo(index: number, options: JumpToOptions = {}): void {\n if (this.items.length === 0) {\n this.#cancelJumpAnimation();\n return;\n }\n\n const targetIndex = this._clampItemIndex(index);\n this._prepareAnchorState();\n const targetAnchor = this._getTargetAnchor(targetIndex);\n\n const animated = options.animated ?? true;\n if (!animated) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n return;\n }\n\n const startAnchor = this._readAnchor();\n if (!Number.isFinite(startAnchor)) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n return;\n }\n\n const duration = clamp(\n options.duration ??\n VirtualizedRenderer.MIN_JUMP_DURATION +\n Math.abs(targetAnchor - startAnchor) * VirtualizedRenderer.JUMP_DURATION_PER_ITEM,\n 0,\n VirtualizedRenderer.MAX_JUMP_DURATION,\n );\n\n if (duration <= 0 || Math.abs(targetAnchor - startAnchor) <= Number.EPSILON) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n return;\n }\n\n this.#jumpAnimation = {\n startAnchor,\n targetAnchor,\n startTime: getNow(),\n duration,\n needsMoreFrames: true,\n };\n this.#controlledState = {\n position: this.position,\n offset: this.offset,\n };\n }\n\n protected _resetRenderFeedback(feedback?: RenderFeedback): void {\n if (feedback == null) {\n return;\n }\n feedback.minIdx = Number.NaN;\n feedback.maxIdx = Number.NaN;\n feedback.min = Number.NaN;\n feedback.max = Number.NaN;\n }\n\n protected _accumulateRenderFeedback(feedback: RenderFeedback, idx: number, top: number, height: number): void {\n if (!Number.isFinite(top) || !Number.isFinite(height) || height <= 0) {\n return;\n }\n\n const viewportHeight = this.graphics.canvas.clientHeight;\n const visibleTop = clamp(-top, 0, height);\n const visibleBottom = clamp(viewportHeight - top, 0, height);\n if (visibleBottom <= visibleTop) {\n return;\n }\n\n const itemMin = idx + visibleTop / height;\n const itemMax = idx + visibleBottom / height;\n feedback.minIdx = Number.isNaN(feedback.minIdx) ? idx : Math.min(idx, feedback.minIdx);\n feedback.maxIdx = Number.isNaN(feedback.maxIdx) ? idx : Math.max(idx, feedback.maxIdx);\n feedback.min = Number.isNaN(feedback.min) ? itemMin : Math.min(itemMin, feedback.min);\n feedback.max = Number.isNaN(feedback.max) ? itemMax : Math.max(itemMax, feedback.max);\n }\n\n protected _renderDrawList(list: DrawItem<C>[], shift: number, feedback?: RenderFeedback): boolean {\n let result = false;\n const viewportHeight = this.graphics.canvas.clientHeight;\n\n for (const { idx, node, offset, height } of list) {\n const y = offset + shift;\n if (feedback != null) {\n this._accumulateRenderFeedback(feedback, idx, y, height);\n }\n if (y + height < 0 || y > viewportHeight) {\n continue;\n }\n if (node.draw(this.context, 0, y)) {\n result = true;\n }\n }\n\n return result;\n }\n\n protected _prepareRender(): boolean {\n const animation = this.#jumpAnimation;\n if (animation == null) {\n return false;\n }\n if (this.items.length === 0) {\n this.#cancelJumpAnimation();\n return false;\n }\n if (this.#controlledState != null && !sameState(this.#controlledState, this.position, this.offset)) {\n this.#cancelJumpAnimation();\n return false;\n }\n\n const progress = clamp((getNow() - animation.startTime) / animation.duration, 0, 1);\n const eased = progress >= 1 ? 1 : smoothstep(progress);\n const anchor = animation.startAnchor + (animation.targetAnchor - animation.startAnchor) * eased;\n this._applyAnchor(anchor);\n animation.needsMoreFrames = progress < 1;\n return animation.needsMoreFrames;\n }\n\n protected _finishRender(requestRedraw: boolean): boolean {\n const animation = this.#jumpAnimation;\n if (animation == null) {\n return requestRedraw;\n }\n\n if (animation.needsMoreFrames) {\n this.#controlledState = {\n position: this.position,\n offset: this.offset,\n };\n return true;\n }\n\n this.#cancelJumpAnimation();\n return requestRedraw;\n }\n\n protected _clampItemIndex(index: number): number {\n return clamp(Number.isFinite(index) ? Math.trunc(index) : 0, 0, this.items.length - 1);\n }\n\n protected _getItemHeight(index: number): number {\n const item = this.items[index];\n const node = this.options.renderItem(item);\n return this.measureNode(node).height;\n }\n\n protected abstract _prepareAnchorState(): void;\n protected abstract _readAnchor(): number;\n protected abstract _applyAnchor(anchor: number): void;\n protected abstract _getTargetAnchor(index: number): number;\n\n #cancelJumpAnimation(): void {\n this.#jumpAnimation = undefined;\n this.#controlledState = undefined;\n }\n}\n\nexport class TimelineRenderer<C extends CanvasRenderingContext2D, T extends {}> extends VirtualizedRenderer<C, T> {\n protected _prepareAnchorState(): void {\n if (this.items.length === 0) {\n return;\n }\n if (!Number.isFinite(this.position)) {\n this.position = 0;\n this.offset = 0;\n return;\n }\n this.position = this._clampItemIndex(this.position);\n if (!Number.isFinite(this.offset)) {\n this.offset = 0;\n }\n }\n\n protected _readAnchor(): number {\n this._prepareAnchorState();\n if (this.items.length === 0) {\n return 0;\n }\n const height = this._getItemHeight(this.position);\n return height > 0 ? this.position - this.offset / height : this.position;\n }\n\n protected _applyAnchor(anchor: number): void {\n if (this.items.length === 0) {\n return;\n }\n const clampedAnchor = clamp(anchor, 0, this.items.length);\n const position = clamp(Math.floor(clampedAnchor), 0, this.items.length - 1);\n const height = this._getItemHeight(position);\n this.position = position;\n const offset = height > 0 ? -(clampedAnchor - position) * height : 0;\n this.offset = Object.is(offset, -0) ? 0 : offset;\n }\n\n protected _getTargetAnchor(index: number): number {\n return index;\n }\n\n render(feedback?: RenderFeedback): boolean {\n const keepAnimating = this._prepareRender();\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n this._resetRenderFeedback(feedback);\n\n let drawLength = 0;\n if (Number.isNaN(this.position)) {\n this.position = 0;\n }\n\n if (this.offset > 0) {\n if (this.position === 0) {\n this.offset = 0;\n } else {\n for (let i = this.position - 1; i >= 0; i -= 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n this.position = i;\n this.offset -= height;\n if (this.offset <= 0) {\n break;\n }\n }\n if (this.position === 0 && this.offset > 0) {\n this.offset = 0;\n }\n }\n }\n\n let y = this.offset;\n const drawList: DrawItem<C>[] = [];\n for (let i = this.position; i < this.items.length; i += 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n if (y + height > 0) {\n drawList.push({ idx: i, node, offset: y, height });\n drawLength += height;\n } else {\n this.offset += height;\n this.position = i + 1;\n }\n y += height;\n if (y >= viewportHeight) {\n break;\n }\n }\n\n let shift = 0;\n if (y < viewportHeight) {\n if (this.position === 0 && drawLength < viewportHeight) {\n shift = -this.offset;\n this.offset = 0;\n } else {\n shift = viewportHeight - y;\n y = (this.offset += shift);\n let lastIdx = -1;\n for (let i = this.position - 1; i >= 0; i -= 1) {\n const item = this.items[(lastIdx = i)];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n drawLength += height;\n y -= height;\n drawList.push({ idx: i, node, offset: y - shift, height });\n if (y < 0) {\n break;\n }\n }\n if (lastIdx === 0 && drawLength < viewportHeight) {\n shift = -drawList[drawList.length - 1].offset;\n this.position = 0;\n this.offset = 0;\n }\n }\n }\n\n const requestRedraw = this._renderDrawList(drawList, shift, feedback);\n return this._finishRender(keepAnimating || requestRedraw);\n }\n\n hittest(test: HitTest): boolean {\n const viewportHeight = this.graphics.canvas.clientHeight;\n let y = this.offset;\n\n for (let i = this.position; i < this.items.length; i += 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n if (test.y < y + height) {\n return node.hittest(\n this.context,\n shallowMerge(test, {\n y: test.y - y,\n }),\n );\n }\n y += height;\n if (y >= viewportHeight) {\n break;\n }\n }\n return false;\n }\n}\n\nexport class ChatRenderer<C extends CanvasRenderingContext2D, T extends {}> extends VirtualizedRenderer<C, T> {\n protected _prepareAnchorState(): void {\n if (this.items.length === 0) {\n return;\n }\n if (!Number.isFinite(this.position)) {\n this.position = this.items.length - 1;\n this.offset = 0;\n return;\n }\n this.position = this._clampItemIndex(this.position);\n if (!Number.isFinite(this.offset)) {\n this.offset = 0;\n }\n }\n\n protected _readAnchor(): number {\n this._prepareAnchorState();\n if (this.items.length === 0) {\n return 0;\n }\n const height = this._getItemHeight(this.position);\n return height > 0 ? this.position + 1 - this.offset / height : this.position + 1;\n }\n\n protected _applyAnchor(anchor: number): void {\n if (this.items.length === 0) {\n return;\n }\n const clampedAnchor = clamp(anchor, 0, this.items.length);\n const position = clamp(Math.ceil(clampedAnchor) - 1, 0, this.items.length - 1);\n const height = this._getItemHeight(position);\n this.position = position;\n const offset = height > 0 ? (position + 1 - clampedAnchor) * height : 0;\n this.offset = Object.is(offset, -0) ? 0 : offset;\n }\n\n protected _getTargetAnchor(index: number): number {\n return index + 1;\n }\n\n render(feedback?: RenderFeedback): boolean {\n const keepAnimating = this._prepareRender();\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n this._resetRenderFeedback(feedback);\n\n let drawLength = 0;\n if (Number.isNaN(this.position)) {\n this.position = this.items.length - 1;\n }\n\n if (this.offset < 0) {\n if (this.position === this.items.length - 1) {\n this.offset = 0;\n } else {\n for (let i = this.position + 1; i < this.items.length; i += 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n this.position = i;\n this.offset += height;\n if (this.offset > 0) {\n break;\n }\n }\n }\n }\n\n let y = viewportHeight + this.offset;\n const drawList: DrawItem<C>[] = [];\n for (let i = this.position; i >= 0; i -= 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n y -= height;\n if (y <= viewportHeight) {\n drawList.push({ idx: i, node, offset: y, height });\n drawLength += height;\n } else {\n this.offset -= height;\n this.position = i - 1;\n }\n if (y < 0) {\n break;\n }\n }\n\n let shift = 0;\n if (y > 0) {\n shift = -y;\n if (drawLength < viewportHeight) {\n y = drawLength;\n for (let i = this.position + 1; i < this.items.length; i += 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n drawList.push({ idx: i, node, offset: y - shift, height });\n y = (drawLength += height);\n this.position = i;\n if (y >= viewportHeight) {\n break;\n }\n }\n if (drawLength < viewportHeight) {\n this.offset = 0;\n } else {\n this.offset = drawLength - viewportHeight;\n }\n } else {\n this.offset = drawLength - viewportHeight;\n }\n }\n\n const requestRedraw = this._renderDrawList(drawList, shift, feedback);\n return this._finishRender(keepAnimating || requestRedraw);\n }\n\n hittest(test: HitTest): boolean {\n const viewportHeight = this.graphics.canvas.clientHeight;\n\n let drawLength = 0;\n const heights: Array<readonly [Node<C>, number]> = [];\n for (let i = this.position; i >= 0; i -= 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n drawLength += height;\n heights.push([node, height]);\n }\n\n let y = drawLength < viewportHeight ? drawLength : viewportHeight + this.offset;\n if (test.y > y) {\n return false;\n }\n\n for (const [node, height] of heights) {\n y -= height;\n if (test.y > y) {\n return node.hittest(\n this.context,\n shallowMerge(test, {\n y: test.y - y,\n }),\n );\n }\n }\n return false;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["#inner","#top","#bottom","#left","#right","#shift","#width","#lines","#text","#ctx","#lastWidth","#cache","#cancelJumpAnimation","#jumpAnimation","#controlledState"],"sources":["../src/text.ts","../src/utils.ts","../src/registry.ts","../src/nodes.ts","../src/renderer.ts"],"sourcesContent":["import { layoutWithLines, prepareWithSegments } from \"@chenglou/pretext\";\nimport type { Context } from \"./types\";\n\nexport interface TextLayout {\n width: number;\n text: string;\n shift: number;\n}\n\nfunction preprocessSegments(text: string): string[] {\n return text\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter(Boolean);\n}\n\nexport function layoutFirstLine<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n): TextLayout {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n const segments = preprocessSegments(text);\n const segment = segments[0];\n if (!segment) {\n return { width: 0, text: \"\", shift: 0 };\n }\n const {\n fontBoundingBoxAscent: ascent = 0,\n fontBoundingBoxDescent: descent = 0,\n } = ctx.graphics.measureText(segment);\n const shift = ascent - descent;\n if (maxWidth === 0) {\n return { width: 0, text: \"\", shift };\n }\n const prepared = prepareWithSegments(segment, ctx.graphics.font);\n const { lines } = layoutWithLines(prepared, maxWidth, 0);\n if (lines.length === 0) {\n return { width: 0, text: \"\", shift };\n }\n return { width: lines[0].width, text: lines[0].text, shift };\n}\n\nexport function layoutText<C extends CanvasRenderingContext2D>(\n ctx: Context<C>,\n text: string,\n maxWidth: number,\n): { width: number; lines: TextLayout[] } {\n if (maxWidth < 0) {\n maxWidth = 0;\n }\n\n const segments = preprocessSegments(text);\n if (segments.length === 0 || maxWidth === 0) {\n return { width: 0, lines: [] };\n }\n\n const font = ctx.graphics.font;\n let width = 0;\n const lines: TextLayout[] = [];\n\n for (const segment of segments) {\n const {\n fontBoundingBoxAscent: ascent = 0,\n fontBoundingBoxDescent: descent = 0,\n } = ctx.graphics.measureText(segment);\n const shift = ascent - descent;\n const prepared = prepareWithSegments(segment, font);\n const { lines: segLines } = layoutWithLines(prepared, maxWidth, 0);\n for (const segLine of segLines) {\n width = Math.max(width, segLine.width);\n lines.push({ width: segLine.width, text: segLine.text, shift });\n }\n }\n\n return { width, lines };\n}\n","export function shallow<T extends object>(object: T): T {\n return Object.create(object) as T;\n}\n\nexport function shallowMerge<T extends object, R extends object>(object: T, other: R): T & R {\n return { __proto__: object, ...other } as unknown as T & R;\n}\n","import type { Node } from \"./types\";\n\nconst registry = new WeakMap<Node<any>, Node<any>>();\n\nexport function registerNodeParent<C extends CanvasRenderingContext2D>(\n node: Node<C>,\n parent: Node<C>,\n): void {\n registry.set(node, parent);\n}\n\nexport function unregisterNodeParent<C extends CanvasRenderingContext2D>(node: Node<C>): void {\n registry.delete(node);\n}\n\nexport function getNodeParent<C extends CanvasRenderingContext2D>(node: Node<C>): Node<C> | undefined {\n return registry.get(node);\n}\n","import type { Alignment, Box, Context, DynValue, HitTest, Node } from \"./types\";\nimport { layoutFirstLine, layoutText, type TextLayout } from \"./text\";\nimport { shallow, shallowMerge } from \"./utils\";\nimport { registerNodeParent, unregisterNodeParent } from \"./registry\";\n\nexport abstract class Group<C extends CanvasRenderingContext2D> implements Node<C> {\n constructor(readonly children: Node<C>[]) {\n for (const child of children) {\n registerNodeParent(child, this);\n }\n }\n\n abstract measure(ctx: Context<C>): Box;\n abstract draw(ctx: Context<C>, x: number, y: number): boolean;\n abstract hittest(ctx: Context<C>, test: HitTest): boolean;\n\n get flex(): boolean {\n return this.children.some((item) => item.flex);\n }\n}\n\nexport class VStack<C extends CanvasRenderingContext2D> extends Group<C> {\n constructor(\n children: Node<C>[],\n readonly options: { gap?: number; alignment?: \"left\" | \"center\" | \"right\" } = {},\n ) {\n super(children);\n }\n\n measure(ctx: Context<C>): Box {\n let width = 0;\n let height = 0;\n if (this.options.alignment != null) {\n ctx.alignment = this.options.alignment;\n }\n\n for (const [index, child] of this.children.entries()) {\n if (this.options.gap != null && index !== 0) {\n height += this.options.gap;\n }\n const result = shallow(ctx).measureNode(child);\n height += result.height;\n width = Math.max(width, result.width);\n }\n ctx.remainingWidth -= width;\n return { width, height };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n let result = false;\n const fullWidth = ctx.measureNode(this).width;\n const alignment = this.options.alignment ?? ctx.alignment;\n if (this.options.alignment != null) {\n ctx.alignment = this.options.alignment;\n }\n\n for (const [index, child] of this.children.entries()) {\n if (this.options.gap != null && index !== 0) {\n y += this.options.gap;\n }\n const { width, height } = shallow(ctx).measureNode(child);\n const curCtx = shallow(ctx);\n let requestRedraw: boolean;\n if (alignment === \"right\") {\n requestRedraw = child.draw(curCtx, x + fullWidth - width, y);\n } else if (alignment === \"center\") {\n requestRedraw = child.draw(curCtx, x + (fullWidth - width) / 2, y);\n } else {\n requestRedraw = child.draw(curCtx, x, y);\n }\n result ||= requestRedraw;\n y += height;\n }\n return result;\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n let y = 0;\n const fullWidth = ctx.measureNode(this).width;\n const alignment = this.options.alignment ?? ctx.alignment;\n if (this.options.alignment != null) {\n ctx.alignment = this.options.alignment;\n }\n\n for (const [index, child] of this.children.entries()) {\n if (this.options.gap != null && index !== 0) {\n y += this.options.gap;\n }\n\n const { width, height } = shallow(ctx).measureNode(child);\n const curCtx = shallow(ctx);\n if (test.y >= y && test.y < y + height) {\n let x: number;\n if (alignment === \"right\") {\n x = test.x - fullWidth + width;\n } else if (alignment === \"center\") {\n x = test.x - (fullWidth - width) / 2;\n } else {\n x = test.x;\n }\n if (x < 0 || x >= width) {\n return false;\n }\n return child.hittest(\n curCtx,\n shallowMerge(test, {\n x,\n y: test.y - y,\n }),\n );\n }\n y += height;\n }\n return false;\n }\n}\n\nexport class HStack<C extends CanvasRenderingContext2D> extends Group<C> {\n constructor(\n readonly children: Node<C>[],\n readonly options: { reverse?: boolean; gap?: number } = {},\n ) {\n super(children);\n }\n\n measure(ctx: Context<C>): Box {\n let width = 0;\n let height = 0;\n let firstFlex: Node<C> | undefined;\n\n for (const [index, child] of this.children.entries()) {\n if (this.options.gap != null && index !== 0) {\n width += this.options.gap;\n }\n if (firstFlex == null && child.flex) {\n firstFlex = child;\n continue;\n }\n const curCtx = shallow(ctx);\n curCtx.remainingWidth = ctx.remainingWidth - width;\n const result = curCtx.measureNode(child);\n width += result.width;\n height = Math.max(height, result.height);\n }\n\n if (firstFlex != null) {\n const curCtx = shallow(ctx);\n curCtx.remainingWidth = ctx.remainingWidth - width;\n const result = curCtx.measureNode(firstFlex);\n width += result.width;\n height = Math.max(height, result.height);\n }\n\n return { width, height };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n let result = false;\n const reverse = this.options.reverse ?? ctx.reverse;\n if (this.options.reverse) {\n ctx.reverse = this.options.reverse;\n }\n\n if (reverse) {\n x += ctx.measureNode(this).width;\n for (const [index, child] of this.children.entries()) {\n const gap = this.options.gap != null && index !== 0 ? this.options.gap : undefined;\n if (gap) {\n x -= gap;\n ctx.remainingWidth -= gap;\n }\n const { width } = shallow(ctx).measureNode(child);\n x -= width;\n const requestRedraw = child.draw(shallow(ctx), x, y);\n result ||= requestRedraw;\n ctx.remainingWidth -= width;\n }\n } else {\n for (const [index, child] of this.children.entries()) {\n const gap = this.options.gap != null && index !== 0 ? this.options.gap : undefined;\n if (gap) {\n x += gap;\n ctx.remainingWidth -= gap;\n }\n const requestRedraw = child.draw(shallow(ctx), x, y);\n result ||= requestRedraw;\n const { width } = shallow(ctx).measureNode(child);\n ctx.remainingWidth -= width;\n x += width;\n }\n }\n\n return result;\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n const reverse = this.options.reverse ?? ctx.reverse;\n if (this.options.reverse) {\n ctx.reverse = this.options.reverse;\n }\n\n if (reverse) {\n let x = ctx.measureNode(this).width;\n for (const [index, child] of this.children.entries()) {\n const gap = this.options.gap != null && index !== 0 ? this.options.gap : undefined;\n if (gap) {\n x -= gap;\n ctx.remainingWidth -= gap;\n }\n const { width, height } = shallow(ctx).measureNode(child);\n x -= width;\n if (x <= test.x && test.x < x + width) {\n if (test.y >= height) {\n return false;\n }\n return child.hittest(\n shallow(ctx),\n shallowMerge(test, {\n x: test.x - x,\n }),\n );\n }\n ctx.remainingWidth -= width;\n }\n } else {\n let x = 0;\n for (const [index, child] of this.children.entries()) {\n const gap = this.options.gap != null && index !== 0 ? this.options.gap : undefined;\n if (gap) {\n x += gap;\n ctx.remainingWidth -= gap;\n }\n const { width, height } = shallow(ctx).measureNode(child);\n if (x <= test.x && test.x < x + width) {\n if (test.y >= height) {\n return false;\n }\n return child.hittest(\n shallow(ctx),\n shallowMerge(test, {\n x: test.x - x,\n }),\n );\n }\n x += width;\n ctx.remainingWidth -= width;\n }\n }\n\n return false;\n }\n}\n\nexport class Wrapper<C extends CanvasRenderingContext2D> implements Node<C> {\n #inner: Node<C>;\n\n constructor(inner: Node<C>) {\n this.#inner = inner;\n registerNodeParent(this.#inner, this);\n }\n\n get inner(): Node<C> {\n return this.#inner;\n }\n\n set inner(newNode: Node<C>) {\n if (newNode === this.#inner) {\n return;\n }\n unregisterNodeParent(this.#inner);\n this.#inner = newNode;\n registerNodeParent(newNode, this);\n }\n\n get flex(): boolean {\n return this.inner.flex;\n }\n\n measure(ctx: Context<C>): Box {\n return this.inner.measure(ctx);\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return this.inner.draw(ctx, x, y);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n return this.inner.hittest(ctx, test);\n }\n}\n\nexport class PaddingBox<C extends CanvasRenderingContext2D> extends Wrapper<C> {\n constructor(\n inner: Node<C>,\n readonly padding: {\n top?: number;\n bottom?: number;\n left?: number;\n right?: number;\n } = {},\n ) {\n super(inner);\n }\n\n get #top(): number {\n return this.padding.top ?? 0;\n }\n\n get #bottom(): number {\n return this.padding.bottom ?? 0;\n }\n\n get #left(): number {\n return this.padding.left ?? 0;\n }\n\n get #right(): number {\n return this.padding.right ?? 0;\n }\n\n measure(ctx: Context<C>): Box {\n ctx.remainingWidth -= this.#left + this.#right;\n const { width, height } = ctx.measureNode(this.inner);\n return {\n width: width + this.#left + this.#right,\n height: height + this.#top + this.#bottom,\n };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n ctx.remainingWidth -= this.#left + this.#right;\n return this.inner.draw(ctx, x + this.#left, y + this.#top);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n ctx.remainingWidth -= this.#left + this.#right;\n const { width, height } = shallow(ctx).measureNode(this.inner);\n if (0 <= test.x - this.#left && test.x - this.#left < width && 0 <= test.y - this.#top && test.y - this.#top < height) {\n return this.inner.hittest(\n shallow(ctx),\n shallowMerge(test, {\n x: test.x - this.#left,\n y: test.y - this.#top,\n }),\n );\n }\n return false;\n }\n}\n\nexport class AlignBox<C extends CanvasRenderingContext2D> extends Wrapper<C> {\n #shift = 0;\n\n constructor(\n inner: Node<C>,\n readonly options: {\n alignment: Alignment;\n },\n ) {\n super(inner);\n }\n\n measure(ctx: Context<C>): Box {\n ctx.alignment = this.options.alignment;\n const { width, height } = ctx.measureNode(this.inner);\n switch (this.options.alignment) {\n case \"center\":\n this.#shift = (ctx.remainingWidth - width) / 2;\n break;\n case \"right\":\n this.#shift = ctx.remainingWidth - width;\n break;\n default:\n this.#shift = 0;\n }\n return {\n width: ctx.remainingWidth,\n height,\n };\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n ctx.alignment = this.options.alignment;\n return this.inner.draw(ctx, x + this.#shift, y);\n }\n\n hittest(ctx: Context<C>, test: HitTest): boolean {\n ctx.alignment = this.options.alignment;\n const { width } = shallow(ctx).measureNode(this.inner);\n if (0 <= test.x - this.#shift && test.x - this.#shift < width) {\n return this.inner.hittest(\n shallow(ctx),\n shallowMerge(test, {\n x: test.x - this.#shift,\n }),\n );\n }\n return false;\n }\n}\n\nexport class MultilineText<C extends CanvasRenderingContext2D> implements Node<C> {\n #width = 0;\n #lines: TextLayout[] = [];\n\n constructor(\n readonly text: string,\n readonly options: {\n lineHeight: number;\n font: string;\n alignment: \"left\" | \"center\" | \"right\";\n style: DynValue<C, string>;\n },\n ) {}\n\n get flex(): boolean {\n return true;\n }\n\n measure(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width, lines } = layoutText(ctx, this.text, ctx.remainingWidth);\n this.#width = width;\n this.#lines = lines;\n return { width: this.#width, height: this.#lines.length * this.options.lineHeight };\n });\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return ctx.with((g) => {\n g.font = this.options.font;\n g.fillStyle = ctx.resolveDynValue(this.options.style);\n switch (this.options.alignment) {\n case \"left\":\n for (const { text, shift } of this.#lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n case \"right\":\n x += this.#width;\n g.textAlign = \"right\";\n for (const { text, shift } of this.#lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n case \"center\":\n x += this.#width / 2;\n g.textAlign = \"center\";\n for (const { text, shift } of this.#lines) {\n g.fillText(text, x, y + (this.options.lineHeight + shift) / 2);\n y += this.options.lineHeight;\n }\n break;\n }\n return false;\n });\n }\n\n hittest(_ctx: Context<C>, _test: HitTest): boolean {\n return false;\n }\n}\n\nexport class Text<C extends CanvasRenderingContext2D> implements Node<C> {\n #width = 0;\n #text = \"\";\n #shift = 0;\n\n constructor(\n readonly text: string,\n readonly options: {\n lineHeight: number;\n font: string;\n style: DynValue<C, string>;\n },\n ) {}\n\n get flex(): boolean {\n return false;\n }\n\n measure(ctx: Context<C>): Box {\n return ctx.with((g) => {\n g.font = this.options.font;\n const { width, text, shift } = layoutFirstLine(ctx, this.text, ctx.remainingWidth);\n this.#width = width;\n this.#text = text;\n this.#shift = shift;\n return { width: this.#width, height: this.options.lineHeight };\n });\n }\n\n draw(ctx: Context<C>, x: number, y: number): boolean {\n return ctx.with((g) => {\n g.font = this.options.font;\n g.fillStyle = ctx.resolveDynValue(this.options.style);\n g.fillText(this.#text, x, y + (this.options.lineHeight + this.#shift) / 2);\n return false;\n });\n }\n\n hittest(_ctx: Context<C>, _test: HitTest): boolean {\n return false;\n }\n}\n\nexport class Fixed<C extends CanvasRenderingContext2D> implements Node<C> {\n constructor(\n readonly width: number,\n readonly height: number,\n ) {}\n\n get flex(): boolean {\n return false;\n }\n\n measure(_ctx: Context<C>): Box {\n return { width: this.width, height: this.height };\n }\n\n draw(_ctx: Context<C>, _x: number, _y: number): boolean {\n return false;\n }\n\n hittest(_ctx: Context<C>, _test: HitTest): boolean {\n return false;\n }\n}\n","import type { Box, Context, DynValue, HitTest, Node, RenderFeedback, RendererOptions } from \"./types\";\nimport { shallow, shallowMerge } from \"./utils\";\nimport { getNodeParent } from \"./registry\";\n\nexport class BaseRenderer<C extends CanvasRenderingContext2D, O extends {} = {}> {\n graphics: C;\n #ctx: Context<C>;\n #lastWidth: number;\n #cache = new WeakMap<Node<C>, Box>();\n\n protected get context(): Context<C> {\n return shallow(this.#ctx);\n }\n\n constructor(\n graphics: C,\n readonly options: RendererOptions & O,\n ) {\n this.graphics = graphics;\n this.graphics.textRendering = \"optimizeLegibility\";\n const self = this;\n this.#ctx = {\n graphics: this.graphics,\n get remainingWidth() {\n return this.graphics.canvas.clientWidth;\n },\n set remainingWidth(value: number) {\n Object.defineProperty(this, \"remainingWidth\", { value, writable: true });\n },\n alignment: \"left\",\n reverse: false,\n measureNode(node: Node<C>) {\n return self.measureNode(node, this);\n },\n invalidateNode: this.invalidateNode.bind(this),\n resolveDynValue<T>(value: DynValue<C, T>): T {\n if (typeof value === \"function\") {\n return value(this.graphics);\n }\n return value as T;\n },\n with<T>(cb: (g: C) => T): T {\n this.graphics.save();\n try {\n return cb(this.graphics);\n } finally {\n this.graphics.restore();\n }\n },\n };\n this.#lastWidth = this.graphics.canvas.clientWidth;\n }\n\n invalidateNode(node: Node<C>): void {\n this.#cache.delete(node);\n let it: Node<C> | undefined = node;\n while ((it = getNodeParent(it))) {\n this.#cache.delete(it);\n }\n }\n\n measureNode(node: Node<C>, ctx?: Context<C>): Box {\n if (this.#lastWidth !== this.graphics.canvas.clientWidth) {\n this.#cache = new WeakMap<Node<C>, Box>();\n this.#lastWidth = this.graphics.canvas.clientWidth;\n } else {\n const result = this.#cache.get(node);\n if (result != null) {\n return result;\n }\n }\n const result = node.measure(ctx ?? this.context);\n this.#cache.set(node, result);\n return result;\n }\n}\n\nexport class DebugRenderer<C extends CanvasRenderingContext2D> extends BaseRenderer<C> {\n draw(node: Node<C>): boolean {\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n return node.draw(this.context, 0, 0);\n }\n\n hittest(node: Node<C>, test: HitTest): boolean {\n return node.hittest(this.context, test);\n }\n}\n\nexport function memoRenderItem<C extends CanvasRenderingContext2D, T extends {}>(\n renderItem: (item: T) => Node<C>,\n): ((item: T) => Node<C>) & { reset: (key: T) => boolean } {\n const cache = new WeakMap<object, Node<C>>();\n\n function fn(item: T): Node<C> {\n const key = item as unknown as object;\n const cached = cache.get(key);\n if (cached != null) {\n return cached;\n }\n const result = renderItem(item);\n cache.set(key, result);\n return result;\n }\n\n return Object.assign(fn, {\n reset: (key: T) => cache.delete(key as unknown as object),\n });\n}\n\nexport class ListState<T extends {}> {\n offset = 0;\n position = Number.NaN;\n items: T[] = [];\n\n unshift(...items: T[]): void {\n this.unshiftAll(items);\n }\n\n unshiftAll(items: T[]): void {\n this.position += items.length;\n this.items = items.concat(this.items);\n }\n\n push(...items: T[]): void {\n this.pushAll(items);\n }\n\n pushAll(items: T[]): void {\n this.items.push(...items);\n }\n\n reset(): void {\n this.items = [];\n this.offset = 0;\n this.position = Number.NaN;\n }\n\n resetScroll(): void {\n this.offset = 0;\n this.position = Number.NaN;\n }\n\n applyScroll(delta: number): void {\n this.offset += delta;\n }\n}\n\ntype DrawItem<C extends CanvasRenderingContext2D> = {\n idx: number;\n node: Node<C>;\n offset: number;\n height: number;\n};\n\nexport interface JumpToOptions {\n animated?: boolean;\n duration?: number;\n onComplete?: () => void;\n}\n\ntype ControlledState = {\n position: number;\n offset: number;\n};\n\ntype JumpAnimation = {\n startAnchor: number;\n targetAnchor: number;\n startTime: number;\n duration: number;\n needsMoreFrames: boolean;\n onComplete: (() => void) | undefined;\n};\n\nfunction clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nfunction sameState(state: ControlledState, position: number, offset: number): boolean {\n return Object.is(state.position, position) && Object.is(state.offset, offset);\n}\n\nfunction smoothstep(value: number): number {\n return value * value * (3 - 2 * value);\n}\n\nfunction getNow(): number {\n return globalThis.performance?.now() ?? Date.now();\n}\n\nexport abstract class VirtualizedRenderer<C extends CanvasRenderingContext2D, T extends {}> extends BaseRenderer<\n C,\n {\n renderItem: (item: T) => Node<C>;\n list: ListState<T>;\n }\n> {\n static readonly MIN_JUMP_DURATION = 160;\n static readonly MAX_JUMP_DURATION = 420;\n static readonly JUMP_DURATION_PER_ITEM = 28;\n\n #controlledState: ControlledState | undefined;\n #jumpAnimation: JumpAnimation | undefined;\n\n get position(): number {\n return this.options.list.position;\n }\n\n set position(value: number) {\n this.options.list.position = value;\n }\n\n get offset(): number {\n return this.options.list.offset;\n }\n\n set offset(value: number) {\n this.options.list.offset = value;\n }\n\n get items(): T[] {\n return this.options.list.items;\n }\n\n set items(value: T[]) {\n this.options.list.items = value;\n }\n\n abstract render(feedback?: RenderFeedback): boolean;\n abstract hittest(test: HitTest): boolean;\n\n jumpTo(index: number, options: JumpToOptions = {}): void {\n if (this.items.length === 0) {\n this.#cancelJumpAnimation();\n return;\n }\n\n const targetIndex = this._clampItemIndex(index);\n this._prepareAnchorState();\n const targetAnchor = this._getTargetAnchor(targetIndex);\n\n const animated = options.animated ?? true;\n if (!animated) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n options.onComplete?.();\n return;\n }\n\n const startAnchor = this._readAnchor();\n if (!Number.isFinite(startAnchor)) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n options.onComplete?.();\n return;\n }\n\n const duration = clamp(\n options.duration ??\n VirtualizedRenderer.MIN_JUMP_DURATION +\n Math.abs(targetAnchor - startAnchor) * VirtualizedRenderer.JUMP_DURATION_PER_ITEM,\n 0,\n VirtualizedRenderer.MAX_JUMP_DURATION,\n );\n\n if (duration <= 0 || Math.abs(targetAnchor - startAnchor) <= Number.EPSILON) {\n this.#cancelJumpAnimation();\n this._applyAnchor(targetAnchor);\n options.onComplete?.();\n return;\n }\n\n this.#jumpAnimation = {\n startAnchor,\n targetAnchor,\n startTime: getNow(),\n duration,\n needsMoreFrames: true,\n onComplete: options.onComplete,\n };\n this.#controlledState = {\n position: this.position,\n offset: this.offset,\n };\n }\n\n protected _resetRenderFeedback(feedback?: RenderFeedback): void {\n if (feedback == null) {\n return;\n }\n feedback.minIdx = Number.NaN;\n feedback.maxIdx = Number.NaN;\n feedback.min = Number.NaN;\n feedback.max = Number.NaN;\n }\n\n protected _accumulateRenderFeedback(feedback: RenderFeedback, idx: number, top: number, height: number): void {\n if (!Number.isFinite(top) || !Number.isFinite(height) || height <= 0) {\n return;\n }\n\n const viewportHeight = this.graphics.canvas.clientHeight;\n const visibleTop = clamp(-top, 0, height);\n const visibleBottom = clamp(viewportHeight - top, 0, height);\n if (visibleBottom <= visibleTop) {\n return;\n }\n\n const itemMin = idx + visibleTop / height;\n const itemMax = idx + visibleBottom / height;\n feedback.minIdx = Number.isNaN(feedback.minIdx) ? idx : Math.min(idx, feedback.minIdx);\n feedback.maxIdx = Number.isNaN(feedback.maxIdx) ? idx : Math.max(idx, feedback.maxIdx);\n feedback.min = Number.isNaN(feedback.min) ? itemMin : Math.min(itemMin, feedback.min);\n feedback.max = Number.isNaN(feedback.max) ? itemMax : Math.max(itemMax, feedback.max);\n }\n\n protected _renderDrawList(list: DrawItem<C>[], shift: number, feedback?: RenderFeedback): boolean {\n let result = false;\n const viewportHeight = this.graphics.canvas.clientHeight;\n\n for (const { idx, node, offset, height } of list) {\n const y = offset + shift;\n if (feedback != null) {\n this._accumulateRenderFeedback(feedback, idx, y, height);\n }\n if (y + height < 0 || y > viewportHeight) {\n continue;\n }\n if (node.draw(this.context, 0, y)) {\n result = true;\n }\n }\n\n return result;\n }\n\n protected _prepareRender(): boolean {\n const animation = this.#jumpAnimation;\n if (animation == null) {\n return false;\n }\n if (this.items.length === 0) {\n this.#cancelJumpAnimation();\n return false;\n }\n if (this.#controlledState != null && !sameState(this.#controlledState, this.position, this.offset)) {\n this.#cancelJumpAnimation();\n return false;\n }\n\n const progress = clamp((getNow() - animation.startTime) / animation.duration, 0, 1);\n const eased = progress >= 1 ? 1 : smoothstep(progress);\n const anchor = animation.startAnchor + (animation.targetAnchor - animation.startAnchor) * eased;\n this._applyAnchor(anchor);\n animation.needsMoreFrames = progress < 1;\n return animation.needsMoreFrames;\n }\n\n protected _finishRender(requestRedraw: boolean): boolean {\n const animation = this.#jumpAnimation;\n if (animation == null) {\n return requestRedraw;\n }\n\n if (animation.needsMoreFrames) {\n this.#controlledState = {\n position: this.position,\n offset: this.offset,\n };\n return true;\n }\n\n const onComplete = animation.onComplete;\n this.#cancelJumpAnimation();\n onComplete?.();\n return requestRedraw || this.#jumpAnimation != null;\n }\n\n protected _clampItemIndex(index: number): number {\n return clamp(Number.isFinite(index) ? Math.trunc(index) : 0, 0, this.items.length - 1);\n }\n\n protected _getItemHeight(index: number): number {\n const item = this.items[index];\n const node = this.options.renderItem(item);\n return this.measureNode(node).height;\n }\n\n protected abstract _prepareAnchorState(): void;\n protected abstract _readAnchor(): number;\n protected abstract _applyAnchor(anchor: number): void;\n protected abstract _getTargetAnchor(index: number): number;\n\n #cancelJumpAnimation(): void {\n this.#jumpAnimation = undefined;\n this.#controlledState = undefined;\n }\n}\n\nexport class TimelineRenderer<C extends CanvasRenderingContext2D, T extends {}> extends VirtualizedRenderer<C, T> {\n protected _prepareAnchorState(): void {\n if (this.items.length === 0) {\n return;\n }\n if (!Number.isFinite(this.position)) {\n this.position = 0;\n this.offset = 0;\n return;\n }\n this.position = this._clampItemIndex(this.position);\n if (!Number.isFinite(this.offset)) {\n this.offset = 0;\n }\n }\n\n protected _readAnchor(): number {\n this._prepareAnchorState();\n if (this.items.length === 0) {\n return 0;\n }\n const height = this._getItemHeight(this.position);\n return height > 0 ? this.position - this.offset / height : this.position;\n }\n\n protected _applyAnchor(anchor: number): void {\n if (this.items.length === 0) {\n return;\n }\n const clampedAnchor = clamp(anchor, 0, this.items.length);\n const position = clamp(Math.floor(clampedAnchor), 0, this.items.length - 1);\n const height = this._getItemHeight(position);\n this.position = position;\n const offset = height > 0 ? -(clampedAnchor - position) * height : 0;\n this.offset = Object.is(offset, -0) ? 0 : offset;\n }\n\n protected _getTargetAnchor(index: number): number {\n return index;\n }\n\n render(feedback?: RenderFeedback): boolean {\n const keepAnimating = this._prepareRender();\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n this._resetRenderFeedback(feedback);\n\n let drawLength = 0;\n if (Number.isNaN(this.position)) {\n this.position = 0;\n }\n\n if (this.offset > 0) {\n if (this.position === 0) {\n this.offset = 0;\n } else {\n for (let i = this.position - 1; i >= 0; i -= 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n this.position = i;\n this.offset -= height;\n if (this.offset <= 0) {\n break;\n }\n }\n if (this.position === 0 && this.offset > 0) {\n this.offset = 0;\n }\n }\n }\n\n let y = this.offset;\n const drawList: DrawItem<C>[] = [];\n for (let i = this.position; i < this.items.length; i += 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n if (y + height > 0) {\n drawList.push({ idx: i, node, offset: y, height });\n drawLength += height;\n } else {\n this.offset += height;\n this.position = i + 1;\n }\n y += height;\n if (y >= viewportHeight) {\n break;\n }\n }\n\n let shift = 0;\n if (y < viewportHeight) {\n if (this.position === 0 && drawLength < viewportHeight) {\n shift = -this.offset;\n this.offset = 0;\n } else {\n shift = viewportHeight - y;\n y = (this.offset += shift);\n let lastIdx = -1;\n for (let i = this.position - 1; i >= 0; i -= 1) {\n const item = this.items[(lastIdx = i)];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n drawLength += height;\n y -= height;\n drawList.push({ idx: i, node, offset: y - shift, height });\n if (y < 0) {\n break;\n }\n }\n if (lastIdx === 0 && drawLength < viewportHeight) {\n shift = -drawList[drawList.length - 1].offset;\n this.position = 0;\n this.offset = 0;\n }\n }\n }\n\n const requestRedraw = this._renderDrawList(drawList, shift, feedback);\n return this._finishRender(keepAnimating || requestRedraw);\n }\n\n hittest(test: HitTest): boolean {\n const viewportHeight = this.graphics.canvas.clientHeight;\n let y = this.offset;\n\n for (let i = this.position; i < this.items.length; i += 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n if (test.y < y + height) {\n return node.hittest(\n this.context,\n shallowMerge(test, {\n y: test.y - y,\n }),\n );\n }\n y += height;\n if (y >= viewportHeight) {\n break;\n }\n }\n return false;\n }\n}\n\nexport class ChatRenderer<C extends CanvasRenderingContext2D, T extends {}> extends VirtualizedRenderer<C, T> {\n protected _prepareAnchorState(): void {\n if (this.items.length === 0) {\n return;\n }\n if (!Number.isFinite(this.position)) {\n this.position = this.items.length - 1;\n this.offset = 0;\n return;\n }\n this.position = this._clampItemIndex(this.position);\n if (!Number.isFinite(this.offset)) {\n this.offset = 0;\n }\n }\n\n protected _readAnchor(): number {\n this._prepareAnchorState();\n if (this.items.length === 0) {\n return 0;\n }\n const height = this._getItemHeight(this.position);\n return height > 0 ? this.position + 1 - this.offset / height : this.position + 1;\n }\n\n protected _applyAnchor(anchor: number): void {\n if (this.items.length === 0) {\n return;\n }\n const clampedAnchor = clamp(anchor, 0, this.items.length);\n const position = clamp(Math.ceil(clampedAnchor) - 1, 0, this.items.length - 1);\n const height = this._getItemHeight(position);\n this.position = position;\n const offset = height > 0 ? (position + 1 - clampedAnchor) * height : 0;\n this.offset = Object.is(offset, -0) ? 0 : offset;\n }\n\n protected _getTargetAnchor(index: number): number {\n return index + 1;\n }\n\n render(feedback?: RenderFeedback): boolean {\n const keepAnimating = this._prepareRender();\n const { clientWidth: viewportWidth, clientHeight: viewportHeight } = this.graphics.canvas;\n this.graphics.clearRect(0, 0, viewportWidth, viewportHeight);\n this._resetRenderFeedback(feedback);\n\n let drawLength = 0;\n if (Number.isNaN(this.position)) {\n this.position = this.items.length - 1;\n }\n\n if (this.offset < 0) {\n if (this.position === this.items.length - 1) {\n this.offset = 0;\n } else {\n for (let i = this.position + 1; i < this.items.length; i += 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n this.position = i;\n this.offset += height;\n if (this.offset > 0) {\n break;\n }\n }\n }\n }\n\n let y = viewportHeight + this.offset;\n const drawList: DrawItem<C>[] = [];\n for (let i = this.position; i >= 0; i -= 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n y -= height;\n if (y <= viewportHeight) {\n drawList.push({ idx: i, node, offset: y, height });\n drawLength += height;\n } else {\n this.offset -= height;\n this.position = i - 1;\n }\n if (y < 0) {\n break;\n }\n }\n\n let shift = 0;\n if (y > 0) {\n shift = -y;\n if (drawLength < viewportHeight) {\n y = drawLength;\n for (let i = this.position + 1; i < this.items.length; i += 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n drawList.push({ idx: i, node, offset: y - shift, height });\n y = (drawLength += height);\n this.position = i;\n if (y >= viewportHeight) {\n break;\n }\n }\n if (drawLength < viewportHeight) {\n this.offset = 0;\n } else {\n this.offset = drawLength - viewportHeight;\n }\n } else {\n this.offset = drawLength - viewportHeight;\n }\n }\n\n const requestRedraw = this._renderDrawList(drawList, shift, feedback);\n return this._finishRender(keepAnimating || requestRedraw);\n }\n\n hittest(test: HitTest): boolean {\n const viewportHeight = this.graphics.canvas.clientHeight;\n\n let drawLength = 0;\n const heights: Array<readonly [Node<C>, number]> = [];\n for (let i = this.position; i >= 0; i -= 1) {\n const item = this.items[i];\n const node = this.options.renderItem(item);\n const { height } = this.measureNode(node);\n drawLength += height;\n heights.push([node, height]);\n }\n\n let y = drawLength < viewportHeight ? drawLength : viewportHeight + this.offset;\n if (test.y > y) {\n return false;\n }\n\n for (const [node, height] of heights) {\n y -= height;\n if (test.y > y) {\n return node.hittest(\n this.context,\n shallowMerge(test, {\n y: test.y - y,\n }),\n );\n }\n }\n return false;\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -8,7 +8,7 @@
8
8
  "repository": {
9
9
  "url": "https://github.com/codehz/chat-layout.git"
10
10
  },
11
- "version": "0.1.3",
11
+ "version": "0.1.4",
12
12
  "main": "./index.mjs",
13
13
  "types": "./index.d.mts",
14
14
  "exports": {