@canvas-harness/react 0.1.2 → 0.1.4

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.cjs CHANGED
@@ -815,12 +815,27 @@ var usePanZoom = (ref, store, tool) => {
815
815
  scheduled = false;
816
816
  rafId = 0;
817
817
  if (pendingZoomFactor !== 1 && pendingZoomAnchor) {
818
+ const MAX_PER_FRAME = 2;
819
+ const MIN_PER_FRAME = 0.5;
820
+ let appliedFactor = pendingZoomFactor;
821
+ let drained = true;
822
+ if (appliedFactor > MAX_PER_FRAME) {
823
+ appliedFactor = MAX_PER_FRAME;
824
+ pendingZoomFactor = pendingZoomFactor / MAX_PER_FRAME;
825
+ drained = false;
826
+ } else if (appliedFactor < MIN_PER_FRAME) {
827
+ appliedFactor = MIN_PER_FRAME;
828
+ pendingZoomFactor = pendingZoomFactor / MIN_PER_FRAME;
829
+ drained = false;
830
+ } else {
831
+ pendingZoomFactor = 1;
832
+ }
818
833
  const camera = store.getCamera();
819
834
  store.setCamera(
820
- core.zoomAtScreenPoint(camera, core.clampZoom(camera.z * pendingZoomFactor), pendingZoomAnchor)
835
+ core.zoomAtScreenPoint(camera, core.clampZoom(camera.z * appliedFactor), pendingZoomAnchor)
821
836
  );
822
- pendingZoomFactor = 1;
823
- pendingZoomAnchor = null;
837
+ if (drained) pendingZoomAnchor = null;
838
+ else schedule();
824
839
  }
825
840
  if (pendingDx !== 0 || pendingDy !== 0) {
826
841
  const camera = store.getCamera();
@@ -857,7 +872,7 @@ var usePanZoom = (ref, store, tool) => {
857
872
  if (isEditing()) return;
858
873
  e.preventDefault();
859
874
  if (e.ctrlKey || e.metaKey) {
860
- const factor = Math.exp(-e.deltaY * 0.01);
875
+ const factor = Math.abs(e.deltaY) >= 100 ? e.deltaY > 0 ? 1 / 1.1 : 1.1 : Math.exp(-e.deltaY * 0.01);
861
876
  pendingZoomFactor *= factor;
862
877
  pendingZoomAnchor = screenFromClient(e.clientX, e.clientY);
863
878
  pulseMotion("zooming");
@@ -1032,6 +1047,7 @@ function CanvasSurface({
1032
1047
  arrowDefaults,
1033
1048
  background,
1034
1049
  selectionColor,
1050
+ maxDpr,
1035
1051
  renderCustomNodeView,
1036
1052
  children
1037
1053
  }) {
@@ -1049,8 +1065,15 @@ function CanvasSurface({
1049
1065
  const interactionMode = useInteractionMode();
1050
1066
  useArrowTool(wrapRef, store, tool === "arrow", arrowDefaults);
1051
1067
  const { mountedIds, setMountedIds } = useOverlayHost();
1052
- const [camera, setCamera] = react.useState(() => store.getCamera());
1053
- react.useEffect(() => store.subscribe("camera", (c) => setCamera({ ...c })), [store]);
1068
+ react.useEffect(() => {
1069
+ const el = overlayRef.current;
1070
+ if (!el) return;
1071
+ const apply = (c) => {
1072
+ el.style.transform = `translate(${-c.x * c.z}px, ${-c.y * c.z}px) scale(${c.z})`;
1073
+ };
1074
+ apply(store.getCamera());
1075
+ return store.subscribe("camera", apply);
1076
+ }, [store]);
1054
1077
  react.useEffect(() => {
1055
1078
  if (!staticRef.current || !interactiveRef.current || w === 0 || h === 0) return;
1056
1079
  if (rendererRef.current) {
@@ -1066,6 +1089,7 @@ function CanvasSurface({
1066
1089
  height: h,
1067
1090
  background,
1068
1091
  selectionColor,
1092
+ maxDpr,
1069
1093
  onOverlayChange: (ids) => setMountedIds(ids)
1070
1094
  });
1071
1095
  r.start();
@@ -1075,7 +1099,7 @@ function CanvasSurface({
1075
1099
  r.dispose();
1076
1100
  rendererRef.current = null;
1077
1101
  };
1078
- }, [store, theme, w, h, onRenderer, setMountedIds]);
1102
+ }, [store, theme, w, h, maxDpr, onRenderer, setMountedIds]);
1079
1103
  react.useEffect(() => {
1080
1104
  rendererRef.current?.setBackground(background);
1081
1105
  }, [background]);
@@ -1097,9 +1121,9 @@ function CanvasSurface({
1097
1121
  if (toolRef.current === "select") {
1098
1122
  const rect = el.getBoundingClientRect();
1099
1123
  const screen = { x: e.clientX - rect.left, y: e.clientY - rect.top };
1100
- const camera2 = store.getCamera();
1101
- const world = core.screenToWorld(screen, camera2);
1102
- const hit = core.hitTestAny(store, world, camera2.z);
1124
+ const camera = store.getCamera();
1125
+ const world = core.screenToWorld(screen, camera);
1126
+ const hit = core.hitTestAny(store, world, camera.z);
1103
1127
  if (hit && hit.kind === "body" && "nodeId" in hit) {
1104
1128
  store.beginEdit(hit.nodeId);
1105
1129
  } else if (hit && hit.kind === "body" && "edgeId" in hit) {
@@ -1137,9 +1161,9 @@ function CanvasSurface({
1137
1161
  if (e.button !== 0) return;
1138
1162
  if (!isShapeTool(toolRef.current)) return;
1139
1163
  if (store.getInteractionState().mode === "editing") return;
1140
- const camera2 = store.getCamera();
1141
- const world = core.screenToWorld(screenFromEvent(e), camera2);
1142
- if (core.hitTestAny(store, world, camera2.z)) return;
1164
+ const camera = store.getCamera();
1165
+ const world = core.screenToWorld(screenFromEvent(e), camera);
1166
+ if (core.hitTestAny(store, world, camera.z)) return;
1143
1167
  startWorld = world;
1144
1168
  startScreen = screenFromEvent(e);
1145
1169
  activePointerId = e.pointerId;
@@ -1246,7 +1270,8 @@ function CanvasSurface({
1246
1270
  window.addEventListener("keydown", onKey);
1247
1271
  return () => window.removeEventListener("keydown", onKey);
1248
1272
  }, [store]);
1249
- const overlayTransform = `translate(${-camera.x * camera.z}px, ${-camera.y * camera.z}px) scale(${camera.z})`;
1273
+ const initialCamera = store.getCamera();
1274
+ const overlayTransform = `translate(${-initialCamera.x * initialCamera.z}px, ${-initialCamera.y * initialCamera.z}px) scale(${initialCamera.z})`;
1250
1275
  return /* @__PURE__ */ jsxRuntime.jsxs(
1251
1276
  "div",
1252
1277
  {