@bwp-web/canvas 0.15.0 → 1.1.0

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.ts CHANGED
@@ -20,6 +20,8 @@ export type { ViewCanvasProviderProps, ViewCanvasContextValue, ViewCanvasViewpor
20
20
  export { useCanvasRef } from './context';
21
21
  export { ObjectOverlay } from './overlay';
22
22
  export type { ObjectOverlayProps } from './overlay';
23
+ export { OverlayContainer } from './overlay';
24
+ export type { OverlayContainerProps } from './overlay';
23
25
  export { OverlayContent } from './overlay';
24
26
  export type { OverlayContentProps } from './overlay';
25
27
  export { FixedSizeContent } from './overlay';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -165,6 +165,7 @@ function setupMousePan(canvas, getMode, isEnabled) {
165
165
  const isModifiedSelect = e instanceof MouseEvent && mode === "select" && (e.metaKey || e.ctrlKey);
166
166
  const shouldPan = mode === "pan" || isMiddleButton || isModifiedSelect || mode === "select" && !opt.target;
167
167
  if (shouldPan) {
168
+ e.preventDefault();
168
169
  isPanning = true;
169
170
  lastPanX = pos.x;
170
171
  lastPanY = pos.y;
@@ -3183,8 +3184,10 @@ function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
3183
3184
  const [state, setState] = useState3({
3184
3185
  visible: false,
3185
3186
  content: null,
3186
- position: { x: 0, y: 0 }
3187
+ position: { x: 0, y: 0 },
3188
+ ref: { current: null }
3187
3189
  });
3190
+ const tooltipElRef = useRef5(null);
3188
3191
  const hoveredObjectRef = useRef5(null);
3189
3192
  const optionsRef = useRef5(options);
3190
3193
  optionsRef.current = options;
@@ -3201,6 +3204,12 @@ function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
3201
3204
  y: bounds.top * zoom + vt[5] - 10
3202
3205
  };
3203
3206
  }
3207
+ function applyPositionToDOM(position) {
3208
+ const el = tooltipElRef.current;
3209
+ if (!el) return;
3210
+ el.style.left = `${position.x}px`;
3211
+ el.style.top = `${position.y}px`;
3212
+ }
3204
3213
  const handleMouseOver = (e) => {
3205
3214
  const target = e.target;
3206
3215
  if (!target) return;
@@ -3210,7 +3219,7 @@ function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
3210
3219
  hoveredObjectRef.current = target;
3211
3220
  const position = calculatePosition(target);
3212
3221
  if (position) {
3213
- setState({ visible: true, content, position });
3222
+ setState({ visible: true, content, position, ref: tooltipElRef });
3214
3223
  }
3215
3224
  }
3216
3225
  };
@@ -3224,7 +3233,7 @@ function useCanvasTooltip(canvasRefOrOptions, maybeOptions) {
3224
3233
  if (!hoveredObjectRef.current) return;
3225
3234
  const position = calculatePosition(hoveredObjectRef.current);
3226
3235
  if (position) {
3227
- setState((prev) => prev.visible ? { ...prev, position } : prev);
3236
+ applyPositionToDOM(position);
3228
3237
  }
3229
3238
  };
3230
3239
  canvas.on("mouse:over", handleMouseOver);
@@ -3442,10 +3451,66 @@ function useViewCanvasState() {
3442
3451
  }
3443
3452
 
3444
3453
  // src/overlay/ObjectOverlay.tsx
3445
- import { useEffect as useEffect7, useRef as useRef7 } from "react";
3446
- import { Stack } from "@mui/material";
3454
+ import { useEffect as useEffect8, useRef as useRef8 } from "react";
3455
+ import { Stack as Stack2 } from "@mui/material";
3447
3456
  import { util as util4 } from "fabric";
3457
+
3458
+ // src/overlay/OverlayContainer.tsx
3459
+ import {
3460
+ createContext as createContext4,
3461
+ useContext as useContext4,
3462
+ useEffect as useEffect7,
3463
+ useRef as useRef7
3464
+ } from "react";
3465
+ import { Stack } from "@mui/material";
3448
3466
  import { jsx as jsx4 } from "react/jsx-runtime";
3467
+ var OverlayContainerContext = createContext4(false);
3468
+ function useIsInsideOverlayContainer() {
3469
+ return useContext4(OverlayContainerContext);
3470
+ }
3471
+ function OverlayContainer({
3472
+ canvasRef: canvasRefProp,
3473
+ children
3474
+ }) {
3475
+ const contextCanvasRef = useCanvasRef();
3476
+ const canvasRef = canvasRefProp ?? contextCanvasRef;
3477
+ const containerRef = useRef7(null);
3478
+ useEffect7(() => {
3479
+ const canvas = canvasRef?.current;
3480
+ const el = containerRef.current;
3481
+ if (!canvas || !el) return;
3482
+ function updateContainer() {
3483
+ if (!canvas || !el) return;
3484
+ const vt = canvas.viewportTransform;
3485
+ if (!vt) return;
3486
+ el.style.transform = `translate(${vt[4]}px, ${vt[5]}px)`;
3487
+ }
3488
+ updateContainer();
3489
+ canvas.on("after:render", updateContainer);
3490
+ return () => {
3491
+ canvas.off("after:render", updateContainer);
3492
+ };
3493
+ }, [canvasRef]);
3494
+ return /* @__PURE__ */ jsx4(OverlayContainerContext.Provider, { value: true, children: /* @__PURE__ */ jsx4(
3495
+ Stack,
3496
+ {
3497
+ ref: containerRef,
3498
+ sx: {
3499
+ position: "absolute",
3500
+ left: 0,
3501
+ top: 0,
3502
+ width: "100%",
3503
+ height: "100%",
3504
+ pointerEvents: "none",
3505
+ willChange: "transform"
3506
+ },
3507
+ children
3508
+ }
3509
+ ) });
3510
+ }
3511
+
3512
+ // src/overlay/ObjectOverlay.tsx
3513
+ import { jsx as jsx5 } from "react/jsx-runtime";
3449
3514
  function ObjectOverlay({
3450
3515
  canvasRef: canvasRefProp,
3451
3516
  object,
@@ -3455,8 +3520,10 @@ function ObjectOverlay({
3455
3520
  }) {
3456
3521
  const contextCanvasRef = useCanvasRef();
3457
3522
  const canvasRef = canvasRefProp ?? contextCanvasRef;
3458
- const stackRef = useRef7(null);
3459
- useEffect7(() => {
3523
+ const insideContainer = useIsInsideOverlayContainer();
3524
+ const stackRef = useRef8(null);
3525
+ const prev = useRef8({ transform: "", w: "", h: "" });
3526
+ useEffect8(() => {
3460
3527
  const canvas = canvasRef?.current;
3461
3528
  if (!canvas || !object) return;
3462
3529
  function update() {
@@ -3468,15 +3535,32 @@ function ObjectOverlay({
3468
3535
  const center = object.getCenterPoint();
3469
3536
  const actualWidth = (object.width ?? 0) * (object.scaleX ?? 1);
3470
3537
  const actualHeight = (object.height ?? 0) * (object.scaleY ?? 1);
3471
- const screenCoords = util4.transformPoint(center, vt);
3472
3538
  const screenWidth = actualWidth * zoom;
3473
3539
  const screenHeight = actualHeight * zoom;
3474
3540
  const angle = object.angle ?? 0;
3475
- el.style.left = `${screenCoords.x - screenWidth / 2}px`;
3476
- el.style.top = `${screenCoords.y - screenHeight / 2}px`;
3477
- el.style.width = `${screenWidth}px`;
3478
- el.style.height = `${screenHeight}px`;
3479
- el.style.transform = angle !== 0 ? `rotate(${angle}deg)` : "";
3541
+ let tx;
3542
+ let ty;
3543
+ if (insideContainer) {
3544
+ tx = center.x * zoom - screenWidth / 2;
3545
+ ty = center.y * zoom - screenHeight / 2;
3546
+ } else {
3547
+ const screenCoords = util4.transformPoint(center, vt);
3548
+ tx = screenCoords.x - screenWidth / 2;
3549
+ ty = screenCoords.y - screenHeight / 2;
3550
+ }
3551
+ const transform = angle !== 0 ? `translate(${tx}px, ${ty}px) rotate(${angle}deg)` : `translate(${tx}px, ${ty}px)`;
3552
+ if (transform !== prev.current.transform) {
3553
+ el.style.transform = transform;
3554
+ prev.current.transform = transform;
3555
+ }
3556
+ const w = `${screenWidth}px`;
3557
+ const h = `${screenHeight}px`;
3558
+ if (prev.current.w !== w || prev.current.h !== h) {
3559
+ el.style.width = w;
3560
+ el.style.height = h;
3561
+ prev.current.w = w;
3562
+ prev.current.h = h;
3563
+ }
3480
3564
  }
3481
3565
  update();
3482
3566
  canvas.on("after:render", update);
@@ -3488,19 +3572,23 @@ function ObjectOverlay({
3488
3572
  object.off("moving", update);
3489
3573
  object.off("scaling", update);
3490
3574
  object.off("rotating", update);
3575
+ prev.current = { transform: "", w: "", h: "" };
3491
3576
  };
3492
- }, [canvasRef, object]);
3577
+ }, [canvasRef, object, insideContainer]);
3493
3578
  if (!object) return null;
3494
- return /* @__PURE__ */ jsx4(
3495
- Stack,
3579
+ return /* @__PURE__ */ jsx5(
3580
+ Stack2,
3496
3581
  {
3497
3582
  ref: stackRef,
3498
3583
  sx: {
3499
3584
  position: "absolute",
3585
+ left: 0,
3586
+ top: 0,
3500
3587
  pointerEvents: "none",
3501
3588
  alignItems: "center",
3502
3589
  justifyContent: "center",
3503
3590
  zIndex: 1,
3591
+ willChange: "transform",
3504
3592
  ...sx
3505
3593
  },
3506
3594
  ...rest,
@@ -3510,28 +3598,28 @@ function ObjectOverlay({
3510
3598
  }
3511
3599
 
3512
3600
  // src/overlay/OverlayContent.tsx
3513
- import { Stack as Stack2 } from "@mui/material";
3514
- import { useEffect as useEffect8, useRef as useRef8 } from "react";
3515
- import { jsx as jsx5 } from "react/jsx-runtime";
3601
+ import { Stack as Stack3 } from "@mui/material";
3602
+ import { useEffect as useEffect9, useRef as useRef9 } from "react";
3603
+ import { jsx as jsx6 } from "react/jsx-runtime";
3516
3604
  function OverlayContent({
3517
3605
  children,
3518
- padding = 4,
3606
+ padding = 6,
3519
3607
  maxScale = 2,
3520
3608
  sx,
3521
3609
  ...rest
3522
3610
  }) {
3523
- const outerRef = useRef8(null);
3524
- const innerRef = useRef8(null);
3525
- useEffect8(() => {
3611
+ const outerRef = useRef9(null);
3612
+ const innerRef = useRef9(null);
3613
+ useEffect9(() => {
3526
3614
  const outer = outerRef.current;
3527
3615
  const inner = innerRef.current;
3528
3616
  if (!outer || !inner) return;
3617
+ let natW = 0;
3618
+ let natH = 0;
3529
3619
  function fit() {
3530
3620
  if (!outer || !inner) return;
3531
3621
  const containerW = outer.clientWidth;
3532
3622
  const containerH = outer.clientHeight;
3533
- const natW = inner.scrollWidth;
3534
- const natH = inner.scrollHeight;
3535
3623
  if (natW === 0 || natH === 0 || containerW <= 0 || containerH <= 0) {
3536
3624
  inner.style.transform = "";
3537
3625
  inner.style.removeProperty("--overlay-scale");
@@ -3545,14 +3633,25 @@ function OverlayContent({
3545
3633
  inner.style.transform = `scale(${scale})`;
3546
3634
  inner.style.setProperty("--overlay-scale", String(scale));
3547
3635
  }
3548
- const observer = new ResizeObserver(fit);
3636
+ const observer = new ResizeObserver((entries) => {
3637
+ for (const entry of entries) {
3638
+ if (entry.target === inner) {
3639
+ natW = inner.scrollWidth;
3640
+ natH = inner.scrollHeight;
3641
+ break;
3642
+ }
3643
+ }
3644
+ fit();
3645
+ });
3549
3646
  observer.observe(outer);
3550
3647
  observer.observe(inner);
3648
+ natW = inner.scrollWidth;
3649
+ natH = inner.scrollHeight;
3551
3650
  fit();
3552
3651
  return () => observer.disconnect();
3553
3652
  }, [padding, maxScale]);
3554
- return /* @__PURE__ */ jsx5(
3555
- Stack2,
3653
+ return /* @__PURE__ */ jsx6(
3654
+ Stack3,
3556
3655
  {
3557
3656
  ref: outerRef,
3558
3657
  sx: {
@@ -3564,8 +3663,8 @@ function OverlayContent({
3564
3663
  ...sx
3565
3664
  },
3566
3665
  ...rest,
3567
- children: /* @__PURE__ */ jsx5(
3568
- Stack2,
3666
+ children: /* @__PURE__ */ jsx6(
3667
+ Stack3,
3569
3668
  {
3570
3669
  ref: innerRef,
3571
3670
  sx: {
@@ -3582,9 +3681,9 @@ function OverlayContent({
3582
3681
  }
3583
3682
 
3584
3683
  // src/overlay/FixedSizeContent.tsx
3585
- import { Stack as Stack3 } from "@mui/material";
3586
- import { useEffect as useEffect9, useRef as useRef9 } from "react";
3587
- import { jsx as jsx6 } from "react/jsx-runtime";
3684
+ import { Stack as Stack4 } from "@mui/material";
3685
+ import { useEffect as useEffect10, useRef as useRef10 } from "react";
3686
+ import { jsx as jsx7 } from "react/jsx-runtime";
3588
3687
  function FixedSizeContent({
3589
3688
  children,
3590
3689
  hideOnOverflow = true,
@@ -3592,9 +3691,9 @@ function FixedSizeContent({
3592
3691
  sx,
3593
3692
  ...rest
3594
3693
  }) {
3595
- const ref = useRef9(null);
3596
- const totalContentHeightRef = useRef9(0);
3597
- useEffect9(() => {
3694
+ const ref = useRef10(null);
3695
+ const totalContentHeightRef = useRef10(0);
3696
+ useEffect10(() => {
3598
3697
  const el = ref.current;
3599
3698
  if (!el) return;
3600
3699
  let clipAncestor = el.parentElement;
@@ -3605,34 +3704,45 @@ function FixedSizeContent({
3605
3704
  if (!clipAncestor) return;
3606
3705
  const ancestor = clipAncestor;
3607
3706
  totalContentHeightRef.current = el.parentElement?.scrollHeight ?? 0;
3608
- function check() {
3609
- requestAnimationFrame(() => {
3610
- if (!el) return;
3611
- const containerRect = ancestor.getBoundingClientRect();
3612
- el.style.maxWidth = `${Math.max(0, containerRect.width - truncationPadding * 2)}px`;
3613
- if (!hideOnOverflow) return;
3614
- const fits = containerRect.height >= totalContentHeightRef.current;
3615
- if (fits && el.style.display === "none") {
3616
- el.style.display = "";
3617
- totalContentHeightRef.current = el.parentElement?.scrollHeight ?? 0;
3618
- if (containerRect.height < totalContentHeightRef.current) {
3619
- el.style.display = "none";
3620
- }
3621
- } else if (!fits && el.style.display !== "none") {
3707
+ let rafId = 0;
3708
+ function doCheck() {
3709
+ if (!el) return;
3710
+ const containerW = ancestor.clientWidth;
3711
+ const containerH = ancestor.clientHeight;
3712
+ el.style.maxWidth = `${Math.max(0, containerW - truncationPadding * 2)}px`;
3713
+ if (!hideOnOverflow) return;
3714
+ const fits = containerH >= totalContentHeightRef.current;
3715
+ if (fits && el.style.display === "none") {
3716
+ el.style.display = "";
3717
+ totalContentHeightRef.current = el.parentElement?.scrollHeight ?? 0;
3718
+ if (containerH < totalContentHeightRef.current) {
3622
3719
  el.style.display = "none";
3623
3720
  }
3624
- if (el.style.display !== "none") {
3625
- totalContentHeightRef.current = el.parentElement?.scrollHeight ?? 0;
3626
- }
3627
- });
3721
+ } else if (!fits && el.style.display !== "none") {
3722
+ el.style.display = "none";
3723
+ }
3724
+ if (el.style.display !== "none") {
3725
+ totalContentHeightRef.current = el.parentElement?.scrollHeight ?? 0;
3726
+ }
3727
+ }
3728
+ function scheduleCheck() {
3729
+ if (!rafId) {
3730
+ rafId = requestAnimationFrame(() => {
3731
+ rafId = 0;
3732
+ doCheck();
3733
+ });
3734
+ }
3628
3735
  }
3629
- const observer = new ResizeObserver(check);
3736
+ const observer = new ResizeObserver(scheduleCheck);
3630
3737
  observer.observe(ancestor);
3631
- check();
3632
- return () => observer.disconnect();
3738
+ scheduleCheck();
3739
+ return () => {
3740
+ if (rafId) cancelAnimationFrame(rafId);
3741
+ observer.disconnect();
3742
+ };
3633
3743
  }, [hideOnOverflow, truncationPadding]);
3634
- return /* @__PURE__ */ jsx6(
3635
- Stack3,
3744
+ return /* @__PURE__ */ jsx7(
3745
+ Stack4,
3636
3746
  {
3637
3747
  ref,
3638
3748
  sx: {
@@ -3656,9 +3766,9 @@ function FixedSizeContent({
3656
3766
  }
3657
3767
 
3658
3768
  // src/overlay/OverlayBadge.tsx
3659
- import { Stack as Stack4 } from "@mui/material";
3660
- import { useEffect as useEffect10, useRef as useRef10 } from "react";
3661
- import { jsx as jsx7 } from "react/jsx-runtime";
3769
+ import { Stack as Stack5 } from "@mui/material";
3770
+ import { useEffect as useEffect11, useRef as useRef11 } from "react";
3771
+ import { jsx as jsx8 } from "react/jsx-runtime";
3662
3772
  function toPx(v) {
3663
3773
  if (v === void 0) return void 0;
3664
3774
  return typeof v === "number" ? `${v}px` : v;
@@ -3688,10 +3798,19 @@ function ellipsePosition(angleDeg) {
3688
3798
  function toNum(v) {
3689
3799
  return typeof v === "number" ? v : 0;
3690
3800
  }
3801
+ function readOverlayScale(el) {
3802
+ let node = el.parentElement;
3803
+ while (node) {
3804
+ const val = node.style.getPropertyValue("--overlay-scale");
3805
+ if (val) return parseFloat(val) || 1;
3806
+ node = node.parentElement;
3807
+ }
3808
+ return 1;
3809
+ }
3691
3810
  function OverlayBadge({
3692
3811
  children,
3693
- maxScale = 2,
3694
- minScale = 0.75,
3812
+ maxScale = 1.5,
3813
+ minScale = 0.5,
3695
3814
  top,
3696
3815
  right,
3697
3816
  bottom,
@@ -3700,41 +3819,47 @@ function OverlayBadge({
3700
3819
  sx,
3701
3820
  ...rest
3702
3821
  }) {
3703
- const ref = useRef10(null);
3704
- const baseSize = useRef10(null);
3705
- useEffect10(() => {
3822
+ const ref = useRef11(null);
3823
+ const baseSize = useRef11(null);
3824
+ useEffect11(() => {
3706
3825
  const el = ref.current;
3707
3826
  if (!el) return;
3708
3827
  const ancestor = el.parentElement;
3709
3828
  if (!ancestor) return;
3710
- function update() {
3711
- requestAnimationFrame(() => {
3712
- if (!el || !ancestor) return;
3713
- const containerW = ancestor.clientWidth;
3714
- const containerH = ancestor.clientHeight;
3715
- if (containerW <= 0 || containerH <= 0) {
3716
- el.style.transform = "";
3717
- return;
3718
- }
3719
- if (!baseSize.current) {
3720
- baseSize.current = { w: containerW, h: containerH };
3721
- }
3722
- const ratio = Math.min(
3723
- containerW / baseSize.current.w,
3724
- containerH / baseSize.current.h
3725
- );
3726
- const ownScale = Math.max(minScale, Math.min(ratio, maxScale));
3727
- const overlayScale = parseFloat(
3728
- getComputedStyle(el).getPropertyValue("--overlay-scale")
3729
- ) || 1;
3730
- const scale = `scale(${ownScale / overlayScale})`;
3731
- el.style.transform = circular ? `translate(-50%, -50%) ${scale}` : scale;
3732
- });
3829
+ let rafId = 0;
3830
+ function doUpdate() {
3831
+ if (!el || !ancestor) return;
3832
+ const containerW = ancestor.clientWidth;
3833
+ const containerH = ancestor.clientHeight;
3834
+ if (containerW <= 0 || containerH <= 0) {
3835
+ el.style.transform = "";
3836
+ return;
3837
+ }
3838
+ if (!baseSize.current) {
3839
+ baseSize.current = { w: containerW, h: containerH };
3840
+ }
3841
+ const ratio = Math.min(
3842
+ containerW / baseSize.current.w,
3843
+ containerH / baseSize.current.h
3844
+ );
3845
+ const ownScale = Math.max(minScale, Math.min(ratio, maxScale));
3846
+ const overlayScale = readOverlayScale(el);
3847
+ const scale = `scale(${ownScale / overlayScale})`;
3848
+ el.style.transform = circular ? `translate(-50%, -50%) ${scale}` : scale;
3733
3849
  }
3734
- const observer = new ResizeObserver(update);
3850
+ function scheduleUpdate() {
3851
+ if (!rafId) {
3852
+ rafId = requestAnimationFrame(() => {
3853
+ rafId = 0;
3854
+ doUpdate();
3855
+ });
3856
+ }
3857
+ }
3858
+ const observer = new ResizeObserver(scheduleUpdate);
3735
3859
  observer.observe(ancestor);
3736
- update();
3860
+ scheduleUpdate();
3737
3861
  return () => {
3862
+ if (rafId) cancelAnimationFrame(rafId);
3738
3863
  observer.disconnect();
3739
3864
  baseSize.current = null;
3740
3865
  };
@@ -3754,8 +3879,8 @@ function OverlayBadge({
3754
3879
  bottom: toPx(bottom),
3755
3880
  left: toPx(left)
3756
3881
  };
3757
- return /* @__PURE__ */ jsx7(
3758
- Stack4,
3882
+ return /* @__PURE__ */ jsx8(
3883
+ Stack5,
3759
3884
  {
3760
3885
  ref,
3761
3886
  sx: {
@@ -3799,6 +3924,7 @@ export {
3799
3924
  FixedSizeContent,
3800
3925
  ObjectOverlay,
3801
3926
  OverlayBadge,
3927
+ OverlayContainer,
3802
3928
  OverlayContent,
3803
3929
  Point9 as Point,
3804
3930
  Polygon5 as Polygon,