@orangecatai/adgen-canvas 0.0.12 → 0.0.14

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/dev/index.js CHANGED
@@ -67,10 +67,10 @@ import {
67
67
  serializeAsJSON,
68
68
  serializeLibraryAsJSON,
69
69
  strokeRectWithRotation_simple
70
- } from "./chunk-RAO3IICE.js";
70
+ } from "./chunk-W3WRQE6Q.js";
71
71
  import {
72
72
  define_import_meta_env_default
73
- } from "./chunk-RDEPKTPR.js";
73
+ } from "./chunk-3OPVOEOA.js";
74
74
  import {
75
75
  en_default
76
76
  } from "./chunk-IFMURN5W.js";
@@ -84,7 +84,7 @@ import {
84
84
  } from "./chunk-XDFCUUT6.js";
85
85
 
86
86
  // index.tsx
87
- import React64, { useEffect as useEffect62 } from "react";
87
+ import React64, { useEffect as useEffect62, useMemo as useMemo15 } from "react";
88
88
  import { DEFAULT_UI_OPTIONS, isShallowEqual as isShallowEqual10 } from "@orangecatai/common";
89
89
 
90
90
  // components/App.tsx
@@ -5250,7 +5250,8 @@ import React10, {
5250
5250
  useState as useState6,
5251
5251
  useRef as useRef9,
5252
5252
  useEffect as useEffect10,
5253
- useCallback as useCallback3
5253
+ useCallback as useCallback3,
5254
+ useSyncExternalStore
5254
5255
  } from "react";
5255
5256
  import {
5256
5257
  arrayToList,
@@ -5526,6 +5527,10 @@ var FontPickerList = React10.memo(
5526
5527
  const stylesPanelMode = useStylesPanelMode();
5527
5528
  const [searchTerm, setSearchTerm] = useState6("");
5528
5529
  const inputRef = useRef9(null);
5530
+ const customFontVersion = useSyncExternalStore(
5531
+ Fonts.subscribeToCustomFonts,
5532
+ Fonts.getCustomFontVersion
5533
+ );
5529
5534
  const allFonts = useMemo(
5530
5535
  () => Array.from(Fonts.registered.entries()).filter(
5531
5536
  ([_, { metadata }]) => !metadata.private && !metadata.fallback
@@ -5548,7 +5553,7 @@ var FontPickerList = React10.memo(
5548
5553
  }).sort(
5549
5554
  (a, b) => a.text.toLowerCase() > b.text.toLowerCase() ? 1 : -1
5550
5555
  ),
5551
- []
5556
+ [customFontVersion]
5552
5557
  );
5553
5558
  const sceneFamilies = useMemo(
5554
5559
  () => new Set(fonts.getSceneFamilies()),
@@ -9765,7 +9770,7 @@ var exportCanvas = async (type, elements, appState, files, {
9765
9770
  let blob = canvasToBlob(tempCanvas);
9766
9771
  if (appState.exportEmbedScene) {
9767
9772
  blob = blob.then(
9768
- (blob2) => import("./data/image-U7EILU4Y.js").then(
9773
+ (blob2) => import("./data/image-NKXZX2BO.js").then(
9769
9774
  ({ encodePngMetadata: encodePngMetadata2 }) => encodePngMetadata2({
9770
9775
  blob: blob2,
9771
9776
  metadata: serializeAsJSON(elements, appState, files, "local")
@@ -24778,6 +24783,17 @@ function fitImageToFrame(imgW, imgH, frameW, frameH) {
24778
24783
  const relY = (frameH - fittedH) / 2;
24779
24784
  return { relX, relY, width: fittedW, height: fittedH };
24780
24785
  }
24786
+ function containImageInBbox(imgW, imgH, bboxW, bboxH) {
24787
+ if (imgW <= 0 || imgH <= 0) {
24788
+ return { relX: 0, relY: 0, width: bboxW, height: bboxH };
24789
+ }
24790
+ const scale = Math.min(bboxW / imgW, bboxH / imgH);
24791
+ const fittedW = imgW * scale;
24792
+ const fittedH = imgH * scale;
24793
+ const relX = (bboxW - fittedW) / 2;
24794
+ const relY = (bboxH - fittedH) / 2;
24795
+ return { relX, relY, width: fittedW, height: fittedH };
24796
+ }
24781
24797
  async function captureFrameScreenshotFromApp(app, frameId) {
24782
24798
  const elements = app.getSceneElements();
24783
24799
  const frame = elements.find((el) => el.id === frameId);
@@ -25309,12 +25325,19 @@ async function runAutoResizeForDimension(opts) {
25309
25325
  newEls.push({ ...el, frameId });
25310
25326
  } else if (pel.kind === "image") {
25311
25327
  const fileId2 = nanoid();
25328
+ const { width: natW, height: natH } = await getImageNaturalDimensions(pel.dataUrl);
25329
+ const { relX, relY, width: imgW, height: imgH } = containImageInBbox(
25330
+ natW,
25331
+ natH,
25332
+ pel.width,
25333
+ pel.height
25334
+ );
25312
25335
  const el = newImageElement({
25313
25336
  type: "image",
25314
- x: pel.x,
25315
- y: pel.y,
25316
- width: pel.width,
25317
- height: pel.height,
25337
+ x: pel.x + relX,
25338
+ y: pel.y + relY,
25339
+ width: imgW,
25340
+ height: imgH,
25318
25341
  fileId: fileId2,
25319
25342
  status: "pending",
25320
25343
  scale: [1, 1],
@@ -27468,15 +27491,15 @@ var ImageEditToolbar = ({
27468
27491
  },
27469
27492
  tool.id
27470
27493
  )),
27471
- !!element.customData?.brandAssetId && /* @__PURE__ */ jsxs52(
27494
+ !!callbacks?.onSwapAsset && /* @__PURE__ */ jsxs52(
27472
27495
  "button",
27473
27496
  {
27474
27497
  type: "button",
27475
27498
  className: "iet__tool-btn",
27476
27499
  onClick: () => {
27477
- void callbacks?.onSwapAsset?.(element.id);
27500
+ void callbacks.onSwapAsset(element.id);
27478
27501
  },
27479
- title: "Swap brand asset",
27502
+ title: "Swap image from asset bank",
27480
27503
  disabled: isToolbarBusy,
27481
27504
  children: [
27482
27505
  /* @__PURE__ */ jsx94(SwapAssetIcon, {}),
@@ -51355,7 +51378,8 @@ function execAddRectangle(args, ctx) {
51355
51378
  fillStyle: args.fillStyle || "solid",
51356
51379
  strokeColor: args.strokeColor || "transparent",
51357
51380
  strokeWidth: args.strokeWidth ?? 0,
51358
- opacity: args.opacity ?? 100
51381
+ opacity: args.opacity ?? 100,
51382
+ roughness: 0
51359
51383
  });
51360
51384
  const elements = ctx.excalidrawAPI.getSceneElements();
51361
51385
  const frameIndex = elements.findIndex((el) => el.id === frameId);
@@ -51416,7 +51440,8 @@ function execAddText(args, ctx) {
51416
51440
  fontFamily: args.fontFamily || 2,
51417
51441
  strokeColor: args.strokeColor || "#000000",
51418
51442
  textAlign: args.textAlign || "left",
51419
- width: args.width
51443
+ width: args.width,
51444
+ roughness: 0
51420
51445
  });
51421
51446
  const elements = ctx.excalidrawAPI.getSceneElements();
51422
51447
  const frameIndex = elements.findIndex((el) => el.id === frameId);
@@ -51459,7 +51484,8 @@ async function execGenerateImage(args, ctx) {
51459
51484
  const height = args.height;
51460
51485
  const referenceImageIndex = args.referenceImageIndex;
51461
51486
  const referenceImageDataUrl = referenceImageIndex !== void 0 ? ctx.fileAttachments?.[referenceImageIndex]?.dataUrl : void 0;
51462
- const safePrompt = `${prompt} \u2014 NO text, NO typography, NO words, NO captions, NO watermarks, NO overlaid copy. Pure clean visual image only.`;
51487
+ const fontHint = ctx.brandHeadlineFontName ? ` Brand typography: ${ctx.brandHeadlineFontName}.` : ctx.brandBodyFontName ? ` Brand typography: ${ctx.brandBodyFontName}.` : "";
51488
+ const safePrompt = `${prompt}${fontHint} \u2014 NO text, NO typography, NO words, NO captions, NO watermarks, NO overlaid copy. Pure clean visual image only.`;
51463
51489
  if (!frameId || !prompt) {
51464
51490
  return {
51465
51491
  success: false,
@@ -52689,15 +52715,17 @@ function buildBrandContextMessage(ctx) {
52689
52715
  if (headline?.family) {
52690
52716
  const sizeHint = headline.sizeScale ? ` (suggested size: ${SIZE_SCALE_MAP[headline.sizeScale] ?? headline.sizeScale})` : "";
52691
52717
  const idNote = headline.fontFamilyId ? ` \u2014 custom font registered in canvas; use \`font-family: "${headline.family}", Arial, sans-serif\` in your HTML CSS` : ` \u2014 no custom font file loaded; use \`font-family: "${headline.family}", Arial, sans-serif\` in your HTML CSS (will render as Arial on canvas)`;
52718
+ const fileNote = headline.fontName ? ` [file: ${headline.fontName}]` : "";
52692
52719
  lines.push(
52693
- `**Headline font**: ${headline.family}${headline.weight ? ` weight ${headline.weight}` : ""}${sizeHint}${idNote}`
52720
+ `**Headline font**: ${headline.family}${headline.weight ? ` weight ${headline.weight}` : ""}${sizeHint}${idNote}${fileNote}`
52694
52721
  );
52695
52722
  }
52696
52723
  if (body?.family) {
52697
52724
  const sizeHint = body.sizeScale ? ` (suggested size: ${SIZE_SCALE_MAP[body.sizeScale] ?? body.sizeScale})` : "";
52698
52725
  const idNote = body.fontFamilyId ? ` \u2014 custom font registered in canvas; use \`font-family: "${body.family}", Arial, sans-serif\` in your HTML CSS` : ` \u2014 no custom font file loaded; use \`font-family: "${body.family}", Arial, sans-serif\` in your HTML CSS (will render as Arial on canvas)`;
52726
+ const fileNote = body.fontName ? ` [file: ${body.fontName}]` : "";
52699
52727
  lines.push(
52700
- `**Body font**: ${body.family}${body.weight ? ` weight ${body.weight}` : ""}${sizeHint}${idNote}`
52728
+ `**Body font**: ${body.family}${body.weight ? ` weight ${body.weight}` : ""}${sizeHint}${idNote}${fileNote}`
52701
52729
  );
52702
52730
  }
52703
52731
  }
@@ -52796,7 +52824,9 @@ async function runAgentLoop(opts) {
52796
52824
  const augmentedToolCtx = {
52797
52825
  ...toolCtx,
52798
52826
  ...Object.keys(customFontMap).length ? { customFontMap } : {},
52799
- ...allImageAttachments.length ? { fileAttachments: allImageAttachments } : {}
52827
+ ...allImageAttachments.length ? { fileAttachments: allImageAttachments } : {},
52828
+ ...brandContext?.typography?.headline?.fontName ? { brandHeadlineFontName: brandContext.typography.headline.fontName } : {},
52829
+ ...brandContext?.typography?.body?.fontName ? { brandBodyFontName: brandContext.typography.body.fontName } : {}
52800
52830
  };
52801
52831
  const messages = [{ role: "system", content: SYSTEM_PROMPT }];
52802
52832
  if (brandContext) {
@@ -55008,11 +55038,8 @@ var ExcalidrawBase = (props) => {
55008
55038
  document.removeEventListener("touchmove", handleTouchMove);
55009
55039
  };
55010
55040
  }, []);
55011
- useEffect62(() => {
55012
- if (!customFonts?.length) {
55013
- return;
55014
- }
55015
- for (const spec of customFonts) {
55041
+ useMemo15(() => {
55042
+ for (const spec of customFonts ?? []) {
55016
55043
  Fonts.registerCustomFont(spec);
55017
55044
  }
55018
55045
  }, [customFonts]);