canvu-react 0.3.25 → 0.3.27
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/chatbot.d.cts +1 -1
- package/dist/chatbot.d.ts +1 -1
- package/dist/react.cjs +81 -31
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +2 -2
- package/dist/react.d.ts +2 -2
- package/dist/react.js +81 -31
- package/dist/react.js.map +1 -1
- package/dist/realtime.cjs +211 -59
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.d.cts +2 -2
- package/dist/realtime.d.ts +2 -2
- package/dist/realtime.js +207 -59
- package/dist/realtime.js.map +1 -1
- package/dist/{types-7kfWcm0L.d.cts → types-BLXR7g_L.d.cts} +7 -0
- package/dist/{types-C4k_AMvi.d.ts → types-Cm7IsgL4.d.ts} +7 -0
- package/package.json +1 -1
package/dist/realtime.cjs
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var lucideReact = require('lucide-react');
|
|
4
|
+
var getStroke = require('perfect-freehand');
|
|
4
5
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
6
|
var react = require('react');
|
|
6
7
|
|
|
8
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
|
+
|
|
10
|
+
var getStroke__default = /*#__PURE__*/_interopDefault(getStroke);
|
|
11
|
+
|
|
7
12
|
// src/react/presence/map-placement-preview.ts
|
|
8
13
|
function remoteMarkupStrokeFromPlacementPreview(preview) {
|
|
9
14
|
if (!preview || preview.kind !== "stroke" || preview.points.length === 0) {
|
|
@@ -11,9 +16,13 @@ function remoteMarkupStrokeFromPlacementPreview(preview) {
|
|
|
11
16
|
}
|
|
12
17
|
const tool = preview.tool;
|
|
13
18
|
const mapped = tool === "laser" || tool === "marker" || tool === "draw" ? tool : "draw";
|
|
19
|
+
const style = preview.style;
|
|
14
20
|
return {
|
|
15
21
|
points: preview.points,
|
|
16
|
-
tool: mapped
|
|
22
|
+
tool: mapped,
|
|
23
|
+
...style?.strokeWidth != null ? { strokeWidth: style.strokeWidth } : {},
|
|
24
|
+
...style?.stroke ? { stroke: style.stroke } : {},
|
|
25
|
+
...style?.strokeOpacity != null ? { strokeOpacity: style.strokeOpacity } : {}
|
|
17
26
|
};
|
|
18
27
|
}
|
|
19
28
|
|
|
@@ -69,6 +78,126 @@ function smoothFreehandPointsToPathD(points) {
|
|
|
69
78
|
return d;
|
|
70
79
|
}
|
|
71
80
|
|
|
81
|
+
// src/scene/custom-shape.ts
|
|
82
|
+
function expandCustomShapeTemplate(template, width, height) {
|
|
83
|
+
return template.replace(/\{\{w\}\}/g, String(width)).replace(/\{\{h\}\}/g, String(height)).replace(/\{\{width\}\}/g, String(width)).replace(/\{\{height\}\}/g, String(height));
|
|
84
|
+
}
|
|
85
|
+
function resolveCustomInner(content, size) {
|
|
86
|
+
if ("render" in content) {
|
|
87
|
+
return content.render(size);
|
|
88
|
+
}
|
|
89
|
+
return expandCustomShapeTemplate(content.svg, size.width, size.height);
|
|
90
|
+
}
|
|
91
|
+
function buildCustomShapeChildrenSvg(inner, intrinsic, bounds) {
|
|
92
|
+
const b = normalizeRect(bounds);
|
|
93
|
+
const sx = b.width / intrinsic.width;
|
|
94
|
+
const sy = b.height / intrinsic.height;
|
|
95
|
+
return `<g transform="scale(${sx},${sy})">${inner}</g>`;
|
|
96
|
+
}
|
|
97
|
+
function createCustomShapeItem(id, bounds, content) {
|
|
98
|
+
const r = normalizeRect(bounds);
|
|
99
|
+
const intrinsic = { width: r.width, height: r.height };
|
|
100
|
+
const inner = resolveCustomInner(content, intrinsic);
|
|
101
|
+
return {
|
|
102
|
+
id,
|
|
103
|
+
x: r.x,
|
|
104
|
+
y: r.y,
|
|
105
|
+
bounds: { ...r },
|
|
106
|
+
toolKind: "custom",
|
|
107
|
+
customIntrinsicSize: intrinsic,
|
|
108
|
+
customInnerSvg: inner,
|
|
109
|
+
childrenSvg: buildCustomShapeChildrenSvg(inner, intrinsic, r)
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/scene/shape-builders.ts
|
|
114
|
+
function perfectFreehandOptions(toolKind, style, strokeComplete, pressureAware = false) {
|
|
115
|
+
const sw = style.strokeWidth;
|
|
116
|
+
const base2 = {
|
|
117
|
+
last: strokeComplete,
|
|
118
|
+
simulatePressure: true
|
|
119
|
+
};
|
|
120
|
+
if (toolKind === "draw" || toolKind === "pencil") {
|
|
121
|
+
if (pressureAware && toolKind === "draw") {
|
|
122
|
+
return {
|
|
123
|
+
...base2,
|
|
124
|
+
size: Math.max(2, sw * 1.05),
|
|
125
|
+
thinning: 0.42,
|
|
126
|
+
smoothing: 0.78,
|
|
127
|
+
streamline: 0.62,
|
|
128
|
+
simulatePressure: true
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
return {
|
|
132
|
+
...base2,
|
|
133
|
+
size: Math.max(2, sw * 1.18),
|
|
134
|
+
thinning: 0.12,
|
|
135
|
+
smoothing: 0.85,
|
|
136
|
+
streamline: 0.78,
|
|
137
|
+
simulatePressure: true
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
if (toolKind === "brush") {
|
|
141
|
+
return {
|
|
142
|
+
...base2,
|
|
143
|
+
size: Math.max(4, sw * 1.22),
|
|
144
|
+
thinning: 0.52,
|
|
145
|
+
smoothing: 0.64,
|
|
146
|
+
streamline: 0.68
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
...base2,
|
|
151
|
+
size: Math.max(6, sw * 1.08),
|
|
152
|
+
thinning: 0.08,
|
|
153
|
+
smoothing: 0.88,
|
|
154
|
+
streamline: 0.84,
|
|
155
|
+
simulatePressure: true
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
function computeFreehandSvgPayload(pathPointsLocal, style, toolKind, strokeComplete = true) {
|
|
159
|
+
if (pathPointsLocal.length === 0) return null;
|
|
160
|
+
if (pathPointsLocal.length === 1) {
|
|
161
|
+
const p = pathPointsLocal[0];
|
|
162
|
+
if (!p) return null;
|
|
163
|
+
return {
|
|
164
|
+
kind: "circle",
|
|
165
|
+
cx: p.x,
|
|
166
|
+
cy: p.y,
|
|
167
|
+
r: Math.max(0.5, style.strokeWidth / 2),
|
|
168
|
+
fill: style.stroke,
|
|
169
|
+
fillOpacity: style.strokeOpacity
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const hasPressure = pathPointsLocal.some(
|
|
173
|
+
(p) => p.pressure != null && Number.isFinite(p.pressure)
|
|
174
|
+
);
|
|
175
|
+
const input = hasPressure ? pathPointsLocal.map(
|
|
176
|
+
(p) => [p.x, p.y, Math.min(1, Math.max(0, p.pressure ?? 0.5))]
|
|
177
|
+
) : pathPointsLocal.map((p) => [p.x, p.y]);
|
|
178
|
+
const stroke = getStroke__default.default(
|
|
179
|
+
input,
|
|
180
|
+
perfectFreehandOptions(toolKind, style, strokeComplete, hasPressure)
|
|
181
|
+
);
|
|
182
|
+
if (stroke.length < 3) return null;
|
|
183
|
+
const first = stroke[0];
|
|
184
|
+
if (!first) return null;
|
|
185
|
+
let d = `M ${first[0]} ${first[1]} Q`;
|
|
186
|
+
for (let i = 0; i < stroke.length; i++) {
|
|
187
|
+
const a = stroke[i];
|
|
188
|
+
const b = stroke[(i + 1) % stroke.length];
|
|
189
|
+
if (!a || !b) continue;
|
|
190
|
+
d += ` ${a[0]} ${a[1]} ${(a[0] + b[0]) / 2} ${(a[1] + b[1]) / 2}`;
|
|
191
|
+
}
|
|
192
|
+
d += " Z";
|
|
193
|
+
return {
|
|
194
|
+
kind: "fillPath",
|
|
195
|
+
d,
|
|
196
|
+
fill: style.stroke,
|
|
197
|
+
fillOpacity: style.strokeOpacity
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
72
201
|
// src/react/presence/peer-color.ts
|
|
73
202
|
function defaultPresenceColorForId(id) {
|
|
74
203
|
let h = 2166136261;
|
|
@@ -93,6 +222,9 @@ function strokePaint(tool, fallback) {
|
|
|
93
222
|
return { stroke: fallback, strokeOpacity: 0.95, widthWorld: 3.5 };
|
|
94
223
|
}
|
|
95
224
|
}
|
|
225
|
+
function isFreehandTool(tool) {
|
|
226
|
+
return tool === "draw" || tool === "marker" || tool === "pencil" || tool === "brush";
|
|
227
|
+
}
|
|
96
228
|
function PresenceRemoteLayer({
|
|
97
229
|
camera,
|
|
98
230
|
cameraVersion: _cameraVersion,
|
|
@@ -128,35 +260,78 @@ function PresenceRemoteLayer({
|
|
|
128
260
|
const markup = peer.markupStroke;
|
|
129
261
|
let strokeNode = null;
|
|
130
262
|
if (markup && markup.points.length > 0) {
|
|
131
|
-
const
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
263
|
+
const fallbackPaint = strokePaint(markup.tool, color);
|
|
264
|
+
const paint = {
|
|
265
|
+
stroke: markup.stroke ?? fallbackPaint.stroke,
|
|
266
|
+
strokeOpacity: markup.strokeOpacity ?? fallbackPaint.strokeOpacity,
|
|
267
|
+
widthWorld: markup.strokeWidth ?? fallbackPaint.widthWorld
|
|
268
|
+
};
|
|
269
|
+
if (markup.tool === "laser") {
|
|
270
|
+
const d = markup.points.length >= 2 ? smoothFreehandPointsToPathD([...markup.points]) : null;
|
|
271
|
+
if (d) {
|
|
272
|
+
strokeNode = /* @__PURE__ */ jsxRuntime.jsx(
|
|
273
|
+
"path",
|
|
274
|
+
{
|
|
275
|
+
d,
|
|
276
|
+
fill: "none",
|
|
277
|
+
stroke: paint.stroke,
|
|
278
|
+
strokeOpacity: paint.strokeOpacity,
|
|
279
|
+
strokeWidth: Math.max(paint.widthWorld / z, overlayStrokePx),
|
|
280
|
+
strokeLinecap: "round",
|
|
281
|
+
strokeLinejoin: "round",
|
|
282
|
+
shapeRendering: "geometricPrecision",
|
|
283
|
+
vectorEffect: "non-scaling-stroke"
|
|
284
|
+
}
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
} else if (isFreehandTool(markup.tool)) {
|
|
288
|
+
const style = {
|
|
289
|
+
stroke: paint.stroke,
|
|
290
|
+
strokeWidth: paint.widthWorld,
|
|
291
|
+
...paint.strokeOpacity != null ? { strokeOpacity: paint.strokeOpacity } : {}
|
|
292
|
+
};
|
|
293
|
+
const payload = computeFreehandSvgPayload(
|
|
294
|
+
markup.points.map((p) => ({ x: p.x, y: p.y })),
|
|
295
|
+
style,
|
|
296
|
+
markup.tool,
|
|
297
|
+
false
|
|
147
298
|
);
|
|
148
|
-
|
|
149
|
-
const p0 = markup.points[0];
|
|
150
|
-
if (p0) {
|
|
299
|
+
if (payload?.kind === "circle") {
|
|
151
300
|
strokeNode = /* @__PURE__ */ jsxRuntime.jsx(
|
|
152
301
|
"circle",
|
|
153
302
|
{
|
|
154
|
-
cx:
|
|
155
|
-
cy:
|
|
156
|
-
r:
|
|
157
|
-
fill:
|
|
158
|
-
fillOpacity:
|
|
159
|
-
|
|
303
|
+
cx: payload.cx,
|
|
304
|
+
cy: payload.cy,
|
|
305
|
+
r: payload.r,
|
|
306
|
+
fill: payload.fill,
|
|
307
|
+
...payload.fillOpacity != null ? { fillOpacity: payload.fillOpacity } : {},
|
|
308
|
+
shapeRendering: "geometricPrecision"
|
|
309
|
+
}
|
|
310
|
+
);
|
|
311
|
+
} else if (payload?.kind === "fillPath") {
|
|
312
|
+
strokeNode = /* @__PURE__ */ jsxRuntime.jsx(
|
|
313
|
+
"path",
|
|
314
|
+
{
|
|
315
|
+
d: payload.d,
|
|
316
|
+
fill: payload.fill,
|
|
317
|
+
fillRule: "nonzero",
|
|
318
|
+
stroke: "none",
|
|
319
|
+
...payload.fillOpacity != null ? { fillOpacity: payload.fillOpacity } : {},
|
|
320
|
+
shapeRendering: "geometricPrecision"
|
|
321
|
+
}
|
|
322
|
+
);
|
|
323
|
+
} else if (payload?.kind === "strokePath") {
|
|
324
|
+
strokeNode = /* @__PURE__ */ jsxRuntime.jsx(
|
|
325
|
+
"path",
|
|
326
|
+
{
|
|
327
|
+
d: payload.d,
|
|
328
|
+
fill: "none",
|
|
329
|
+
stroke: payload.stroke,
|
|
330
|
+
strokeWidth: payload.strokeWidth,
|
|
331
|
+
...payload.strokeOpacity != null ? { strokeOpacity: payload.strokeOpacity } : {},
|
|
332
|
+
strokeLinecap: "round",
|
|
333
|
+
strokeLinejoin: "round",
|
|
334
|
+
shapeRendering: "geometricPrecision"
|
|
160
335
|
}
|
|
161
336
|
);
|
|
162
337
|
}
|
|
@@ -257,7 +432,16 @@ function parseMarkupStroke(value) {
|
|
|
257
432
|
if (x == null || y == null) return null;
|
|
258
433
|
return { x, y };
|
|
259
434
|
}).filter((point) => point != null);
|
|
260
|
-
|
|
435
|
+
const strokeWidth = getNumber(value.strokeWidth);
|
|
436
|
+
const stroke = getString(value.stroke);
|
|
437
|
+
const strokeOpacity = getNumber(value.strokeOpacity);
|
|
438
|
+
return {
|
|
439
|
+
points,
|
|
440
|
+
tool,
|
|
441
|
+
...strokeWidth != null ? { strokeWidth } : {},
|
|
442
|
+
...stroke ? { stroke } : {},
|
|
443
|
+
...strokeOpacity != null ? { strokeOpacity } : {}
|
|
444
|
+
};
|
|
261
445
|
}
|
|
262
446
|
function parsePresencePayload(value) {
|
|
263
447
|
if (!isRecord(value)) return void 0;
|
|
@@ -779,38 +963,6 @@ var DEFAULT_VECTOR_TOOLS = [
|
|
|
779
963
|
shortcutHint: "I"
|
|
780
964
|
}
|
|
781
965
|
];
|
|
782
|
-
|
|
783
|
-
// src/scene/custom-shape.ts
|
|
784
|
-
function expandCustomShapeTemplate(template, width, height) {
|
|
785
|
-
return template.replace(/\{\{w\}\}/g, String(width)).replace(/\{\{h\}\}/g, String(height)).replace(/\{\{width\}\}/g, String(width)).replace(/\{\{height\}\}/g, String(height));
|
|
786
|
-
}
|
|
787
|
-
function resolveCustomInner(content, size) {
|
|
788
|
-
if ("render" in content) {
|
|
789
|
-
return content.render(size);
|
|
790
|
-
}
|
|
791
|
-
return expandCustomShapeTemplate(content.svg, size.width, size.height);
|
|
792
|
-
}
|
|
793
|
-
function buildCustomShapeChildrenSvg(inner, intrinsic, bounds) {
|
|
794
|
-
const b = normalizeRect(bounds);
|
|
795
|
-
const sx = b.width / intrinsic.width;
|
|
796
|
-
const sy = b.height / intrinsic.height;
|
|
797
|
-
return `<g transform="scale(${sx},${sy})">${inner}</g>`;
|
|
798
|
-
}
|
|
799
|
-
function createCustomShapeItem(id, bounds, content) {
|
|
800
|
-
const r = normalizeRect(bounds);
|
|
801
|
-
const intrinsic = { width: r.width, height: r.height };
|
|
802
|
-
const inner = resolveCustomInner(content, intrinsic);
|
|
803
|
-
return {
|
|
804
|
-
id,
|
|
805
|
-
x: r.x,
|
|
806
|
-
y: r.y,
|
|
807
|
-
bounds: { ...r },
|
|
808
|
-
toolKind: "custom",
|
|
809
|
-
customIntrinsicSize: intrinsic,
|
|
810
|
-
customInnerSvg: inner,
|
|
811
|
-
childrenSvg: buildCustomShapeChildrenSvg(inner, intrinsic, r)
|
|
812
|
-
};
|
|
813
|
-
}
|
|
814
966
|
var iconProps = { size: 20, strokeWidth: 2 };
|
|
815
967
|
var COMMENT_PLUGIN_DATA_KEY = "realtimeComment";
|
|
816
968
|
var REALTIME_COMMENT_TOOL = {
|