@fieldnotes/core 0.40.2 → 0.40.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/dist/index.d.cts CHANGED
@@ -1048,6 +1048,6 @@ declare class LaserTool implements Tool {
1048
1048
  private notifyOptionsChange;
1049
1049
  }
1050
1050
 
1051
- declare const VERSION = "0.40.2";
1051
+ declare const VERSION = "0.40.4";
1052
1052
 
1053
1053
  export { type ActiveFormats, type AlignEdge, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, type BackgroundOptions, type BackgroundPattern, type Binding, type Bounds, Camera, type CameraChangeInfo, type CameraOptions, type CanvasElement, type CanvasState, type Command, DEFAULT_NOTE_FONT_SIZE, type DistributeAxis, ElementStore, type ElementStyle, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, type ExportImageOptions, type ExportSvgOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, LaserTool, type LaserToolOptions, type Layer, LayerManager, MeasureTool, type MeasureToolOptions, type Measurement, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, type RenderStatsSnapshot, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type ShortcutBindings, type ShortcutOptions, type ShortcutsApi, type Size, type StrokeElement, type StrokePoint, type TemplateElement, type TemplateShape, TemplateTool, type TemplateToolOptions, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, VERSION, Viewport, type ViewportOptions, boundsIntersect, createArrow, createGrid, createHtmlElement, createImage, createNote, createShape, createStroke, createTemplate, createText, drawHexPath, exportImage, exportSvg, getActiveFormats, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getElementBounds, getElementStyle, getElementsBoundingBox, getHexCellsInCone, getHexCellsInLine, getHexCellsInRadius, getHexCellsInSquare, getHexDistance, isNearBezier, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
package/dist/index.d.ts CHANGED
@@ -1048,6 +1048,6 @@ declare class LaserTool implements Tool {
1048
1048
  private notifyOptionsChange;
1049
1049
  }
1050
1050
 
1051
- declare const VERSION = "0.40.2";
1051
+ declare const VERSION = "0.40.4";
1052
1052
 
1053
1053
  export { type ActiveFormats, type AlignEdge, type ArrowElement, ArrowTool, type ArrowToolOptions, AutoSave, type AutoSaveOptions, type BackgroundOptions, type BackgroundPattern, type Binding, type Bounds, Camera, type CameraChangeInfo, type CameraOptions, type CanvasElement, type CanvasState, type Command, DEFAULT_NOTE_FONT_SIZE, type DistributeAxis, ElementStore, type ElementStyle, type ElementType, type ElementUpdateEvent, EraserTool, type EraserToolOptions, type ExportImageOptions, type ExportSvgOptions, type FontSizePreset, type GridElement, type GridInfo, HandTool, type HexOrientation, HistoryStack, type HistoryStackOptions, type HtmlElement, type ImageElement, ImageTool, type ImageToolOptions, LaserTool, type LaserToolOptions, type Layer, LayerManager, MeasureTool, type MeasureToolOptions, type Measurement, type NoteElement, NoteTool, type NoteToolOptions, PencilTool, type PencilToolOptions, type Point, type PointerState, type RenderStatsSnapshot, SelectTool, type ShapeElement, type ShapeKind, ShapeTool, type ShapeToolOptions, type ShortcutBindings, type ShortcutOptions, type ShortcutsApi, type Size, type StrokeElement, type StrokePoint, type TemplateElement, type TemplateShape, TemplateTool, type TemplateToolOptions, type TextElement, TextTool, type TextToolOptions, type Tool, type ToolContext, ToolManager, type ToolName, VERSION, Viewport, type ViewportOptions, boundsIntersect, createArrow, createGrid, createHtmlElement, createImage, createNote, createShape, createStroke, createTemplate, createText, drawHexPath, exportImage, exportSvg, getActiveFormats, getArrowBounds, getArrowControlPoint, getArrowMidpoint, getArrowTangentAngle, getBendFromPoint, getElementBounds, getElementStyle, getElementsBoundingBox, getHexCellsInCone, getHexCellsInLine, getHexCellsInRadius, getHexCellsInSquare, getHexDistance, isNearBezier, setFontSize, smartSnap, snapPoint, snapToHexCenter, styleToPatch, toggleBold, toggleItalic, toggleStrikethrough, toggleUnderline };
package/dist/index.js CHANGED
@@ -587,7 +587,7 @@ function getBendFromPoint(from, to, dragPoint) {
587
587
  if (len === 0) return 0;
588
588
  const perpX = -dy / len;
589
589
  const perpY = dx / len;
590
- return (dragPoint.x - midX) * perpX + (dragPoint.y - midY) * perpY;
590
+ return 2 * ((dragPoint.x - midX) * perpX + (dragPoint.y - midY) * perpY);
591
591
  }
592
592
  function getArrowTangentAngle(from, to, bend, t) {
593
593
  const cp = getArrowControlPoint(from, to, bend);
@@ -4638,29 +4638,42 @@ function buildFontString(run) {
4638
4638
  const weight = run.bold ? "bold" : "normal";
4639
4639
  return `${style} ${weight} ${run.fontSize}px system-ui, sans-serif`;
4640
4640
  }
4641
- function renderStyledRuns(ctx, runs, startX, startY, maxWidth) {
4641
+ function renderStyledRuns(ctx, runs, startX, startY, maxWidth, opts = {}) {
4642
+ const align = opts.align ?? "left";
4643
+ const lhMul = opts.lineHeight ?? 1.3;
4642
4644
  ctx.textBaseline = "top";
4645
+ const lines = [];
4643
4646
  let cursorX = startX;
4644
- let cursorY = startY;
4647
+ let lineY = startY;
4645
4648
  let lineHeight = 0;
4649
+ let fragments = [];
4650
+ const finalizeLine = () => {
4651
+ const last = fragments[fragments.length - 1];
4652
+ const width = last ? last.x + last.width : 0;
4653
+ lines.push({ y: lineY, width, fragments });
4654
+ };
4655
+ const breakLine = (runLineHeight) => {
4656
+ finalizeLine();
4657
+ lineY += lineHeight;
4658
+ lineHeight = runLineHeight;
4659
+ fragments = [];
4660
+ cursorX = startX;
4661
+ };
4646
4662
  for (const run of runs) {
4647
- ctx.font = buildFontString(run);
4648
- const runLineHeight = run.fontSize * 1.3;
4663
+ const font = buildFontString(run);
4664
+ ctx.font = font;
4665
+ const runLineHeight = run.fontSize * lhMul;
4649
4666
  lineHeight = Math.max(lineHeight, runLineHeight);
4650
4667
  const words = run.text.split(/(\n| )/);
4651
4668
  for (const word of words) {
4652
4669
  if (word === "\n") {
4653
- cursorX = startX;
4654
- cursorY += lineHeight;
4655
- lineHeight = runLineHeight;
4670
+ breakLine(runLineHeight);
4656
4671
  continue;
4657
4672
  }
4658
4673
  if (word === " ") {
4659
4674
  const spaceWidth = ctx.measureText(" ").width;
4660
4675
  if (cursorX + spaceWidth > startX + maxWidth && cursorX > startX) {
4661
- cursorX = startX;
4662
- cursorY += lineHeight;
4663
- lineHeight = runLineHeight;
4676
+ breakLine(runLineHeight);
4664
4677
  } else {
4665
4678
  cursorX += spaceWidth;
4666
4679
  }
@@ -4669,20 +4682,33 @@ function renderStyledRuns(ctx, runs, startX, startY, maxWidth) {
4669
4682
  if (!word) continue;
4670
4683
  const metrics = ctx.measureText(word);
4671
4684
  if (cursorX + metrics.width > startX + maxWidth && cursorX > startX) {
4672
- cursorX = startX;
4673
- cursorY += lineHeight;
4674
- lineHeight = runLineHeight;
4685
+ breakLine(runLineHeight);
4675
4686
  }
4676
- ctx.fillText(word, cursorX, cursorY);
4677
- if (run.underline) {
4678
- const underY = cursorY + run.fontSize + 1;
4679
- ctx.fillRect(cursorX, underY, metrics.width, 1);
4687
+ fragments.push({
4688
+ text: word,
4689
+ font,
4690
+ x: cursorX - startX,
4691
+ width: metrics.width,
4692
+ fontSize: run.fontSize,
4693
+ underline: run.underline,
4694
+ strikethrough: run.strikethrough
4695
+ });
4696
+ cursorX += metrics.width;
4697
+ }
4698
+ }
4699
+ finalizeLine();
4700
+ for (const line of lines) {
4701
+ const offset = align === "center" ? (maxWidth - line.width) / 2 : align === "right" ? maxWidth - line.width : 0;
4702
+ for (const fragment of line.fragments) {
4703
+ ctx.font = fragment.font;
4704
+ const fx = startX + offset + fragment.x;
4705
+ ctx.fillText(fragment.text, fx, line.y);
4706
+ if (fragment.underline) {
4707
+ ctx.fillRect(fx, line.y + fragment.fontSize + 1, fragment.width, 1);
4680
4708
  }
4681
- if (run.strikethrough) {
4682
- const strikeY = cursorY + run.fontSize * 0.55;
4683
- ctx.fillRect(cursorX, strikeY, metrics.width, 1);
4709
+ if (fragment.strikethrough) {
4710
+ ctx.fillRect(fx, line.y + fragment.fontSize * 0.55, fragment.width, 1);
4684
4711
  }
4685
- cursorX += metrics.width;
4686
4712
  }
4687
4713
  }
4688
4714
  }
@@ -4693,7 +4719,10 @@ function renderTextOnCanvas(ctx, text) {
4693
4719
  ctx.save();
4694
4720
  ctx.fillStyle = text.color;
4695
4721
  const runs = parseStyledRuns(text.text ?? "", text.fontSize);
4696
- renderStyledRuns(ctx, runs, text.position.x + pad, text.position.y + pad, text.size.w - pad * 2);
4722
+ renderStyledRuns(ctx, runs, text.position.x + pad, text.position.y + pad, text.size.w - pad * 2, {
4723
+ align: text.textAlign,
4724
+ lineHeight: 1.4
4725
+ });
4697
4726
  ctx.restore();
4698
4727
  }
4699
4728
 
@@ -9664,7 +9693,7 @@ var LaserTool = class {
9664
9693
  };
9665
9694
 
9666
9695
  // src/index.ts
9667
- var VERSION = "0.40.2";
9696
+ var VERSION = "0.40.4";
9668
9697
  export {
9669
9698
  ArrowTool,
9670
9699
  AutoSave,