canvu-react 0.4.41 → 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 +91 -2
- 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 +91 -2
- 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.",
|
|
@@ -4774,6 +4852,7 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4774
4852
|
onLinkToolRequest,
|
|
4775
4853
|
linkToolDialogLabels,
|
|
4776
4854
|
onWorldPointerDown,
|
|
4855
|
+
onRemotePresencePress,
|
|
4777
4856
|
onWorldPointerMove,
|
|
4778
4857
|
onWorldPointerLeave,
|
|
4779
4858
|
onPlacementPreviewChange,
|
|
@@ -4797,6 +4876,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4797
4876
|
onLinkToolRequestRef.current = onLinkToolRequest;
|
|
4798
4877
|
const onWorldPointerDownRef = react.useRef(onWorldPointerDown);
|
|
4799
4878
|
onWorldPointerDownRef.current = onWorldPointerDown;
|
|
4879
|
+
const onRemotePresencePressRef = react.useRef(onRemotePresencePress);
|
|
4880
|
+
onRemotePresencePressRef.current = onRemotePresencePress;
|
|
4800
4881
|
const onWorldPointerMoveRef = react.useRef(onWorldPointerMove);
|
|
4801
4882
|
onWorldPointerMoveRef.current = onWorldPointerMove;
|
|
4802
4883
|
const onWorldPointerLeaveRef = react.useRef(onWorldPointerLeave);
|
|
@@ -4817,6 +4898,8 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4817
4898
|
itemsRef.current = items;
|
|
4818
4899
|
const selectedIdsRef = react.useRef(selectedIds);
|
|
4819
4900
|
selectedIdsRef.current = selectedIds;
|
|
4901
|
+
const remotePresenceRef = react.useRef(remotePresence);
|
|
4902
|
+
remotePresenceRef.current = remotePresence;
|
|
4820
4903
|
const dragStateRef = react.useRef({ kind: "idle" });
|
|
4821
4904
|
const [placementPreview, setPlacementPreviewState] = react.useState(null);
|
|
4822
4905
|
const setRealtimePlacementPreview = react.useCallback(
|
|
@@ -4976,13 +5059,19 @@ var NativeVectorViewport = react.forwardRef(function NativeVectorViewport2({
|
|
|
4976
5059
|
const sx = point.x;
|
|
4977
5060
|
const sy = point.y;
|
|
4978
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
|
+
}
|
|
4979
5070
|
if (!interactive) {
|
|
4980
5071
|
dragStateRef.current = { kind: "pan" };
|
|
4981
5072
|
return;
|
|
4982
5073
|
}
|
|
4983
5074
|
const tool = toolIdRef.current;
|
|
4984
|
-
const cam = cameraRef.current;
|
|
4985
|
-
if (!cam) return;
|
|
4986
5075
|
const { worldX, worldY } = screenToWorld(sx, sy);
|
|
4987
5076
|
onWorldPointerMoveRef.current?.({ x: worldX, y: worldY });
|
|
4988
5077
|
if (tool === "hand") {
|