@bwp-web/canvas 0.6.2 → 0.7.1

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.
@@ -8,6 +8,4 @@ export { useCanvasTooltip } from './useCanvasTooltip';
8
8
  export type { UseCanvasTooltipOptions, CanvasTooltipState, } from './useCanvasTooltip';
9
9
  export { useCanvasClick } from './useCanvasClick';
10
10
  export type { UseCanvasClickOptions } from './useCanvasClick';
11
- export { useObjectOverlay } from './useObjectOverlay';
12
- export type { UseObjectOverlayOptions } from './useObjectOverlay';
13
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE7E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EACV,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAE9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAE5D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,YAAY,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAE7E,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,YAAY,EACV,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.cjs CHANGED
@@ -30,6 +30,9 @@ __export(index_exports, {
30
30
  FabricCanvas: () => import_fabric19.Canvas,
31
31
  FabricImage: () => import_fabric19.FabricImage,
32
32
  FabricObject: () => import_fabric19.FabricObject,
33
+ FixedSizeContent: () => FixedSizeContent,
34
+ ObjectOverlay: () => ObjectOverlay,
35
+ OverlayContent: () => OverlayContent,
33
36
  Point: () => import_fabric19.Point,
34
37
  Polygon: () => import_fabric19.Polygon,
35
38
  Rect: () => import_fabric19.Rect,
@@ -75,7 +78,6 @@ __export(index_exports, {
75
78
  useCanvasEvents: () => useCanvasEvents,
76
79
  useCanvasTooltip: () => useCanvasTooltip,
77
80
  useEditCanvas: () => useEditCanvas,
78
- useObjectOverlay: () => useObjectOverlay,
79
81
  useViewCanvas: () => useViewCanvas,
80
82
  util: () => import_fabric19.util
81
83
  });
@@ -3043,18 +3045,24 @@ function useCanvasClick(canvasRef, onClick, options) {
3043
3045
  }, [canvasRef]);
3044
3046
  }
3045
3047
 
3046
- // src/hooks/useObjectOverlay.ts
3048
+ // src/overlay/ObjectOverlay.tsx
3047
3049
  var import_react8 = require("react");
3050
+ var import_material = require("@mui/material");
3048
3051
  var import_fabric18 = require("fabric");
3049
- function useObjectOverlay(canvasRef, object, options) {
3050
- const containerRef = (0, import_react8.useRef)(null);
3051
- const optionsRef = (0, import_react8.useRef)(options);
3052
- optionsRef.current = options;
3052
+ var import_jsx_runtime2 = require("react/jsx-runtime");
3053
+ function ObjectOverlay({
3054
+ canvasRef,
3055
+ object,
3056
+ sx,
3057
+ children,
3058
+ ...rest
3059
+ }) {
3060
+ const stackRef = (0, import_react8.useRef)(null);
3053
3061
  (0, import_react8.useEffect)(() => {
3054
3062
  const canvas = canvasRef.current;
3055
3063
  if (!canvas || !object) return;
3056
3064
  function update() {
3057
- const el = containerRef.current;
3065
+ const el = stackRef.current;
3058
3066
  if (!el || !canvas || !object) return;
3059
3067
  const zoom = canvas.getZoom();
3060
3068
  const vt = canvas.viewportTransform;
@@ -3066,32 +3074,11 @@ function useObjectOverlay(canvasRef, object, options) {
3066
3074
  const screenWidth = actualWidth * zoom;
3067
3075
  const screenHeight = actualHeight * zoom;
3068
3076
  const angle = object.angle ?? 0;
3069
- const opts = optionsRef.current;
3070
- if (opts?.autoScaleContent !== false) {
3071
- el.style.left = `${screenCoords.x - actualWidth / 2}px`;
3072
- el.style.top = `${screenCoords.y - actualHeight / 2}px`;
3073
- el.style.width = `${actualWidth}px`;
3074
- el.style.height = `${actualHeight}px`;
3075
- el.style.transformOrigin = "center center";
3076
- el.style.transform = angle !== 0 ? `scale(${zoom}) rotate(${angle}deg)` : `scale(${zoom})`;
3077
- el.style.rotate = "";
3078
- el.style.setProperty("--overlay-scale", String(zoom));
3079
- if (opts?.textSelector) {
3080
- const textMinScale = opts?.textMinScale ?? 0.5;
3081
- const textEls = el.querySelectorAll(opts.textSelector);
3082
- const display = zoom < textMinScale ? "none" : "";
3083
- textEls.forEach((t) => {
3084
- t.style.display = display;
3085
- });
3086
- }
3087
- } else {
3088
- el.style.left = `${screenCoords.x - screenWidth / 2}px`;
3089
- el.style.top = `${screenCoords.y - screenHeight / 2}px`;
3090
- el.style.width = `${screenWidth}px`;
3091
- el.style.height = `${screenHeight}px`;
3092
- el.style.transform = "";
3093
- el.style.rotate = angle !== 0 ? `${angle}deg` : "";
3094
- }
3077
+ el.style.left = `${screenCoords.x - screenWidth / 2}px`;
3078
+ el.style.top = `${screenCoords.y - screenHeight / 2}px`;
3079
+ el.style.width = `${screenWidth}px`;
3080
+ el.style.height = `${screenHeight}px`;
3081
+ el.style.transform = angle !== 0 ? `rotate(${angle}deg)` : "";
3095
3082
  }
3096
3083
  update();
3097
3084
  canvas.on("after:render", update);
@@ -3105,7 +3092,169 @@ function useObjectOverlay(canvasRef, object, options) {
3105
3092
  object.off("rotating", update);
3106
3093
  };
3107
3094
  }, [canvasRef, object]);
3108
- return containerRef;
3095
+ if (!object) return null;
3096
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
3097
+ import_material.Stack,
3098
+ {
3099
+ ref: stackRef,
3100
+ sx: {
3101
+ position: "absolute",
3102
+ pointerEvents: "none",
3103
+ alignItems: "center",
3104
+ justifyContent: "center",
3105
+ zIndex: 1,
3106
+ overflow: "hidden",
3107
+ ...sx
3108
+ },
3109
+ ...rest,
3110
+ children
3111
+ }
3112
+ );
3113
+ }
3114
+
3115
+ // src/overlay/OverlayContent.tsx
3116
+ var import_material2 = require("@mui/material");
3117
+ var import_react9 = require("react");
3118
+ var import_jsx_runtime3 = require("react/jsx-runtime");
3119
+ function OverlayContent({
3120
+ children,
3121
+ padding = 4,
3122
+ maxScale = 2,
3123
+ sx,
3124
+ ...rest
3125
+ }) {
3126
+ const outerRef = (0, import_react9.useRef)(null);
3127
+ const innerRef = (0, import_react9.useRef)(null);
3128
+ (0, import_react9.useEffect)(() => {
3129
+ const outer = outerRef.current;
3130
+ const inner = innerRef.current;
3131
+ if (!outer || !inner) return;
3132
+ function fit() {
3133
+ if (!outer || !inner) return;
3134
+ const containerW = outer.clientWidth;
3135
+ const containerH = outer.clientHeight;
3136
+ const natW = inner.scrollWidth;
3137
+ const natH = inner.scrollHeight;
3138
+ if (natW === 0 || natH === 0 || containerW <= 0 || containerH <= 0) {
3139
+ inner.style.transform = "";
3140
+ inner.style.removeProperty("--overlay-scale");
3141
+ return;
3142
+ }
3143
+ const scale = Math.min(
3144
+ containerW / (natW + padding * 2),
3145
+ containerH / (natH + padding * 2),
3146
+ maxScale
3147
+ );
3148
+ inner.style.transform = `scale(${scale})`;
3149
+ inner.style.setProperty("--overlay-scale", String(scale));
3150
+ }
3151
+ const observer = new ResizeObserver(fit);
3152
+ observer.observe(outer);
3153
+ observer.observe(inner);
3154
+ fit();
3155
+ return () => observer.disconnect();
3156
+ }, [padding, maxScale]);
3157
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3158
+ import_material2.Stack,
3159
+ {
3160
+ ref: outerRef,
3161
+ sx: {
3162
+ width: "100%",
3163
+ height: "100%",
3164
+ alignItems: "center",
3165
+ justifyContent: "center",
3166
+ overflow: "hidden",
3167
+ ...sx
3168
+ },
3169
+ ...rest,
3170
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3171
+ import_material2.Stack,
3172
+ {
3173
+ ref: innerRef,
3174
+ sx: {
3175
+ alignItems: "center",
3176
+ transformOrigin: "center center",
3177
+ flexShrink: 0,
3178
+ width: "max-content"
3179
+ },
3180
+ children
3181
+ }
3182
+ )
3183
+ }
3184
+ );
3185
+ }
3186
+
3187
+ // src/overlay/FixedSizeContent.tsx
3188
+ var import_material3 = require("@mui/material");
3189
+ var import_react10 = require("react");
3190
+ var import_jsx_runtime4 = require("react/jsx-runtime");
3191
+ function FixedSizeContent({
3192
+ children,
3193
+ hideOnOverflow = true,
3194
+ truncationPadding = 4,
3195
+ sx,
3196
+ ...rest
3197
+ }) {
3198
+ const ref = (0, import_react10.useRef)(null);
3199
+ const totalContentHeightRef = (0, import_react10.useRef)(0);
3200
+ (0, import_react10.useEffect)(() => {
3201
+ const el = ref.current;
3202
+ if (!el) return;
3203
+ let clipAncestor = el.parentElement;
3204
+ while (clipAncestor) {
3205
+ if (getComputedStyle(clipAncestor).overflow === "hidden") break;
3206
+ clipAncestor = clipAncestor.parentElement;
3207
+ }
3208
+ if (!clipAncestor) return;
3209
+ const ancestor = clipAncestor;
3210
+ totalContentHeightRef.current = el.parentElement?.scrollHeight ?? 0;
3211
+ function check() {
3212
+ requestAnimationFrame(() => {
3213
+ if (!el) return;
3214
+ const containerRect = ancestor.getBoundingClientRect();
3215
+ el.style.maxWidth = `${Math.max(0, containerRect.width - truncationPadding * 2)}px`;
3216
+ if (!hideOnOverflow) return;
3217
+ const fits = containerRect.height >= totalContentHeightRef.current;
3218
+ if (fits && el.style.display === "none") {
3219
+ el.style.display = "";
3220
+ totalContentHeightRef.current = el.parentElement?.scrollHeight ?? 0;
3221
+ if (containerRect.height < totalContentHeightRef.current) {
3222
+ el.style.display = "none";
3223
+ }
3224
+ } else if (!fits && el.style.display !== "none") {
3225
+ el.style.display = "none";
3226
+ }
3227
+ if (el.style.display !== "none") {
3228
+ totalContentHeightRef.current = el.parentElement?.scrollHeight ?? 0;
3229
+ }
3230
+ });
3231
+ }
3232
+ const observer = new ResizeObserver(check);
3233
+ observer.observe(ancestor);
3234
+ check();
3235
+ return () => observer.disconnect();
3236
+ }, [hideOnOverflow, truncationPadding]);
3237
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3238
+ import_material3.Stack,
3239
+ {
3240
+ ref,
3241
+ sx: {
3242
+ transform: "scale(calc(1 / var(--overlay-scale, 1)))",
3243
+ transformOrigin: "center center",
3244
+ flexShrink: 0,
3245
+ width: "max-content",
3246
+ overflow: "hidden",
3247
+ "& > *": {
3248
+ maxWidth: "100%",
3249
+ overflow: "hidden",
3250
+ textOverflow: "ellipsis"
3251
+ },
3252
+ ...sx
3253
+ },
3254
+ ...rest,
3255
+ children
3256
+ }
3257
+ );
3109
3258
  }
3110
3259
 
3111
3260
  // src/index.ts
@@ -3122,6 +3271,9 @@ var import_fabric19 = require("fabric");
3122
3271
  FabricCanvas,
3123
3272
  FabricImage,
3124
3273
  FabricObject,
3274
+ FixedSizeContent,
3275
+ ObjectOverlay,
3276
+ OverlayContent,
3125
3277
  Point,
3126
3278
  Polygon,
3127
3279
  Rect,
@@ -3167,7 +3319,6 @@ var import_fabric19 = require("fabric");
3167
3319
  useCanvasEvents,
3168
3320
  useCanvasTooltip,
3169
3321
  useEditCanvas,
3170
- useObjectOverlay,
3171
3322
  useViewCanvas,
3172
3323
  util
3173
3324
  });