canvu-react 0.4.25 → 0.4.27

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/native.cjs CHANGED
@@ -43,6 +43,7 @@ function escapeHtmlText(s) {
43
43
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
44
44
  }
45
45
  var DEFAULT_TEXT_FONT_SIZE = 18;
46
+ var DEFAULT_TEXT_TOOL_FONT_SIZE = 28;
46
47
  var TEXT_FONT_FAMILY = "Inter, -apple-system, BlinkMacSystemFont, ui-sans-serif, system-ui, sans-serif";
47
48
  var LINE_HEIGHT_RATIO = 22 / 18;
48
49
  var FIRST_LINE_BASELINE_RATIO = 20 / 18;
@@ -83,6 +84,12 @@ function lineHeightFor(fontSize) {
83
84
  function firstLineBaselineY(fontSize) {
84
85
  return fontSize * FIRST_LINE_BASELINE_RATIO;
85
86
  }
87
+ function textBaselineYFor(fontSize) {
88
+ return firstLineBaselineY(fontSize);
89
+ }
90
+ function textLineHeightFor(fontSize) {
91
+ return lineHeightFor(fontSize);
92
+ }
86
93
  function measureTextBoundsLocal(content, fontSize = DEFAULT_TEXT_FONT_SIZE) {
87
94
  const cacheKey = textMeasureCacheKey(content, fontSize);
88
95
  const cached = textMeasureCache.get(cacheKey);
@@ -1305,16 +1312,17 @@ function parseSvgTransform(s) {
1305
1312
  function skiaCameraTransform(zoom, panX, panY) {
1306
1313
  return [{ translateX: panX }, { translateY: panY }, { scale: zoom }];
1307
1314
  }
1308
- function skiaItemPlacementTransform(x, y, cx, cy, rotationRad) {
1309
- const result = [];
1315
+ function skiaItemTranslationTransform(x, y) {
1316
+ return [{ translateX: x }, { translateY: y }];
1317
+ }
1318
+ function skiaItemRotationTransform(rotationRad) {
1310
1319
  if (Math.abs(rotationRad) > 1e-12) {
1311
- result.push({
1312
- rotate: rotationRad,
1313
- origin: { x: cx, y: cy }
1314
- });
1320
+ return [{ rotate: rotationRad }];
1315
1321
  }
1316
- result.push({ translateX: x }, { translateY: y });
1317
- return result;
1322
+ return [];
1323
+ }
1324
+ function skiaItemRotationOrigin(x, y, cx, cy) {
1325
+ return { x: x + cx, y: y + cy };
1318
1326
  }
1319
1327
  function rgbaFromHexAndOpacity(hex, opacity) {
1320
1328
  if (!hex) return hex;
@@ -2164,8 +2172,10 @@ function NativeInteractionOverlay({
2164
2172
  const b = normalizeRect(it.bounds);
2165
2173
  const cx = b.width / 2;
2166
2174
  const cy = b.height / 2;
2167
- const t = skiaItemPlacementTransform(it.x, it.y, cx, cy, it.rotation ?? 0);
2168
- return /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.Group, { transform: t, children: /* @__PURE__ */ jsxRuntime.jsx(
2175
+ const rotationTransform = skiaItemRotationTransform(it.rotation ?? 0);
2176
+ const rotationOrigin = skiaItemRotationOrigin(it.x, it.y, cx, cy);
2177
+ const translationTransform = skiaItemTranslationTransform(it.x, it.y);
2178
+ const selectionRect = /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.Group, { transform: translationTransform, children: /* @__PURE__ */ jsxRuntime.jsx(
2169
2179
  reactNativeSkia.Rect,
2170
2180
  {
2171
2181
  x: 0,
@@ -2177,7 +2187,11 @@ function NativeInteractionOverlay({
2177
2187
  strokeWidth: overlayStrokeWorld,
2178
2188
  antiAlias: true
2179
2189
  }
2180
- ) }, it.id);
2190
+ ) });
2191
+ if (rotationTransform.length === 0) {
2192
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.Group, { children: selectionRect }, it.id);
2193
+ }
2194
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.Group, { transform: rotationTransform, origin: rotationOrigin, children: selectionRect }, it.id);
2181
2195
  }),
2182
2196
  showResizeHandles && bSingle && single && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
2183
2197
  HANDLE_ORDER.map((hid) => {
@@ -2438,16 +2452,28 @@ function NativeInteractionOverlay({
2438
2452
  const b = normalizeRect(it.bounds);
2439
2453
  const cx = b.width / 2;
2440
2454
  const cy = b.height / 2;
2441
- const t = skiaItemPlacementTransform(it.x, it.y, cx, cy, it.rotation ?? 0);
2442
- return /* @__PURE__ */ jsxRuntime.jsx(
2455
+ const rotationTransform = skiaItemRotationTransform(it.rotation ?? 0);
2456
+ const rotationOrigin = skiaItemRotationOrigin(it.x, it.y, cx, cy);
2457
+ const translationTransform = skiaItemTranslationTransform(it.x, it.y);
2458
+ const preview = /* @__PURE__ */ jsxRuntime.jsx(
2443
2459
  reactNativeSkia.Group,
2444
2460
  {
2445
- transform: t,
2461
+ transform: translationTransform,
2446
2462
  opacity: ERASER_PREVIEW_OPACITY,
2447
2463
  children: /* @__PURE__ */ jsxRuntime.jsx(NativeShapeRenderer, { item: it })
2448
2464
  },
2449
2465
  `erase-${it.id}`
2450
2466
  );
2467
+ if (rotationTransform.length === 0) return preview;
2468
+ return /* @__PURE__ */ jsxRuntime.jsx(
2469
+ reactNativeSkia.Group,
2470
+ {
2471
+ transform: rotationTransform,
2472
+ origin: rotationOrigin,
2473
+ children: preview
2474
+ },
2475
+ `erase-rot-${it.id}`
2476
+ );
2451
2477
  }) });
2452
2478
  }, [eraserPreviewItems]);
2453
2479
  const eraserTrailElements = react.useMemo(() => {
@@ -2639,14 +2665,12 @@ var MemoShape = react.memo(function MemoShape2({
2639
2665
  const b = normalizeRect(item.bounds);
2640
2666
  const cx = b.width / 2;
2641
2667
  const cy = b.height / 2;
2642
- const itemTransform = skiaItemPlacementTransform(
2643
- item.x,
2644
- item.y,
2645
- cx,
2646
- cy,
2647
- item.rotation ?? 0
2648
- );
2649
- return /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.Group, { transform: itemTransform, children: /* @__PURE__ */ jsxRuntime.jsx(NativeShapeRenderer, { item }) });
2668
+ const rotationTransform = skiaItemRotationTransform(item.rotation ?? 0);
2669
+ const rotationOrigin = skiaItemRotationOrigin(item.x, item.y, cx, cy);
2670
+ const translationTransform = skiaItemTranslationTransform(item.x, item.y);
2671
+ const shape = /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.Group, { transform: translationTransform, children: /* @__PURE__ */ jsxRuntime.jsx(NativeShapeRenderer, { item }) });
2672
+ if (rotationTransform.length === 0) return shape;
2673
+ return /* @__PURE__ */ jsxRuntime.jsx(reactNativeSkia.Group, { transform: rotationTransform, origin: rotationOrigin, children: shape });
2650
2674
  });
2651
2675
  function NativeSceneRenderer({
2652
2676
  items,
@@ -4617,17 +4641,21 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
4617
4641
  if (!change) return;
4618
4642
  if (st.tool === "text") {
4619
4643
  const id = createShapeId();
4644
+ const fs = DEFAULT_TEXT_TOOL_FONT_SIZE;
4645
+ const baseline = textBaselineYFor(fs);
4646
+ const lh = textLineHeightFor(fs);
4647
+ const minH = Math.max(26, baseline + Math.max(4, lh * 0.2));
4620
4648
  const item = createTextItem(
4621
4649
  id,
4622
4650
  {
4623
4651
  x: st.startWorld.x - 4,
4624
- y: st.startWorld.y - 18,
4652
+ y: st.startWorld.y - baseline,
4625
4653
  width: 160,
4626
- height: 26
4654
+ height: minH
4627
4655
  },
4628
4656
  "Text",
4629
4657
  strokeStyleRef.current,
4630
- 18
4658
+ fs
4631
4659
  );
4632
4660
  change([...itemsRef.current, item]);
4633
4661
  onSelectionChangeRef.current?.([id]);