canvu-react 0.4.40 → 0.4.42
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/native.cjs +107 -3
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +24 -1
- package/dist/native.d.ts +24 -1
- package/dist/native.js +107 -3
- package/dist/native.js.map +1 -1
- package/package.json +1 -1
package/dist/native.cjs
CHANGED
|
@@ -4678,6 +4678,84 @@ function resizeItemByHandle(item, start, handle, currentWorld) {
|
|
|
4678
4678
|
}
|
|
4679
4679
|
return { ...item, x: nb.x, y: nb.y, bounds: nb };
|
|
4680
4680
|
}
|
|
4681
|
+
|
|
4682
|
+
// src/native/native-remote-presence-hit-test.ts
|
|
4683
|
+
var REMOTE_CURSOR_SCREEN_PX2 = 22;
|
|
4684
|
+
var REMOTE_LABEL_SCREEN_PX2 = 12;
|
|
4685
|
+
var REMOTE_LABEL_OFFSET_X = 14;
|
|
4686
|
+
var REMOTE_LABEL_BASELINE_OFFSET_Y = 18;
|
|
4687
|
+
var REMOTE_LABEL_AVERAGE_CHAR_PX = 7;
|
|
4688
|
+
var REMOTE_LABEL_MAX_WIDTH_PX = 180;
|
|
4689
|
+
var REMOTE_LABEL_MIN_HIT_WIDTH_PX = 44;
|
|
4690
|
+
var REMOTE_LABEL_HIT_PADDING_X = 10;
|
|
4691
|
+
var REMOTE_LABEL_HIT_PADDING_Y = 10;
|
|
4692
|
+
var REMOTE_CURSOR_MIN_HIT_SIZE_PX = 36;
|
|
4693
|
+
function pointInScreenRect(point, rect) {
|
|
4694
|
+
return point.x >= rect.x && point.x <= rect.x + rect.width && point.y >= rect.y && point.y <= rect.y + rect.height;
|
|
4695
|
+
}
|
|
4696
|
+
function displayLabelForPeer(peer) {
|
|
4697
|
+
const displayName = peer.displayName?.trim();
|
|
4698
|
+
if (displayName) return displayName;
|
|
4699
|
+
return null;
|
|
4700
|
+
}
|
|
4701
|
+
function followIdForPeer(peer) {
|
|
4702
|
+
return peer.clientId ?? peer.peerId ?? peer.id;
|
|
4703
|
+
}
|
|
4704
|
+
function estimateLabelWidth(label) {
|
|
4705
|
+
return Math.max(
|
|
4706
|
+
REMOTE_LABEL_MIN_HIT_WIDTH_PX,
|
|
4707
|
+
Math.min(REMOTE_LABEL_MAX_WIDTH_PX, label.length * REMOTE_LABEL_AVERAGE_CHAR_PX)
|
|
4708
|
+
);
|
|
4709
|
+
}
|
|
4710
|
+
function buildHit(peer, camera, point, target) {
|
|
4711
|
+
const world = camera.screenToWorld(point.x, point.y);
|
|
4712
|
+
return {
|
|
4713
|
+
peer,
|
|
4714
|
+
followId: followIdForPeer(peer),
|
|
4715
|
+
target,
|
|
4716
|
+
screenX: point.x,
|
|
4717
|
+
screenY: point.y,
|
|
4718
|
+
worldX: world.worldX,
|
|
4719
|
+
worldY: world.worldY,
|
|
4720
|
+
...peer.clientId ? { clientId: peer.clientId } : {},
|
|
4721
|
+
...peer.peerId ? { peerId: peer.peerId } : {}
|
|
4722
|
+
};
|
|
4723
|
+
}
|
|
4724
|
+
function hitTestNativeRemotePresence(peers, camera, point) {
|
|
4725
|
+
for (let index = peers.length - 1; index >= 0; index -= 1) {
|
|
4726
|
+
const peer = peers[index];
|
|
4727
|
+
if (!peer || peer.isSelf || !peer.cursor) continue;
|
|
4728
|
+
const cursorScreen = camera.worldToScreen(peer.cursor.x, peer.cursor.y);
|
|
4729
|
+
const label = displayLabelForPeer(peer);
|
|
4730
|
+
if (label) {
|
|
4731
|
+
const labelX = cursorScreen.screenX + REMOTE_LABEL_OFFSET_X;
|
|
4732
|
+
const labelBaselineY = cursorScreen.screenY + REMOTE_LABEL_BASELINE_OFFSET_Y;
|
|
4733
|
+
const labelRect = {
|
|
4734
|
+
x: labelX - REMOTE_LABEL_HIT_PADDING_X,
|
|
4735
|
+
y: labelBaselineY - REMOTE_LABEL_SCREEN_PX2 - REMOTE_LABEL_HIT_PADDING_Y,
|
|
4736
|
+
width: estimateLabelWidth(label) + REMOTE_LABEL_HIT_PADDING_X * 2,
|
|
4737
|
+
height: REMOTE_LABEL_SCREEN_PX2 + REMOTE_LABEL_HIT_PADDING_Y * 2
|
|
4738
|
+
};
|
|
4739
|
+
if (pointInScreenRect(point, labelRect)) {
|
|
4740
|
+
return buildHit(peer, camera, point, "label");
|
|
4741
|
+
}
|
|
4742
|
+
}
|
|
4743
|
+
const cursorHitSize = Math.max(
|
|
4744
|
+
REMOTE_CURSOR_MIN_HIT_SIZE_PX,
|
|
4745
|
+
REMOTE_CURSOR_SCREEN_PX2
|
|
4746
|
+
);
|
|
4747
|
+
const cursorRect = {
|
|
4748
|
+
x: cursorScreen.screenX - (cursorHitSize - REMOTE_CURSOR_SCREEN_PX2) / 2,
|
|
4749
|
+
y: cursorScreen.screenY - (cursorHitSize - REMOTE_CURSOR_SCREEN_PX2) / 2,
|
|
4750
|
+
width: cursorHitSize,
|
|
4751
|
+
height: cursorHitSize
|
|
4752
|
+
};
|
|
4753
|
+
if (pointInScreenRect(point, cursorRect)) {
|
|
4754
|
+
return buildHit(peer, camera, point, "cursor");
|
|
4755
|
+
}
|
|
4756
|
+
}
|
|
4757
|
+
return null;
|
|
4758
|
+
}
|
|
4681
4759
|
var DEFAULT_NATIVE_LINK_TOOL_DIALOG_LABELS = {
|
|
4682
4760
|
title: "Add link",
|
|
4683
4761
|
description: "Paste the link you want to add to the board.",
|
|
@@ -4695,6 +4773,8 @@ var MARKER_TOOL_STYLE = {
|
|
|
4695
4773
|
};
|
|
4696
4774
|
var NATIVE_VIEWPORT_OVERLAY_Z_INDEX = 40;
|
|
4697
4775
|
var NATIVE_VIEWPORT_OVERLAY_ELEVATION = 40;
|
|
4776
|
+
var NATIVE_VIEWPORT_EXTERNAL_OVERLAY_Z_INDEX = 20;
|
|
4777
|
+
var NATIVE_VIEWPORT_EXTERNAL_OVERLAY_ELEVATION = 20;
|
|
4698
4778
|
function isPlacementTool(toolId) {
|
|
4699
4779
|
return toolId === "rect" || toolId === "ellipse" || toolId === "architectural-cloud" || toolId === "line" || toolId === "arrow";
|
|
4700
4780
|
}
|
|
@@ -4772,6 +4852,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4772
4852
|
onLinkToolRequest,
|
|
4773
4853
|
linkToolDialogLabels,
|
|
4774
4854
|
onWorldPointerDown,
|
|
4855
|
+
onRemotePresencePress,
|
|
4775
4856
|
onWorldPointerMove,
|
|
4776
4857
|
onWorldPointerLeave,
|
|
4777
4858
|
onPlacementPreviewChange,
|
|
@@ -4795,6 +4876,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4795
4876
|
onLinkToolRequestRef.current = onLinkToolRequest;
|
|
4796
4877
|
const onWorldPointerDownRef = react.useRef(onWorldPointerDown);
|
|
4797
4878
|
onWorldPointerDownRef.current = onWorldPointerDown;
|
|
4879
|
+
const onRemotePresencePressRef = react.useRef(onRemotePresencePress);
|
|
4880
|
+
onRemotePresencePressRef.current = onRemotePresencePress;
|
|
4798
4881
|
const onWorldPointerMoveRef = react.useRef(onWorldPointerMove);
|
|
4799
4882
|
onWorldPointerMoveRef.current = onWorldPointerMove;
|
|
4800
4883
|
const onWorldPointerLeaveRef = react.useRef(onWorldPointerLeave);
|
|
@@ -4815,6 +4898,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4815
4898
|
itemsRef.current = items;
|
|
4816
4899
|
const selectedIdsRef = react.useRef(selectedIds);
|
|
4817
4900
|
selectedIdsRef.current = selectedIds;
|
|
4901
|
+
const remotePresenceRef = react.useRef(remotePresence);
|
|
4902
|
+
remotePresenceRef.current = remotePresence;
|
|
4818
4903
|
const dragStateRef = react.useRef({ kind: "idle" });
|
|
4819
4904
|
const [placementPreview, setPlacementPreviewState] = react.useState(null);
|
|
4820
4905
|
const setRealtimePlacementPreview = react.useCallback(
|
|
@@ -4974,13 +5059,19 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4974
5059
|
const sx = point.x;
|
|
4975
5060
|
const sy = point.y;
|
|
4976
5061
|
updateToolCursorPoint(point);
|
|
5062
|
+
const cam = cameraRef.current;
|
|
5063
|
+
if (!cam) return;
|
|
5064
|
+
const remotePresenceHit = interactive && onRemotePresencePressRef.current ? hitTestNativeRemotePresence(remotePresenceRef.current, cam, point) : null;
|
|
5065
|
+
if (remotePresenceHit) {
|
|
5066
|
+
dragStateRef.current = { kind: "idle" };
|
|
5067
|
+
onRemotePresencePressRef.current?.(remotePresenceHit);
|
|
5068
|
+
return;
|
|
5069
|
+
}
|
|
4977
5070
|
if (!interactive) {
|
|
4978
5071
|
dragStateRef.current = { kind: "pan" };
|
|
4979
5072
|
return;
|
|
4980
5073
|
}
|
|
4981
5074
|
const tool = toolIdRef.current;
|
|
4982
|
-
const cam = cameraRef.current;
|
|
4983
|
-
if (!cam) return;
|
|
4984
5075
|
const { worldX, worldY } = screenToWorld(sx, sy);
|
|
4985
5076
|
onWorldPointerMoveRef.current?.({ x: worldX, y: worldY });
|
|
4986
5077
|
if (tool === "hand") {
|
|
@@ -5756,7 +5847,20 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
5756
5847
|
]
|
|
5757
5848
|
}
|
|
5758
5849
|
),
|
|
5759
|
-
overlay ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5850
|
+
overlay ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5851
|
+
reactNative.View,
|
|
5852
|
+
{
|
|
5853
|
+
pointerEvents: "box-none",
|
|
5854
|
+
style: [
|
|
5855
|
+
reactNative.StyleSheet.absoluteFill,
|
|
5856
|
+
{
|
|
5857
|
+
zIndex: NATIVE_VIEWPORT_EXTERNAL_OVERLAY_Z_INDEX,
|
|
5858
|
+
elevation: NATIVE_VIEWPORT_EXTERNAL_OVERLAY_ELEVATION
|
|
5859
|
+
}
|
|
5860
|
+
],
|
|
5861
|
+
children: overlay
|
|
5862
|
+
}
|
|
5863
|
+
) : null,
|
|
5760
5864
|
interactive && showStyleInspector && activeStyleToolId ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
5761
5865
|
reactNative.View,
|
|
5762
5866
|
{
|