@bwp-web/canvas 0.4.3 → 0.5.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.
package/dist/index.d.ts CHANGED
@@ -19,7 +19,7 @@ export type { RectangleOptions, RectangleAtPointOptions } from './shapes';
19
19
  export { createCircle, createCircleAtPoint, editCircle } from './shapes';
20
20
  export type { CircleOptions, CircleAtPointOptions } from './shapes';
21
21
  export { createPolygon, createPolygonAtPoint, createPolygonFromDrag, createPolygonFromVertices, editPolygon, } from './shapes';
22
- export type { PolygonOptions, PolygonStyleOptions } from './shapes';
22
+ export type { PolygonOptions } from './shapes';
23
23
  export { enableClickToCreate } from './interactions';
24
24
  export { enableDragToCreate } from './interactions';
25
25
  export type { DragToCreateOptions } from './interactions';
@@ -38,9 +38,9 @@ export type { RotationSnapOptions } from './alignment';
38
38
  export { snapCursorPoint } from './alignment';
39
39
  export type { CursorSnapResult, CursorSnapOptions, GuidelineStyle, } from './alignment';
40
40
  export { deleteObjects, enableKeyboardShortcuts } from './keyboard';
41
- export { enableScaledStrokes, serializeCanvas, loadCanvas, getBaseStrokeWidth, } from './serialization';
41
+ export { enableScaledStrokes, enableScaledBorderRadius, serializeCanvas, loadCanvas, getBaseStrokeWidth, } from './serialization';
42
42
  export type { SerializeOptions, LoadCanvasOptions } from './serialization';
43
- export { fitViewportToBackground, getBackgroundSrc, setBackgroundOpacity, getBackgroundOpacity, setBackgroundInverted, getBackgroundInverted, resizeImageUrl, setBackgroundImage, } from './background';
43
+ export { fitViewportToBackground, getBackgroundSrc, setBackgroundContrast, getBackgroundContrast, setBackgroundInverted, getBackgroundInverted, resizeImageUrl, setBackgroundImage, } from './background';
44
44
  export type { FitViewportOptions, ResizeResult, ResizeImageOptions, SetBackgroundImageOptions, } from './background';
45
45
  export { DEFAULT_CONTROL_STYLE, DEFAULT_SHAPE_STYLE, DEFAULT_CIRCLE_STYLE, DEFAULT_DRAG_SHAPE_STYLE, DEFAULT_GUIDELINE_SHAPE_STYLE, DEFAULT_ALIGNMENT_STYLE, } from './styles';
46
46
  export { Canvas as FabricCanvas, FabricObject, FabricImage, Rect, Polygon, Point, util, } from 'fabric';
@@ -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
@@ -94,7 +94,7 @@ import {
94
94
  var DEFAULT_MIN_ZOOM = 0.2;
95
95
  var DEFAULT_MAX_ZOOM = 10;
96
96
  var DEFAULT_ZOOM_FACTOR = 1.03;
97
- var DEFAULT_ZOOM_STEP = 0.2;
97
+ var DEFAULT_ZOOM_STEP = 1.2;
98
98
  var DEFAULT_VIEWPORT_PADDING = 0.05;
99
99
  var BASE_CANVAS_SIZE = 1e3;
100
100
  var DEFAULT_SNAP_MARGIN = 6;
@@ -276,15 +276,15 @@ function enablePanAndZoom(canvas, options) {
276
276
  setEnabled(value) {
277
277
  enabled = value;
278
278
  },
279
- zoomIn(step = DEFAULT_ZOOM_STEP) {
280
- const z = Math.min(canvas.getZoom() + step, bounds.maxZoom);
279
+ zoomIn(factor = DEFAULT_ZOOM_STEP) {
280
+ const z = Math.min(canvas.getZoom() * factor, bounds.maxZoom);
281
281
  canvas.zoomToPoint(
282
282
  new Point(canvas.getWidth() / 2, canvas.getHeight() / 2),
283
283
  z
284
284
  );
285
285
  },
286
- zoomOut(step = DEFAULT_ZOOM_STEP) {
287
- const z = Math.max(canvas.getZoom() - step, bounds.minZoom);
286
+ zoomOut(factor = DEFAULT_ZOOM_STEP) {
287
+ const z = Math.max(canvas.getZoom() / factor, bounds.minZoom);
288
288
  canvas.zoomToPoint(
289
289
  new Point(canvas.getWidth() / 2, canvas.getHeight() / 2),
290
290
  z
@@ -383,15 +383,37 @@ function fitViewportToBackground(canvas, options) {
383
383
  canvas.setViewportTransform([scale, 0, 0, scale, offsetX, offsetY]);
384
384
  canvas.requestRenderAll();
385
385
  }
386
- function setBackgroundOpacity(canvas, opacity) {
386
+ function setBackgroundContrast(canvas, value) {
387
387
  const bg = getBackgroundImage(canvas);
388
388
  if (!bg) return;
389
- bg.set("opacity", Math.min(1, Math.max(0, opacity)));
389
+ const contrast = Math.min(Math.max(value, 0), 2) - 1;
390
+ const currentFilters = bg.filters ?? [];
391
+ const contrastIdx = currentFilters.findIndex(
392
+ (f) => f instanceof filters.Contrast
393
+ );
394
+ if (contrast === 0) {
395
+ if (contrastIdx >= 0) {
396
+ bg.filters = currentFilters.filter(
397
+ (f) => !(f instanceof filters.Contrast)
398
+ );
399
+ bg.applyFilters();
400
+ }
401
+ } else if (contrastIdx >= 0) {
402
+ currentFilters[contrastIdx].contrast = contrast;
403
+ bg.applyFilters();
404
+ } else {
405
+ bg.filters = [...currentFilters, new filters.Contrast({ contrast })];
406
+ bg.applyFilters();
407
+ }
390
408
  canvas.requestRenderAll();
391
409
  }
392
- function getBackgroundOpacity(canvas) {
410
+ function getBackgroundContrast(canvas) {
393
411
  const bg = getBackgroundImage(canvas);
394
- return bg?.opacity ?? 1;
412
+ if (!bg) return 1;
413
+ const contrastFilter = bg.filters?.find(
414
+ (f) => f instanceof filters.Contrast
415
+ );
416
+ return 1 + (contrastFilter?.contrast ?? 0);
395
417
  }
396
418
  function setBackgroundInverted(canvas, inverted) {
397
419
  const bg = getBackgroundImage(canvas);
@@ -457,7 +479,7 @@ function resizeImageUrl(url, options) {
457
479
  });
458
480
  }
459
481
  async function setBackgroundImage(canvas, url, options) {
460
- const prevOpacity = options?.preserveOpacity ? getBackgroundOpacity(canvas) : void 0;
482
+ const prevContrast = options?.preserveContrast ? getBackgroundContrast(canvas) : void 0;
461
483
  let imageUrl = url;
462
484
  if (options !== void 0) {
463
485
  const result = await resizeImageUrl(url, options);
@@ -465,8 +487,8 @@ async function setBackgroundImage(canvas, url, options) {
465
487
  }
466
488
  const img = await FabricImage.fromURL(imageUrl, { crossOrigin: "anonymous" });
467
489
  canvas.backgroundImage = img;
468
- if (prevOpacity !== void 0 && prevOpacity !== 1) {
469
- img.set("opacity", prevOpacity);
490
+ if (prevContrast !== void 0 && prevContrast !== 1) {
491
+ setBackgroundContrast(canvas, prevContrast);
470
492
  }
471
493
  canvas.requestRenderAll();
472
494
  return img;
@@ -1388,6 +1410,11 @@ function enableDragToCreate(canvas, factory, options) {
1388
1410
  if (width < MIN_DRAG_SIZE && height < MIN_DRAG_SIZE) {
1389
1411
  canvas.requestRenderAll();
1390
1412
  previewRect = null;
1413
+ if (options?.clickFactory) {
1414
+ const obj2 = options.clickFactory(canvas, { x: startX, y: startY });
1415
+ restoreViewport(options?.viewport);
1416
+ options?.onCreated?.(obj2);
1417
+ }
1391
1418
  return;
1392
1419
  }
1393
1420
  const obj = factory(canvas, { startX, startY, width, height });
@@ -2033,6 +2060,8 @@ function enableVertexEdit(canvas, polygon, options, onExit) {
2033
2060
  // src/serialization.ts
2034
2061
  import { Rect as Rect5 } from "fabric";
2035
2062
  var strokeBaseMap = /* @__PURE__ */ new WeakMap();
2063
+ var borderRadiusBaseMap = /* @__PURE__ */ new WeakMap();
2064
+ var VIEW_BORDER_RADIUS = 4;
2036
2065
  function enableScaledStrokes(canvas) {
2037
2066
  function applyScaledStrokes() {
2038
2067
  const zoom = canvas.getZoom();
@@ -2057,6 +2086,28 @@ function enableScaledStrokes(canvas) {
2057
2086
  });
2058
2087
  };
2059
2088
  }
2089
+ function enableScaledBorderRadius(canvas) {
2090
+ function applyScaledBorderRadius() {
2091
+ canvas.forEachObject((obj) => {
2092
+ if (!(obj instanceof Rect5)) return;
2093
+ if (!borderRadiusBaseMap.has(obj)) return;
2094
+ const rx = VIEW_BORDER_RADIUS / (obj.scaleX ?? 1);
2095
+ const ry = VIEW_BORDER_RADIUS / (obj.scaleY ?? 1);
2096
+ obj.set({ rx, ry });
2097
+ });
2098
+ }
2099
+ canvas.on("before:render", applyScaledBorderRadius);
2100
+ return () => {
2101
+ canvas.off("before:render", applyScaledBorderRadius);
2102
+ canvas.forEachObject((obj) => {
2103
+ if (!(obj instanceof Rect5)) return;
2104
+ const base = borderRadiusBaseMap.get(obj);
2105
+ if (base !== void 0) {
2106
+ obj.set({ rx: base.rx, ry: base.ry });
2107
+ }
2108
+ });
2109
+ };
2110
+ }
2060
2111
  function getBaseStrokeWidth(obj) {
2061
2112
  return strokeBaseMap.get(obj) ?? obj.strokeWidth ?? 0;
2062
2113
  }
@@ -2082,14 +2133,28 @@ function serializeCanvas(canvas, options) {
2082
2133
  obj.strokeWidth = base;
2083
2134
  }
2084
2135
  });
2136
+ const appliedRadii = /* @__PURE__ */ new Map();
2137
+ canvas.forEachObject((obj) => {
2138
+ if (!(obj instanceof Rect5)) return;
2139
+ const base = borderRadiusBaseMap.get(obj);
2140
+ if (base !== void 0) {
2141
+ appliedRadii.set(obj, { rx: obj.rx ?? 0, ry: obj.ry ?? 0 });
2142
+ obj.set({ rx: base.rx, ry: base.ry });
2143
+ }
2144
+ });
2085
2145
  const json = canvas.toObject(properties);
2146
+ delete json.backgroundColor;
2086
2147
  scaledWidths.forEach((scaled, obj) => {
2087
2148
  obj.strokeWidth = scaled;
2088
2149
  });
2150
+ appliedRadii.forEach((radii, obj) => {
2151
+ obj.set({ rx: radii.rx, ry: radii.ry });
2152
+ });
2089
2153
  return json;
2090
2154
  }
2091
2155
  async function loadCanvas(canvas, json, options) {
2092
2156
  await canvas.loadFromJSON(json);
2157
+ canvas.backgroundColor = "";
2093
2158
  if (options?.filter) {
2094
2159
  const toRemove = [];
2095
2160
  canvas.forEachObject((obj) => {
@@ -2097,11 +2162,28 @@ async function loadCanvas(canvas, json, options) {
2097
2162
  });
2098
2163
  for (const obj of toRemove) canvas.remove(obj);
2099
2164
  }
2165
+ canvas.forEachObject((obj) => {
2166
+ if (obj.originX === "center" && obj.originY === "center") return;
2167
+ const center = obj.getCenterPoint();
2168
+ obj.set({
2169
+ originX: "center",
2170
+ originY: "center",
2171
+ left: center.x,
2172
+ top: center.y
2173
+ });
2174
+ obj.setCoords();
2175
+ });
2100
2176
  canvas.forEachObject((obj) => {
2101
2177
  obj.set(DEFAULT_CONTROL_STYLE);
2102
2178
  if (obj.shapeType === "circle" && obj instanceof Rect5) {
2103
2179
  restoreCircleConstraints(obj);
2104
2180
  }
2181
+ if (obj instanceof Rect5 && obj.shapeType !== "circle" && obj.data?.type !== "DEVICE") {
2182
+ borderRadiusBaseMap.set(obj, { rx: obj.rx ?? 0, ry: obj.ry ?? 0 });
2183
+ const rx = VIEW_BORDER_RADIUS / (obj.scaleX ?? 1);
2184
+ const ry = VIEW_BORDER_RADIUS / (obj.scaleY ?? 1);
2185
+ obj.set({ rx, ry });
2186
+ }
2105
2187
  });
2106
2188
  canvas.requestRenderAll();
2107
2189
  return canvas.getObjects();
@@ -2153,6 +2235,7 @@ function useEditCanvas(options) {
2153
2235
  if (options?.scaledStrokes !== false) {
2154
2236
  enableScaledStrokes(canvas);
2155
2237
  }
2238
+ enableScaledBorderRadius(canvas);
2156
2239
  if (options?.keyboardShortcuts !== false) {
2157
2240
  keyboardCleanupRef.current = enableKeyboardShortcuts(canvas);
2158
2241
  }
@@ -2259,7 +2342,7 @@ function useEditCanvas(options) {
2259
2342
  async (url, bgOpts) => {
2260
2343
  const canvas = canvasRef.current;
2261
2344
  if (!canvas) throw new Error("Canvas not ready");
2262
- const resizeOpts = options?.backgroundResize !== false ? typeof options?.backgroundResize === "object" ? { ...options.backgroundResize, ...bgOpts } : { ...bgOpts } : bgOpts?.preserveOpacity ? { preserveOpacity: true } : void 0;
2345
+ const resizeOpts = options?.backgroundResize !== false ? typeof options?.backgroundResize === "object" ? { ...options.backgroundResize, ...bgOpts } : { ...bgOpts } : bgOpts?.preserveContrast ? { preserveContrast: true } : void 0;
2263
2346
  const img = await setBackgroundImage(canvas, url, resizeOpts);
2264
2347
  if (options?.autoFitToBackground !== false) {
2265
2348
  fitViewportToBackground(canvas);
@@ -2317,7 +2400,7 @@ function useEditCanvas(options) {
2317
2400
  * exceeds the configured limits (opt out via `backgroundResize: false`),
2318
2401
  * and fits the viewport after setting if `autoFitToBackground` is enabled.
2319
2402
  *
2320
- * Pass `{ preserveOpacity: true }` to keep the current background opacity
2403
+ * Pass `{ preserveContrast: true }` to keep the current background contrast
2321
2404
  * when replacing the image.
2322
2405
  */
2323
2406
  setBackground,
@@ -2330,18 +2413,10 @@ function useEditCanvas(options) {
2330
2413
 
2331
2414
  // src/hooks/useViewCanvas.ts
2332
2415
  import { useCallback as useCallback2, useRef as useRef3, useState as useState2 } from "react";
2333
- import { Rect as Rect6 } from "fabric";
2334
- var VIEW_BORDER_RADIUS = 4;
2335
2416
  function lockCanvas(canvas) {
2336
2417
  canvas.selection = false;
2337
2418
  canvas.forEachObject((obj) => {
2338
2419
  obj.selectable = false;
2339
- obj.evented = false;
2340
- if (obj instanceof Rect6 && obj.shapeType !== "circle" && obj.data?.type !== "DEVICE") {
2341
- const rx = VIEW_BORDER_RADIUS / (obj.scaleX ?? 1);
2342
- const ry = VIEW_BORDER_RADIUS / (obj.scaleY ?? 1);
2343
- obj.set({ rx, ry });
2344
- }
2345
2420
  });
2346
2421
  }
2347
2422
  function useViewCanvas(options) {
@@ -2354,6 +2429,7 @@ function useViewCanvas(options) {
2354
2429
  if (options?.scaledStrokes !== false) {
2355
2430
  enableScaledStrokes(canvas);
2356
2431
  }
2432
+ enableScaledBorderRadius(canvas);
2357
2433
  if (options?.panAndZoom !== false) {
2358
2434
  const panAndZoomOpts = typeof options?.panAndZoom === "object" ? options.panAndZoom : {};
2359
2435
  viewportRef.current = enablePanAndZoom(canvas, {
@@ -2666,7 +2742,7 @@ import {
2666
2742
  Canvas as Canvas2,
2667
2743
  FabricObject as FabricObject5,
2668
2744
  FabricImage as FabricImage2,
2669
- Rect as Rect7,
2745
+ Rect as Rect6,
2670
2746
  Polygon as Polygon5,
2671
2747
  Point as Point9,
2672
2748
  util as util5
@@ -2684,7 +2760,7 @@ export {
2684
2760
  FabricObject5 as FabricObject,
2685
2761
  Point9 as Point,
2686
2762
  Polygon5 as Polygon,
2687
- Rect7 as Rect,
2763
+ Rect6 as Rect,
2688
2764
  createCircle,
2689
2765
  createCircleAtPoint,
2690
2766
  createPolygon,
@@ -2704,11 +2780,12 @@ export {
2704
2780
  enableObjectAlignment,
2705
2781
  enablePanAndZoom,
2706
2782
  enableRotationSnap,
2783
+ enableScaledBorderRadius,
2707
2784
  enableScaledStrokes,
2708
2785
  enableVertexEdit,
2709
2786
  fitViewportToBackground,
2787
+ getBackgroundContrast,
2710
2788
  getBackgroundInverted,
2711
- getBackgroundOpacity,
2712
2789
  getBackgroundSrc,
2713
2790
  getBaseStrokeWidth,
2714
2791
  getSnapPoints,
@@ -2717,9 +2794,9 @@ export {
2717
2794
  resetViewport,
2718
2795
  resizeImageUrl,
2719
2796
  serializeCanvas,
2797
+ setBackgroundContrast,
2720
2798
  setBackgroundImage,
2721
2799
  setBackgroundInverted,
2722
- setBackgroundOpacity,
2723
2800
  snapCursorPoint,
2724
2801
  useCanvasClick,
2725
2802
  useCanvasEvents,