canvu-react 0.4.6 → 0.4.8
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 +471 -100
- package/dist/native.cjs.map +1 -1
- package/dist/native.d.cts +32 -3
- package/dist/native.d.ts +32 -3
- package/dist/native.js +473 -104
- package/dist/native.js.map +1 -1
- package/dist/realtime.cjs +32 -2
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.js +32 -2
- package/dist/realtime.js.map +1 -1
- package/package.json +1 -1
package/dist/native.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import getStroke from 'perfect-freehand';
|
|
2
|
-
import { Group, RoundedRect, Circle, Line, vec, Path, matchFont, Text, Canvas, Rect, Oval } from '@shopify/react-native-skia';
|
|
3
|
-
import { memo, forwardRef, useState, useRef, useCallback, useMemo, useImperativeHandle } from 'react';
|
|
2
|
+
import { Group, RoundedRect, Circle, Line, vec, Path, matchFont, Text, Canvas, Rect, Oval, useImage, Image } from '@shopify/react-native-skia';
|
|
3
|
+
import { memo, forwardRef, useState, useRef, useEffect, useCallback, useMemo, useImperativeHandle } from 'react';
|
|
4
4
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
5
|
-
import { StyleSheet, PanResponder, View, ScrollView, Text as Text$1
|
|
5
|
+
import { StyleSheet, PanResponder, View, ScrollView, Pressable, Text as Text$1 } from 'react-native';
|
|
6
6
|
|
|
7
7
|
// src/scene/shape-builders.ts
|
|
8
8
|
|
|
@@ -893,6 +893,25 @@ function buildRasterImageChildrenSvg(dataUrl, intrinsic, bounds) {
|
|
|
893
893
|
const ty = (r.height - ih * s) / 2;
|
|
894
894
|
return `<g transform="translate(${tx}, ${ty}) scale(${s})"><image href="${href}" x="0" y="0" width="${iw}" height="${ih}" /></g>`;
|
|
895
895
|
}
|
|
896
|
+
function createImageItem(id, bounds, imageRasterHref, imageIntrinsicSize) {
|
|
897
|
+
const r = normalizeRect(bounds);
|
|
898
|
+
const iw = Math.max(1e-6, imageIntrinsicSize.width);
|
|
899
|
+
const ih = Math.max(1e-6, imageIntrinsicSize.height);
|
|
900
|
+
return {
|
|
901
|
+
id,
|
|
902
|
+
x: r.x,
|
|
903
|
+
y: r.y,
|
|
904
|
+
bounds: { ...r },
|
|
905
|
+
toolKind: "image",
|
|
906
|
+
imageRasterHref,
|
|
907
|
+
imageIntrinsicSize: { width: iw, height: ih },
|
|
908
|
+
childrenSvg: buildRasterImageChildrenSvg(
|
|
909
|
+
imageRasterHref,
|
|
910
|
+
{ width: iw, height: ih },
|
|
911
|
+
r
|
|
912
|
+
)
|
|
913
|
+
};
|
|
914
|
+
}
|
|
896
915
|
|
|
897
916
|
// src/math/item-transform.ts
|
|
898
917
|
function getItemRotationRad(item) {
|
|
@@ -1281,6 +1300,9 @@ function SvgNodeItem({ node }) {
|
|
|
1281
1300
|
}
|
|
1282
1301
|
);
|
|
1283
1302
|
}
|
|
1303
|
+
case "image": {
|
|
1304
|
+
return /* @__PURE__ */ jsx(SvgImageNodeItem, { node });
|
|
1305
|
+
}
|
|
1284
1306
|
case "g": {
|
|
1285
1307
|
const transform = node.transform ? parseSvgTransform(node.transform) : void 0;
|
|
1286
1308
|
return /* @__PURE__ */ jsx(Group, { transform, children: node.children.map((child, i) => /* @__PURE__ */ jsx(SvgNodeItem, { node: child }, i)) });
|
|
@@ -1292,6 +1314,23 @@ function SvgNodeItem({ node }) {
|
|
|
1292
1314
|
return null;
|
|
1293
1315
|
}
|
|
1294
1316
|
}
|
|
1317
|
+
function SvgImageNodeItem({
|
|
1318
|
+
node
|
|
1319
|
+
}) {
|
|
1320
|
+
const image = useImage(node.href);
|
|
1321
|
+
if (!image) return null;
|
|
1322
|
+
return /* @__PURE__ */ jsx(
|
|
1323
|
+
Image,
|
|
1324
|
+
{
|
|
1325
|
+
image,
|
|
1326
|
+
x: toNum(node.x),
|
|
1327
|
+
y: toNum(node.y),
|
|
1328
|
+
width: toNum(node.width),
|
|
1329
|
+
height: toNum(node.height),
|
|
1330
|
+
fit: "contain"
|
|
1331
|
+
}
|
|
1332
|
+
);
|
|
1333
|
+
}
|
|
1295
1334
|
function polygonPointsToPath(points) {
|
|
1296
1335
|
const nums = points.split(/[\s,]+/).filter(Boolean).map(Number);
|
|
1297
1336
|
if (nums.length < 4) return "";
|
|
@@ -2194,146 +2233,353 @@ function NativeSceneRenderer({
|
|
|
2194
2233
|
if (width <= 0 || height <= 0) return null;
|
|
2195
2234
|
return /* @__PURE__ */ jsx(Canvas, { style: { width, height }, children: /* @__PURE__ */ jsx(Group, { transform: cameraTransform, children: visible.map((item) => /* @__PURE__ */ jsx(MemoShape, { item }, item.id)) }) });
|
|
2196
2235
|
}
|
|
2236
|
+
var DEFAULT_NATIVE_OVERFLOW_TOOL_IDS = [
|
|
2237
|
+
"rect",
|
|
2238
|
+
"ellipse",
|
|
2239
|
+
"architectural-cloud",
|
|
2240
|
+
"line",
|
|
2241
|
+
"marker",
|
|
2242
|
+
"laser",
|
|
2243
|
+
"image"
|
|
2244
|
+
];
|
|
2197
2245
|
var DEFAULT_NATIVE_VECTOR_TOOLS = [
|
|
2198
|
-
{ id: "hand", label: "Hand", shortLabel: "H" },
|
|
2199
|
-
{ id: "select", label: "Select", shortLabel: "V" },
|
|
2200
|
-
{ id: "
|
|
2201
|
-
{ id: "
|
|
2202
|
-
{
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
{ id: "
|
|
2246
|
+
{ id: "hand", label: "Hand", shortcutHint: "H", shortLabel: "H" },
|
|
2247
|
+
{ id: "select", label: "Select", shortcutHint: "V", shortLabel: "V" },
|
|
2248
|
+
{ id: "rect", label: "Rectangle", shortcutHint: "R", shortLabel: "R" },
|
|
2249
|
+
{ id: "ellipse", label: "Ellipse", shortcutHint: "O", shortLabel: "O" },
|
|
2250
|
+
{
|
|
2251
|
+
id: "architectural-cloud",
|
|
2252
|
+
label: "Nuvem arquitetural",
|
|
2253
|
+
tooltipLabel: "Architectural cloud",
|
|
2254
|
+
shortcutHint: "C",
|
|
2255
|
+
shortLabel: "C"
|
|
2256
|
+
},
|
|
2257
|
+
{ id: "line", label: "Line", shortcutHint: "L", shortLabel: "L" },
|
|
2258
|
+
{ id: "arrow", label: "Arrow", shortcutHint: "A", shortLabel: "A" },
|
|
2259
|
+
{
|
|
2260
|
+
id: "draw",
|
|
2261
|
+
label: "Desenhar",
|
|
2262
|
+
tooltipLabel: "Draw",
|
|
2263
|
+
shortcutHint: "D",
|
|
2264
|
+
shortLabel: "D"
|
|
2265
|
+
},
|
|
2266
|
+
{
|
|
2267
|
+
id: "marker",
|
|
2268
|
+
label: "Realce",
|
|
2269
|
+
tooltipLabel: "Highlighter",
|
|
2270
|
+
shortcutHint: "M",
|
|
2271
|
+
shortLabel: "M"
|
|
2272
|
+
},
|
|
2273
|
+
{ id: "laser", label: "Laser", shortcutHint: "K", shortLabel: "K" },
|
|
2274
|
+
{
|
|
2275
|
+
id: "eraser",
|
|
2276
|
+
label: "Borracha",
|
|
2277
|
+
tooltipLabel: "Eraser",
|
|
2278
|
+
shortcutHint: "E",
|
|
2279
|
+
shortLabel: "E"
|
|
2280
|
+
},
|
|
2281
|
+
{ id: "text", label: "Text", shortcutHint: "T", shortLabel: "T" },
|
|
2282
|
+
{ id: "image", label: "File", shortcutHint: "I", shortLabel: "I" }
|
|
2210
2283
|
];
|
|
2284
|
+
function splitToolbarTools(tools, overflowToolIds) {
|
|
2285
|
+
const overflowIds = new Set(overflowToolIds);
|
|
2286
|
+
if (overflowIds.size === 0) return { primary: tools, overflow: [] };
|
|
2287
|
+
return {
|
|
2288
|
+
primary: tools.filter((tool) => !overflowIds.has(tool.id)),
|
|
2289
|
+
overflow: tools.filter((tool) => overflowIds.has(tool.id))
|
|
2290
|
+
};
|
|
2291
|
+
}
|
|
2292
|
+
function getPromotedOverflowTool(input) {
|
|
2293
|
+
const selectedOverflowTool = input.overflowTools.find((tool) => tool.id === input.selectedId) ?? null;
|
|
2294
|
+
const fallbackTool = input.overflowTools.find((tool) => tool.id === input.initialPromotedId) ?? input.overflowTools[0] ?? null;
|
|
2295
|
+
const promotedTool = selectedOverflowTool ?? fallbackTool;
|
|
2296
|
+
if (!promotedTool) {
|
|
2297
|
+
return { promotedTool: null, remainingOverflowTools: input.overflowTools };
|
|
2298
|
+
}
|
|
2299
|
+
return {
|
|
2300
|
+
promotedTool,
|
|
2301
|
+
remainingOverflowTools: input.overflowTools.filter(
|
|
2302
|
+
(tool) => tool.id !== promotedTool.id
|
|
2303
|
+
)
|
|
2304
|
+
};
|
|
2305
|
+
}
|
|
2306
|
+
function tooltipTextForTool(tool) {
|
|
2307
|
+
const name = tool.tooltipLabel ?? tool.label;
|
|
2308
|
+
return tool.shortcutHint ? `${name} - ${tool.shortcutHint}` : name;
|
|
2309
|
+
}
|
|
2211
2310
|
function NativeVectorToolbar({
|
|
2212
2311
|
value,
|
|
2213
2312
|
onChange,
|
|
2214
2313
|
tools = DEFAULT_NATIVE_VECTOR_TOOLS,
|
|
2314
|
+
overflowToolIds = DEFAULT_NATIVE_OVERFLOW_TOOL_IDS,
|
|
2315
|
+
overflowMenuAccessibilityLabel = "More tools",
|
|
2215
2316
|
disabled = false,
|
|
2216
2317
|
disabledToolIds = [],
|
|
2318
|
+
showToolLockToggle = true,
|
|
2319
|
+
toolLocked = false,
|
|
2320
|
+
onToolLockedChange,
|
|
2321
|
+
density = "compact",
|
|
2217
2322
|
accessibilityLabel = "Canvas tools",
|
|
2218
2323
|
style,
|
|
2219
2324
|
contentContainerStyle,
|
|
2325
|
+
overflowPanelStyle,
|
|
2220
2326
|
toolButtonStyle,
|
|
2221
2327
|
activeToolButtonStyle,
|
|
2222
2328
|
toolLabelStyle,
|
|
2223
2329
|
activeToolLabelStyle,
|
|
2224
2330
|
renderToolIcon,
|
|
2331
|
+
renderToolLockIcon,
|
|
2332
|
+
renderOverflowIcon,
|
|
2333
|
+
renderOverflowChevronIcon,
|
|
2225
2334
|
renderToolButton
|
|
2226
2335
|
}) {
|
|
2336
|
+
const [overflowOpen, setOverflowOpen] = useState(false);
|
|
2227
2337
|
const disabledIds = useMemo(() => new Set(disabledToolIds), [disabledToolIds]);
|
|
2228
|
-
|
|
2229
|
-
|
|
2338
|
+
const { primary: primaryTools, overflow: overflowTools } = useMemo(
|
|
2339
|
+
() => splitToolbarTools(tools, overflowToolIds),
|
|
2340
|
+
[tools, overflowToolIds]
|
|
2341
|
+
);
|
|
2342
|
+
const { promotedTool, remainingOverflowTools } = useMemo(
|
|
2343
|
+
() => getPromotedOverflowTool({
|
|
2344
|
+
overflowTools,
|
|
2345
|
+
selectedId: value,
|
|
2346
|
+
initialPromotedId: overflowToolIds[0] ?? null
|
|
2347
|
+
}),
|
|
2348
|
+
[overflowTools, overflowToolIds, value]
|
|
2349
|
+
);
|
|
2350
|
+
const activeOverflowTool = overflowTools.find((tool) => tool.id === value) ?? null;
|
|
2351
|
+
const toolbarTools = promotedTool !== null ? [...primaryTools, promotedTool] : primaryTools;
|
|
2352
|
+
const showOverflowMenu = remainingOverflowTools.length > 0;
|
|
2353
|
+
const toolLockDisabled = disabled || !onToolLockedChange;
|
|
2354
|
+
const toggleToolLock = () => onToolLockedChange?.(!toolLocked);
|
|
2355
|
+
const toggleOverflow = () => setOverflowOpen((open) => !open);
|
|
2356
|
+
const overflowRenderInput = {
|
|
2357
|
+
open: overflowOpen,
|
|
2358
|
+
activeTool: activeOverflowTool,
|
|
2359
|
+
disabled,
|
|
2360
|
+
foregroundColor: "#18181b",
|
|
2361
|
+
onToggle: toggleOverflow
|
|
2362
|
+
};
|
|
2363
|
+
return /* @__PURE__ */ jsxs(
|
|
2364
|
+
View,
|
|
2230
2365
|
{
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
children:
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
const foregroundColor = selected ? "#fafaf9" : "#18181b";
|
|
2238
|
-
const onSelect = () => {
|
|
2239
|
-
if (!toolDisabled) {
|
|
2240
|
-
onChange(tool.id);
|
|
2241
|
-
}
|
|
2242
|
-
};
|
|
2243
|
-
const input = {
|
|
2244
|
-
tool,
|
|
2245
|
-
selected,
|
|
2246
|
-
disabled: toolDisabled,
|
|
2247
|
-
foregroundColor,
|
|
2248
|
-
onSelect
|
|
2249
|
-
};
|
|
2250
|
-
if (renderToolButton) {
|
|
2251
|
-
return /* @__PURE__ */ jsx(View, { children: renderToolButton(input) }, tool.id);
|
|
2252
|
-
}
|
|
2253
|
-
const icon = renderToolIcon?.(input) ?? /* @__PURE__ */ jsx(
|
|
2254
|
-
Text$1,
|
|
2366
|
+
accessibilityLabel,
|
|
2367
|
+
style: [styles.shell, style],
|
|
2368
|
+
pointerEvents: "box-none",
|
|
2369
|
+
children: [
|
|
2370
|
+
/* @__PURE__ */ jsxs(
|
|
2371
|
+
ScrollView,
|
|
2255
2372
|
{
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
children: tool.shortLabel ?? tool.label.slice(0, 1).toUpperCase()
|
|
2263
|
-
}
|
|
2264
|
-
);
|
|
2265
|
-
return /* @__PURE__ */ jsxs(
|
|
2266
|
-
Pressable,
|
|
2267
|
-
{
|
|
2268
|
-
accessibilityLabel: tool.accessibilityLabel ?? tool.label,
|
|
2269
|
-
accessibilityRole: "button",
|
|
2270
|
-
accessibilityState: { selected, disabled: toolDisabled },
|
|
2271
|
-
disabled: toolDisabled,
|
|
2272
|
-
onPress: onSelect,
|
|
2273
|
-
style: ({ pressed }) => [
|
|
2274
|
-
styles.toolButton,
|
|
2275
|
-
toolButtonStyle,
|
|
2276
|
-
selected ? styles.activeToolButton : void 0,
|
|
2277
|
-
selected ? activeToolButtonStyle : void 0,
|
|
2278
|
-
pressed && !toolDisabled ? styles.pressedToolButton : void 0,
|
|
2279
|
-
toolDisabled ? styles.disabledToolButton : void 0
|
|
2373
|
+
horizontal: true,
|
|
2374
|
+
showsHorizontalScrollIndicator: false,
|
|
2375
|
+
contentContainerStyle: [
|
|
2376
|
+
styles.content,
|
|
2377
|
+
density === "comfortable" ? styles.comfortableContent : void 0,
|
|
2378
|
+
contentContainerStyle
|
|
2280
2379
|
],
|
|
2281
2380
|
children: [
|
|
2282
|
-
/* @__PURE__ */
|
|
2283
|
-
|
|
2284
|
-
|
|
2381
|
+
showToolLockToggle ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2382
|
+
/* @__PURE__ */ jsx(
|
|
2383
|
+
Pressable,
|
|
2384
|
+
{
|
|
2385
|
+
accessibilityLabel: toolLocked ? "Unlock tool" : "Lock tool",
|
|
2386
|
+
accessibilityRole: "button",
|
|
2387
|
+
accessibilityState: {
|
|
2388
|
+
checked: toolLocked,
|
|
2389
|
+
disabled: toolLockDisabled
|
|
2390
|
+
},
|
|
2391
|
+
disabled: toolLockDisabled,
|
|
2392
|
+
onPress: toggleToolLock,
|
|
2393
|
+
style: ({ pressed }) => [
|
|
2394
|
+
styles.toolButton,
|
|
2395
|
+
density === "comfortable" ? styles.comfortableToolButton : void 0,
|
|
2396
|
+
toolLocked ? styles.activeToolButton : void 0,
|
|
2397
|
+
pressed && !toolLockDisabled ? styles.pressedToolButton : void 0,
|
|
2398
|
+
toolLockDisabled ? styles.disabledToolButton : void 0
|
|
2399
|
+
],
|
|
2400
|
+
children: renderToolLockIcon?.({
|
|
2401
|
+
locked: toolLocked,
|
|
2402
|
+
disabled: toolLockDisabled,
|
|
2403
|
+
foregroundColor: "#18181b",
|
|
2404
|
+
onToggle: toggleToolLock
|
|
2405
|
+
}) ?? /* @__PURE__ */ jsx(Text$1, { style: styles.lockGlyph, children: toolLocked ? "L" : "U" })
|
|
2406
|
+
}
|
|
2407
|
+
),
|
|
2408
|
+
/* @__PURE__ */ jsx(View, { style: styles.toolLockDivider })
|
|
2409
|
+
] }) : null,
|
|
2410
|
+
toolbarTools.map(
|
|
2411
|
+
(tool) => renderNativeToolButton({
|
|
2412
|
+
tool,
|
|
2413
|
+
value,
|
|
2414
|
+
onChange,
|
|
2415
|
+
disabled,
|
|
2416
|
+
disabledIds,
|
|
2417
|
+
density,
|
|
2418
|
+
toolButtonStyle,
|
|
2419
|
+
activeToolButtonStyle,
|
|
2420
|
+
toolLabelStyle,
|
|
2421
|
+
activeToolLabelStyle,
|
|
2422
|
+
renderToolIcon,
|
|
2423
|
+
renderToolButton
|
|
2424
|
+
})
|
|
2425
|
+
),
|
|
2426
|
+
showOverflowMenu ? /* @__PURE__ */ jsx(View, { style: styles.overflowSpacer }) : null,
|
|
2427
|
+
showOverflowMenu ? /* @__PURE__ */ jsxs(
|
|
2428
|
+
Pressable,
|
|
2285
2429
|
{
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2430
|
+
accessibilityLabel: activeOverflowTool ? `${overflowMenuAccessibilityLabel}: ${activeOverflowTool.accessibilityLabel ?? activeOverflowTool.label}` : overflowMenuAccessibilityLabel,
|
|
2431
|
+
accessibilityRole: "button",
|
|
2432
|
+
accessibilityState: {
|
|
2433
|
+
expanded: overflowOpen,
|
|
2434
|
+
selected: overflowOpen || activeOverflowTool !== null,
|
|
2435
|
+
disabled
|
|
2436
|
+
},
|
|
2437
|
+
disabled,
|
|
2438
|
+
onPress: toggleOverflow,
|
|
2439
|
+
style: ({ pressed }) => [
|
|
2440
|
+
styles.overflowTrigger,
|
|
2441
|
+
overflowOpen || activeOverflowTool ? styles.activeToolButton : void 0,
|
|
2442
|
+
pressed && !disabled ? styles.pressedToolButton : void 0,
|
|
2443
|
+
disabled ? styles.disabledToolButton : void 0
|
|
2292
2444
|
],
|
|
2293
|
-
children:
|
|
2445
|
+
children: [
|
|
2446
|
+
/* @__PURE__ */ jsx(View, { style: styles.iconSlot, children: activeOverflowTool ? renderToolIcon?.({
|
|
2447
|
+
tool: activeOverflowTool,
|
|
2448
|
+
selected: true,
|
|
2449
|
+
disabled,
|
|
2450
|
+
foregroundColor: "#18181b",
|
|
2451
|
+
onSelect: () => onChange(activeOverflowTool.id)
|
|
2452
|
+
}) ?? renderNativeToolFallback(activeOverflowTool, "#18181b") : renderOverflowIcon?.(overflowRenderInput) ?? /* @__PURE__ */ jsx(Text$1, { style: styles.shapesGlyph, children: "S" }) }),
|
|
2453
|
+
renderOverflowChevronIcon?.(overflowRenderInput) ?? /* @__PURE__ */ jsx(Text$1, { style: styles.chevronGlyph, children: overflowOpen ? "^" : "v" })
|
|
2454
|
+
]
|
|
2294
2455
|
}
|
|
2295
|
-
)
|
|
2456
|
+
) : null
|
|
2296
2457
|
]
|
|
2297
|
-
}
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2458
|
+
}
|
|
2459
|
+
),
|
|
2460
|
+
overflowOpen && showOverflowMenu ? /* @__PURE__ */ jsx(View, { style: [styles.overflowPanel, overflowPanelStyle], children: remainingOverflowTools.map(
|
|
2461
|
+
(tool) => renderNativeToolButton({
|
|
2462
|
+
tool,
|
|
2463
|
+
value,
|
|
2464
|
+
onChange: (toolId) => {
|
|
2465
|
+
setOverflowOpen(false);
|
|
2466
|
+
onChange(toolId);
|
|
2467
|
+
},
|
|
2468
|
+
disabled,
|
|
2469
|
+
disabledIds,
|
|
2470
|
+
density: "compact",
|
|
2471
|
+
toolButtonStyle: styles.overflowToolButton,
|
|
2472
|
+
activeToolButtonStyle,
|
|
2473
|
+
toolLabelStyle,
|
|
2474
|
+
activeToolLabelStyle,
|
|
2475
|
+
renderToolIcon,
|
|
2476
|
+
renderToolButton
|
|
2477
|
+
})
|
|
2478
|
+
) }) : null
|
|
2479
|
+
]
|
|
2480
|
+
}
|
|
2481
|
+
);
|
|
2482
|
+
}
|
|
2483
|
+
function renderNativeToolButton(input) {
|
|
2484
|
+
const selected = input.tool.id === input.value;
|
|
2485
|
+
const toolDisabled = input.disabled || input.tool.disabled || input.disabledIds.has(input.tool.id);
|
|
2486
|
+
const foregroundColor = "#18181b";
|
|
2487
|
+
const onSelect = () => {
|
|
2488
|
+
if (!toolDisabled) {
|
|
2489
|
+
input.onChange(input.tool.id);
|
|
2301
2490
|
}
|
|
2302
|
-
|
|
2491
|
+
};
|
|
2492
|
+
const renderInput = {
|
|
2493
|
+
tool: input.tool,
|
|
2494
|
+
selected,
|
|
2495
|
+
disabled: toolDisabled,
|
|
2496
|
+
foregroundColor,
|
|
2497
|
+
onSelect
|
|
2498
|
+
};
|
|
2499
|
+
if (input.renderToolButton) {
|
|
2500
|
+
return /* @__PURE__ */ jsx(View, { children: input.renderToolButton(renderInput) }, input.tool.id);
|
|
2501
|
+
}
|
|
2502
|
+
const icon = input.renderToolIcon?.(renderInput) ?? renderNativeToolFallback(input.tool, foregroundColor, input.toolLabelStyle);
|
|
2503
|
+
return /* @__PURE__ */ jsxs(
|
|
2504
|
+
Pressable,
|
|
2505
|
+
{
|
|
2506
|
+
accessibilityLabel: input.tool.accessibilityLabel ?? tooltipTextForTool(input.tool),
|
|
2507
|
+
accessibilityRole: "button",
|
|
2508
|
+
accessibilityState: { selected, disabled: toolDisabled },
|
|
2509
|
+
disabled: toolDisabled,
|
|
2510
|
+
onPress: onSelect,
|
|
2511
|
+
style: ({ pressed }) => [
|
|
2512
|
+
styles.toolButton,
|
|
2513
|
+
input.density === "comfortable" ? styles.comfortableToolButton : void 0,
|
|
2514
|
+
input.toolButtonStyle,
|
|
2515
|
+
selected ? styles.activeToolButton : void 0,
|
|
2516
|
+
selected ? input.activeToolButtonStyle : void 0,
|
|
2517
|
+
pressed && !toolDisabled ? styles.pressedToolButton : void 0,
|
|
2518
|
+
toolDisabled ? styles.disabledToolButton : void 0
|
|
2519
|
+
],
|
|
2520
|
+
children: [
|
|
2521
|
+
/* @__PURE__ */ jsx(View, { style: styles.iconSlot, children: icon }),
|
|
2522
|
+
input.density === "comfortable" ? /* @__PURE__ */ jsx(
|
|
2523
|
+
Text$1,
|
|
2524
|
+
{
|
|
2525
|
+
numberOfLines: 1,
|
|
2526
|
+
style: [
|
|
2527
|
+
styles.toolLabel,
|
|
2528
|
+
{ color: foregroundColor },
|
|
2529
|
+
input.toolLabelStyle,
|
|
2530
|
+
selected ? input.activeToolLabelStyle : void 0
|
|
2531
|
+
],
|
|
2532
|
+
children: input.tool.label
|
|
2533
|
+
}
|
|
2534
|
+
) : null
|
|
2535
|
+
]
|
|
2536
|
+
},
|
|
2537
|
+
input.tool.id
|
|
2538
|
+
);
|
|
2539
|
+
}
|
|
2540
|
+
function renderNativeToolFallback(tool, foregroundColor, toolLabelStyle) {
|
|
2541
|
+
return /* @__PURE__ */ jsx(Text$1, { style: [styles.shortLabel, { color: foregroundColor }, toolLabelStyle], children: tool.shortLabel ?? tool.label.slice(0, 1).toUpperCase() });
|
|
2303
2542
|
}
|
|
2304
2543
|
var styles = StyleSheet.create({
|
|
2305
2544
|
shell: {
|
|
2306
|
-
borderRadius:
|
|
2545
|
+
borderRadius: 8,
|
|
2307
2546
|
borderWidth: StyleSheet.hairlineWidth,
|
|
2308
|
-
borderColor: "rgba(
|
|
2309
|
-
backgroundColor: "rgba(255, 255, 255, 0.
|
|
2547
|
+
borderColor: "rgba(0, 0, 0, 0.12)",
|
|
2548
|
+
backgroundColor: "rgba(255, 255, 255, 0.95)",
|
|
2310
2549
|
shadowColor: "#18181b",
|
|
2311
|
-
shadowOpacity: 0.
|
|
2312
|
-
shadowRadius:
|
|
2313
|
-
shadowOffset: { width: 0, height:
|
|
2314
|
-
elevation:
|
|
2550
|
+
shadowOpacity: 0.08,
|
|
2551
|
+
shadowRadius: 3,
|
|
2552
|
+
shadowOffset: { width: 0, height: 1 },
|
|
2553
|
+
elevation: 3
|
|
2315
2554
|
},
|
|
2316
2555
|
content: {
|
|
2317
2556
|
alignItems: "center",
|
|
2318
|
-
gap:
|
|
2319
|
-
paddingHorizontal:
|
|
2557
|
+
gap: 4,
|
|
2558
|
+
paddingHorizontal: 8,
|
|
2320
2559
|
paddingVertical: 6
|
|
2321
2560
|
},
|
|
2561
|
+
comfortableContent: {
|
|
2562
|
+
gap: 6
|
|
2563
|
+
},
|
|
2322
2564
|
toolButton: {
|
|
2323
|
-
minWidth:
|
|
2324
|
-
height:
|
|
2565
|
+
minWidth: 40,
|
|
2566
|
+
height: 40,
|
|
2325
2567
|
alignItems: "center",
|
|
2326
2568
|
justifyContent: "center",
|
|
2327
|
-
gap:
|
|
2328
|
-
borderRadius:
|
|
2569
|
+
gap: 2,
|
|
2570
|
+
borderRadius: 6,
|
|
2329
2571
|
paddingHorizontal: 8,
|
|
2330
2572
|
borderWidth: StyleSheet.hairlineWidth,
|
|
2331
2573
|
borderColor: "transparent",
|
|
2332
2574
|
backgroundColor: "transparent"
|
|
2333
2575
|
},
|
|
2576
|
+
comfortableToolButton: {
|
|
2577
|
+
minWidth: 56,
|
|
2578
|
+
height: 48
|
|
2579
|
+
},
|
|
2334
2580
|
activeToolButton: {
|
|
2335
|
-
borderColor: "rgba(24, 24, 27, 0.
|
|
2336
|
-
backgroundColor: "
|
|
2581
|
+
borderColor: "rgba(24, 24, 27, 0.28)",
|
|
2582
|
+
backgroundColor: "rgba(24, 24, 27, 0.1)"
|
|
2337
2583
|
},
|
|
2338
2584
|
pressedToolButton: {
|
|
2339
2585
|
backgroundColor: "rgba(24, 24, 27, 0.08)"
|
|
@@ -2357,6 +2603,76 @@ var styles = StyleSheet.create({
|
|
|
2357
2603
|
fontSize: 10,
|
|
2358
2604
|
fontWeight: "600",
|
|
2359
2605
|
lineHeight: 12
|
|
2606
|
+
},
|
|
2607
|
+
toolLockDivider: {
|
|
2608
|
+
width: StyleSheet.hairlineWidth,
|
|
2609
|
+
alignSelf: "stretch",
|
|
2610
|
+
backgroundColor: "rgba(24, 24, 27, 0.14)",
|
|
2611
|
+
marginHorizontal: 6,
|
|
2612
|
+
marginVertical: 4
|
|
2613
|
+
},
|
|
2614
|
+
lockGlyph: {
|
|
2615
|
+
color: "#18181b",
|
|
2616
|
+
fontSize: 13,
|
|
2617
|
+
fontWeight: "700",
|
|
2618
|
+
lineHeight: 16
|
|
2619
|
+
},
|
|
2620
|
+
overflowSpacer: {
|
|
2621
|
+
minWidth: 8,
|
|
2622
|
+
flexGrow: 1
|
|
2623
|
+
},
|
|
2624
|
+
overflowTrigger: {
|
|
2625
|
+
minWidth: 48,
|
|
2626
|
+
height: 40,
|
|
2627
|
+
flexDirection: "row",
|
|
2628
|
+
alignItems: "center",
|
|
2629
|
+
justifyContent: "center",
|
|
2630
|
+
gap: 4,
|
|
2631
|
+
borderRadius: 6,
|
|
2632
|
+
paddingHorizontal: 8,
|
|
2633
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
2634
|
+
borderColor: "transparent",
|
|
2635
|
+
backgroundColor: "transparent"
|
|
2636
|
+
},
|
|
2637
|
+
overflowPanel: {
|
|
2638
|
+
position: "absolute",
|
|
2639
|
+
right: 8,
|
|
2640
|
+
bottom: 52,
|
|
2641
|
+
width: 148,
|
|
2642
|
+
flexDirection: "row",
|
|
2643
|
+
flexWrap: "wrap",
|
|
2644
|
+
gap: 6,
|
|
2645
|
+
padding: 10,
|
|
2646
|
+
borderRadius: 10,
|
|
2647
|
+
borderWidth: StyleSheet.hairlineWidth,
|
|
2648
|
+
borderColor: "rgba(0, 0, 0, 0.1)",
|
|
2649
|
+
backgroundColor: "rgba(255, 255, 255, 0.98)",
|
|
2650
|
+
shadowColor: "#18181b",
|
|
2651
|
+
shadowOpacity: 0.12,
|
|
2652
|
+
shadowRadius: 24,
|
|
2653
|
+
shadowOffset: { width: 0, height: -4 },
|
|
2654
|
+
elevation: 8
|
|
2655
|
+
},
|
|
2656
|
+
overflowToolButton: {
|
|
2657
|
+
width: 40,
|
|
2658
|
+
minWidth: 40,
|
|
2659
|
+
height: 40,
|
|
2660
|
+
paddingHorizontal: 0,
|
|
2661
|
+
borderRadius: 8,
|
|
2662
|
+
backgroundColor: "rgba(24, 24, 27, 0.05)"
|
|
2663
|
+
},
|
|
2664
|
+
shapesGlyph: {
|
|
2665
|
+
color: "#18181b",
|
|
2666
|
+
fontSize: 17,
|
|
2667
|
+
fontWeight: "700",
|
|
2668
|
+
lineHeight: 20
|
|
2669
|
+
},
|
|
2670
|
+
chevronGlyph: {
|
|
2671
|
+
color: "#18181b",
|
|
2672
|
+
fontSize: 13,
|
|
2673
|
+
fontWeight: "700",
|
|
2674
|
+
lineHeight: 16,
|
|
2675
|
+
opacity: 0.75
|
|
2360
2676
|
}
|
|
2361
2677
|
});
|
|
2362
2678
|
|
|
@@ -2608,9 +2924,11 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
2608
2924
|
items,
|
|
2609
2925
|
selectedIds = [],
|
|
2610
2926
|
toolId = "hand",
|
|
2927
|
+
toolLocked = false,
|
|
2611
2928
|
interactive = false,
|
|
2612
2929
|
onSelectionChange,
|
|
2613
2930
|
onItemsChange,
|
|
2931
|
+
onToolChangeRequest,
|
|
2614
2932
|
onCameraChange,
|
|
2615
2933
|
toolbar
|
|
2616
2934
|
}, ref) {
|
|
@@ -2618,6 +2936,10 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
2618
2936
|
const cameraRef = useRef(null);
|
|
2619
2937
|
const toolIdRef = useRef(toolId);
|
|
2620
2938
|
toolIdRef.current = toolId;
|
|
2939
|
+
const toolLockedRef = useRef(toolLocked);
|
|
2940
|
+
toolLockedRef.current = toolLocked;
|
|
2941
|
+
const onToolChangeRequestRef = useRef(onToolChangeRequest);
|
|
2942
|
+
onToolChangeRequestRef.current = onToolChangeRequest;
|
|
2621
2943
|
const onCameraChangeRef = useRef(onCameraChange);
|
|
2622
2944
|
onCameraChangeRef.current = onCameraChange;
|
|
2623
2945
|
const onItemsChangeRef = useRef(onItemsChange);
|
|
@@ -2633,8 +2955,23 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
2633
2955
|
null
|
|
2634
2956
|
);
|
|
2635
2957
|
const [eraserTrail, setEraserTrail] = useState([]);
|
|
2958
|
+
const [laserTrail, setLaserTrail] = useState([]);
|
|
2959
|
+
const laserClearTimerRef = useRef(null);
|
|
2960
|
+
useEffect(
|
|
2961
|
+
() => () => {
|
|
2962
|
+
if (laserClearTimerRef.current) {
|
|
2963
|
+
clearTimeout(laserClearTimerRef.current);
|
|
2964
|
+
}
|
|
2965
|
+
},
|
|
2966
|
+
[]
|
|
2967
|
+
);
|
|
2636
2968
|
const [eraserPreviewIds, setEraserPreviewIds] = useState([]);
|
|
2637
2969
|
const eraserPreviewIdSetRef = useRef(/* @__PURE__ */ new Set());
|
|
2970
|
+
const requestSelectToolAfterUse = useCallback(() => {
|
|
2971
|
+
if (!toolLockedRef.current) {
|
|
2972
|
+
onToolChangeRequestRef.current?.("select");
|
|
2973
|
+
}
|
|
2974
|
+
}, []);
|
|
2638
2975
|
if (!cameraRef.current) {
|
|
2639
2976
|
cameraRef.current = new Camera2D({ minZoom: 0.05, maxZoom: 32 });
|
|
2640
2977
|
}
|
|
@@ -2729,12 +3066,19 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
2729
3066
|
}
|
|
2730
3067
|
return;
|
|
2731
3068
|
}
|
|
2732
|
-
if (tool === "draw" || tool === "marker") {
|
|
3069
|
+
if (tool === "draw" || tool === "marker" || tool === "laser") {
|
|
2733
3070
|
dragStateRef.current = {
|
|
2734
3071
|
kind: "draw",
|
|
2735
3072
|
tool,
|
|
2736
3073
|
points: [{ x: worldX, y: worldY }]
|
|
2737
3074
|
};
|
|
3075
|
+
if (tool === "laser") {
|
|
3076
|
+
if (laserClearTimerRef.current) {
|
|
3077
|
+
clearTimeout(laserClearTimerRef.current);
|
|
3078
|
+
laserClearTimerRef.current = null;
|
|
3079
|
+
}
|
|
3080
|
+
setLaserTrail([{ x: worldX, y: worldY }]);
|
|
3081
|
+
}
|
|
2738
3082
|
return;
|
|
2739
3083
|
}
|
|
2740
3084
|
if (tool === "eraser") {
|
|
@@ -2835,11 +3179,15 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
2835
3179
|
if (Math.hypot(dx, dy) > 0.5 / cam.zoom) {
|
|
2836
3180
|
pts.push({ x: worldX, y: worldY });
|
|
2837
3181
|
}
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
3182
|
+
if (st.tool === "laser") {
|
|
3183
|
+
setLaserTrail([...pts]);
|
|
3184
|
+
} else {
|
|
3185
|
+
setPlacementPreview({
|
|
3186
|
+
kind: "stroke",
|
|
3187
|
+
tool: st.tool,
|
|
3188
|
+
points: [...pts]
|
|
3189
|
+
});
|
|
3190
|
+
}
|
|
2843
3191
|
return;
|
|
2844
3192
|
}
|
|
2845
3193
|
if (st.kind === "move") {
|
|
@@ -2907,6 +3255,17 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
2907
3255
|
if (st.kind === "draw") {
|
|
2908
3256
|
dragStateRef.current = { kind: "idle" };
|
|
2909
3257
|
setPlacementPreview(null);
|
|
3258
|
+
if (st.tool === "laser") {
|
|
3259
|
+
if (laserClearTimerRef.current) {
|
|
3260
|
+
clearTimeout(laserClearTimerRef.current);
|
|
3261
|
+
}
|
|
3262
|
+
laserClearTimerRef.current = setTimeout(() => {
|
|
3263
|
+
setLaserTrail([]);
|
|
3264
|
+
laserClearTimerRef.current = null;
|
|
3265
|
+
}, 650);
|
|
3266
|
+
requestSelectToolAfterUse();
|
|
3267
|
+
return;
|
|
3268
|
+
}
|
|
2910
3269
|
if (st.points.length < 1) return;
|
|
2911
3270
|
const change = onItemsChangeRef.current;
|
|
2912
3271
|
if (!change) return;
|
|
@@ -2915,6 +3274,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
2915
3274
|
if (item) {
|
|
2916
3275
|
change([...itemsRef.current, item]);
|
|
2917
3276
|
}
|
|
3277
|
+
requestSelectToolAfterUse();
|
|
2918
3278
|
return;
|
|
2919
3279
|
}
|
|
2920
3280
|
if (st.kind === "move") {
|
|
@@ -2952,6 +3312,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
2952
3312
|
setEraserPreviewIds([]);
|
|
2953
3313
|
setEraserTrail([]);
|
|
2954
3314
|
dragStateRef.current = { kind: "idle" };
|
|
3315
|
+
requestSelectToolAfterUse();
|
|
2955
3316
|
return;
|
|
2956
3317
|
}
|
|
2957
3318
|
if (st.kind === "place") {
|
|
@@ -2989,21 +3350,25 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
2989
3350
|
if (st.tool === "rect") {
|
|
2990
3351
|
change([...itemsRef.current, createRectangleItem(id, raw)]);
|
|
2991
3352
|
onSelectionChangeRef.current?.([id]);
|
|
3353
|
+
requestSelectToolAfterUse();
|
|
2992
3354
|
return;
|
|
2993
3355
|
}
|
|
2994
3356
|
if (st.tool === "ellipse") {
|
|
2995
3357
|
change([...itemsRef.current, createEllipseItem(id, raw)]);
|
|
2996
3358
|
onSelectionChangeRef.current?.([id]);
|
|
3359
|
+
requestSelectToolAfterUse();
|
|
2997
3360
|
return;
|
|
2998
3361
|
}
|
|
2999
3362
|
if (st.tool === "architectural-cloud") {
|
|
3000
3363
|
change([...itemsRef.current, createArchitecturalCloudItem(id, raw)]);
|
|
3001
3364
|
onSelectionChangeRef.current?.([id]);
|
|
3365
|
+
requestSelectToolAfterUse();
|
|
3002
3366
|
return;
|
|
3003
3367
|
}
|
|
3004
3368
|
const line = lineEndpointsToLocal(br, lineStart, lineEnd);
|
|
3005
3369
|
change([...itemsRef.current, createLineItem(id, br, line, st.tool)]);
|
|
3006
3370
|
onSelectionChangeRef.current?.([id]);
|
|
3371
|
+
requestSelectToolAfterUse();
|
|
3007
3372
|
return;
|
|
3008
3373
|
}
|
|
3009
3374
|
if (st.kind === "tap") {
|
|
@@ -3029,6 +3394,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
3029
3394
|
);
|
|
3030
3395
|
change([...itemsRef.current, item]);
|
|
3031
3396
|
onSelectionChangeRef.current?.([id]);
|
|
3397
|
+
requestSelectToolAfterUse();
|
|
3032
3398
|
}
|
|
3033
3399
|
if (st.tool === "note") {
|
|
3034
3400
|
const id = createShapeId();
|
|
@@ -3047,6 +3413,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
3047
3413
|
};
|
|
3048
3414
|
change([...itemsRef.current, note]);
|
|
3049
3415
|
onSelectionChangeRef.current?.([id]);
|
|
3416
|
+
requestSelectToolAfterUse();
|
|
3050
3417
|
}
|
|
3051
3418
|
return;
|
|
3052
3419
|
}
|
|
@@ -3057,9 +3424,10 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
3057
3424
|
lastPanPoint.current = null;
|
|
3058
3425
|
dragStateRef.current = { kind: "idle" };
|
|
3059
3426
|
setPlacementPreview(null);
|
|
3427
|
+
setLaserTrail([]);
|
|
3060
3428
|
}
|
|
3061
3429
|
}),
|
|
3062
|
-
[screenToWorld, requestRender, interactive]
|
|
3430
|
+
[screenToWorld, requestRender, requestSelectToolAfterUse, interactive]
|
|
3063
3431
|
);
|
|
3064
3432
|
useImperativeHandle(
|
|
3065
3433
|
ref,
|
|
@@ -3107,6 +3475,7 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
3107
3475
|
selectedItems,
|
|
3108
3476
|
showResizeHandles,
|
|
3109
3477
|
placementPreview,
|
|
3478
|
+
laserTrail,
|
|
3110
3479
|
eraserTrail,
|
|
3111
3480
|
eraserPreviewItems: items.filter(
|
|
3112
3481
|
(it) => eraserPreviewIds.includes(it.id)
|
|
@@ -3134,6 +3503,6 @@ var NativeVectorViewport = forwardRef(function NativeVectorViewport2({
|
|
|
3134
3503
|
);
|
|
3135
3504
|
});
|
|
3136
3505
|
|
|
3137
|
-
export { DEFAULT_NATIVE_VECTOR_TOOLS, NativeInteractionOverlay, NativeSceneRenderer, NativeShapeRenderer, NativeVectorToolbar, NativeVectorViewport, createFreehandStrokeItem, createShapeId, parseSvgFragment };
|
|
3506
|
+
export { DEFAULT_NATIVE_OVERFLOW_TOOL_IDS, DEFAULT_NATIVE_VECTOR_TOOLS, NativeInteractionOverlay, NativeSceneRenderer, NativeShapeRenderer, NativeVectorToolbar, NativeVectorViewport, createFreehandStrokeItem, createImageItem, createShapeId, parseSvgFragment };
|
|
3138
3507
|
//# sourceMappingURL=native.js.map
|
|
3139
3508
|
//# sourceMappingURL=native.js.map
|