canvu-react 0.4.72 → 0.4.74

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/react.cjs CHANGED
@@ -2260,6 +2260,7 @@ function ImagesMenu({
2260
2260
  onItemsChange,
2261
2261
  onFocusItem,
2262
2262
  labels,
2263
+ hiddenActions,
2263
2264
  defaultOpen = false,
2264
2265
  collapsedButtonClassName,
2265
2266
  collapsedButtonStyle,
@@ -2275,6 +2276,10 @@ function ImagesMenu({
2275
2276
  react.useEffect(() => {
2276
2277
  ensureOpenKeyframe();
2277
2278
  }, []);
2279
+ const hiddenActionSet = react.useMemo(
2280
+ () => new Set(hiddenActions ?? []),
2281
+ [hiddenActions]
2282
+ );
2278
2283
  if (managed.length === 0) {
2279
2284
  return null;
2280
2285
  }
@@ -2349,6 +2354,7 @@ function ImagesMenu({
2349
2354
  {
2350
2355
  item,
2351
2356
  labels: resolvedLabels,
2357
+ hiddenActionSet,
2352
2358
  onFocus: onFocusItem ? () => onFocusItem(item) : void 0,
2353
2359
  onCopy: () => onItemsChange(copyManagedImage(items, item.id)),
2354
2360
  onRotate: () => onItemsChange(rotateManagedImage(items, item.id)),
@@ -2365,6 +2371,7 @@ function ImagesMenu({
2365
2371
  function ImagesMenuRow({
2366
2372
  item,
2367
2373
  labels,
2374
+ hiddenActionSet,
2368
2375
  onFocus,
2369
2376
  onCopy,
2370
2377
  onRotate,
@@ -2404,9 +2411,9 @@ function ImagesMenuRow({
2404
2411
  ),
2405
2412
  /* @__PURE__ */ jsxRuntime.jsx(FocusTarget, { label: labels.focus, onFocus, children: /* @__PURE__ */ jsxRuntime.jsx("div", { style: thumbBoxStyle, children: src ? /* @__PURE__ */ jsxRuntime.jsx("img", { src, alt: "", style: thumbImgStyle, draggable: false }) : null }) }),
2406
2413
  /* @__PURE__ */ jsxRuntime.jsxs("div", { style: actionsColumnStyle, children: [
2407
- /* @__PURE__ */ jsxRuntime.jsx(ImagesMenuAction, { label: labels.duplicate, onClick: onCopy, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CopyPlus, { size: 18 }) }),
2408
- /* @__PURE__ */ jsxRuntime.jsx(ImagesMenuAction, { label: labels.rotate, onClick: onRotate, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCw, { size: 18 }) }),
2409
- /* @__PURE__ */ jsxRuntime.jsx(ImagesMenuAction, { label: labels.delete, onClick: onDelete, danger: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { size: 18 }) })
2414
+ !hiddenActionSet.has("duplicate") ? /* @__PURE__ */ jsxRuntime.jsx(ImagesMenuAction, { label: labels.duplicate, onClick: onCopy, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CopyPlus, { size: 18 }) }) : null,
2415
+ !hiddenActionSet.has("rotate") ? /* @__PURE__ */ jsxRuntime.jsx(ImagesMenuAction, { label: labels.rotate, onClick: onRotate, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.RotateCw, { size: 18 }) }) : null,
2416
+ !hiddenActionSet.has("delete") ? /* @__PURE__ */ jsxRuntime.jsx(ImagesMenuAction, { label: labels.delete, onClick: onDelete, danger: true, children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.Trash2, { size: 18 }) }) : null
2410
2417
  ] })
2411
2418
  ] });
2412
2419
  }
@@ -8554,6 +8561,11 @@ function shallowEqualStringArray(a, b) {
8554
8561
 
8555
8562
  // src/react/stroke-input.ts
8556
8563
  var MAX_INTERPOLATED_POINTS_PER_SAMPLE = 192;
8564
+ var MIN_CURVED_INTERPOLATION_DOT = -0.15;
8565
+ var MAX_STRAIGHT_INTERPOLATION_DOT = 0.985;
8566
+ var CURVED_INTERPOLATION_TENSION = 0.22;
8567
+ var MAX_CURVED_CONTROL_DISTANCE_RATIO = 0.5;
8568
+ var MIN_POINT_DISTANCE_SQUARED = 1e-12;
8557
8569
  function getPointerEventSamples(event) {
8558
8570
  if (typeof event.getCoalescedEvents !== "function") {
8559
8571
  return [event];
@@ -8568,6 +8580,62 @@ var resolveInterpolatedPressure = (lastPoint, nextPoint, ratio) => {
8568
8580
  return ratio === 1 ? nextPoint.pressure : void 0;
8569
8581
  };
8570
8582
  var resolveMaxStepWorld = (maxStepWorld) => Number.isFinite(maxStepWorld) && maxStepWorld > 0 ? maxStepWorld : Number.POSITIVE_INFINITY;
8583
+ var squaredDistance = (firstPoint, secondPoint) => {
8584
+ const deltaX = secondPoint.x - firstPoint.x;
8585
+ const deltaY = secondPoint.y - firstPoint.y;
8586
+ return deltaX * deltaX + deltaY * deltaY;
8587
+ };
8588
+ var resolvePreviousDistinctPoint = (points, lastPoint) => {
8589
+ for (let index = points.length - 2; index >= 0; index--) {
8590
+ const candidatePoint = points[index];
8591
+ if (candidatePoint && squaredDistance(candidatePoint, lastPoint) > MIN_POINT_DISTANCE_SQUARED) {
8592
+ return candidatePoint;
8593
+ }
8594
+ }
8595
+ return void 0;
8596
+ };
8597
+ var shouldUseCurvedInterpolation = (previousPoint, lastPoint, nextPoint) => {
8598
+ if (!previousPoint) return false;
8599
+ const incomingX = lastPoint.x - previousPoint.x;
8600
+ const incomingY = lastPoint.y - previousPoint.y;
8601
+ const outgoingX = nextPoint.x - lastPoint.x;
8602
+ const outgoingY = nextPoint.y - lastPoint.y;
8603
+ const incomingLengthSquared = incomingX * incomingX + incomingY * incomingY;
8604
+ const outgoingLengthSquared = outgoingX * outgoingX + outgoingY * outgoingY;
8605
+ if (incomingLengthSquared <= MIN_POINT_DISTANCE_SQUARED || outgoingLengthSquared <= MIN_POINT_DISTANCE_SQUARED) {
8606
+ return false;
8607
+ }
8608
+ const directionDot = (incomingX * outgoingX + incomingY * outgoingY) / Math.sqrt(incomingLengthSquared * outgoingLengthSquared);
8609
+ return directionDot >= MIN_CURVED_INTERPOLATION_DOT && directionDot <= MAX_STRAIGHT_INTERPOLATION_DOT;
8610
+ };
8611
+ var resolveCurvedControlPoint = (previousPoint, lastPoint, nextPoint, distance) => {
8612
+ const tangentX = nextPoint.x - previousPoint.x;
8613
+ const tangentY = nextPoint.y - previousPoint.y;
8614
+ const tangentLength = Math.sqrt(tangentX * tangentX + tangentY * tangentY);
8615
+ if (tangentLength <= MIN_POINT_DISTANCE_SQUARED) return void 0;
8616
+ const controlDistance = Math.min(
8617
+ distance * MAX_CURVED_CONTROL_DISTANCE_RATIO,
8618
+ tangentLength * CURVED_INTERPOLATION_TENSION
8619
+ );
8620
+ const scale = controlDistance / tangentLength;
8621
+ return {
8622
+ x: lastPoint.x + tangentX * scale,
8623
+ y: lastPoint.y + tangentY * scale
8624
+ };
8625
+ };
8626
+ var resolveInterpolatedPosition = (lastPoint, nextPoint, controlPoint, ratio) => {
8627
+ if (!controlPoint) {
8628
+ return {
8629
+ x: lastPoint.x + (nextPoint.x - lastPoint.x) * ratio,
8630
+ y: lastPoint.y + (nextPoint.y - lastPoint.y) * ratio
8631
+ };
8632
+ }
8633
+ const inverseRatio = 1 - ratio;
8634
+ return {
8635
+ x: inverseRatio * inverseRatio * lastPoint.x + 2 * inverseRatio * ratio * controlPoint.x + ratio * ratio * nextPoint.x,
8636
+ y: inverseRatio * inverseRatio * lastPoint.y + 2 * inverseRatio * ratio * controlPoint.y + ratio * ratio * nextPoint.y
8637
+ };
8638
+ };
8571
8639
  function appendInterpolatedStrokePoint(points, nextPoint, maxStepWorld) {
8572
8640
  if (points.length === 0) return [nextPoint];
8573
8641
  const lastPoint = points[points.length - 1];
@@ -8575,19 +8643,31 @@ function appendInterpolatedStrokePoint(points, nextPoint, maxStepWorld) {
8575
8643
  const deltaX = nextPoint.x - lastPoint.x;
8576
8644
  const deltaY = nextPoint.y - lastPoint.y;
8577
8645
  const distanceSquared = deltaX * deltaX + deltaY * deltaY;
8578
- if (distanceSquared < 1e-12) return points;
8646
+ if (distanceSquared < MIN_POINT_DISTANCE_SQUARED) return points;
8579
8647
  const distance = Math.sqrt(distanceSquared);
8580
8648
  const stepCount = Math.min(
8581
8649
  MAX_INTERPOLATED_POINTS_PER_SAMPLE,
8582
8650
  Math.max(1, Math.ceil(distance / resolveMaxStepWorld(maxStepWorld)))
8583
8651
  );
8584
8652
  if (stepCount === 1) return [...points, nextPoint];
8653
+ const previousPoint = resolvePreviousDistinctPoint(points, lastPoint);
8654
+ const controlPoint = shouldUseCurvedInterpolation(
8655
+ previousPoint,
8656
+ lastPoint,
8657
+ nextPoint
8658
+ ) ? resolveCurvedControlPoint(previousPoint, lastPoint, nextPoint, distance) : void 0;
8585
8659
  const interpolatedPoints = Array.from({ length: stepCount }, (_, index) => {
8586
8660
  const ratio = (index + 1) / stepCount;
8587
8661
  const pressure = resolveInterpolatedPressure(lastPoint, nextPoint, ratio);
8662
+ const position = resolveInterpolatedPosition(
8663
+ lastPoint,
8664
+ nextPoint,
8665
+ controlPoint,
8666
+ ratio
8667
+ );
8588
8668
  return {
8589
- x: lastPoint.x + deltaX * ratio,
8590
- y: lastPoint.y + deltaY * ratio,
8669
+ x: position.x,
8670
+ y: position.y,
8591
8671
  ...pressure != null ? { pressure } : {}
8592
8672
  };
8593
8673
  });