canvu-react 0.3.31 → 0.3.33
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 +168 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +168 -30
- package/dist/index.js.map +1 -1
- package/dist/native.cjs +168 -30
- package/dist/native.cjs.map +1 -1
- package/dist/native.js +168 -30
- package/dist/native.js.map +1 -1
- package/dist/react.cjs +170 -32
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +170 -32
- package/dist/react.js.map +1 -1
- package/dist/realtime.cjs +2 -2
- package/dist/realtime.cjs.map +1 -1
- package/dist/realtime.js +2 -2
- package/dist/realtime.js.map +1 -1
- package/dist/tldraw.cjs +168 -30
- package/dist/tldraw.cjs.map +1 -1
- package/dist/tldraw.js +168 -30
- package/dist/tldraw.js.map +1 -1
- package/package.json +1 -1
package/dist/native.cjs
CHANGED
|
@@ -354,17 +354,154 @@ function svgNumber(value) {
|
|
|
354
354
|
const rounded = Math.round(value * 100) / 100;
|
|
355
355
|
return Number.isInteger(rounded) ? String(rounded) : String(rounded);
|
|
356
356
|
}
|
|
357
|
-
function
|
|
358
|
-
|
|
359
|
-
return Math.PI * (3 * (rx + ry) - Math.sqrt((3 * rx + ry) * (rx + 3 * ry)));
|
|
360
|
-
}
|
|
361
|
-
function architecturalCloudScallopCount(rx, ry, amplitude) {
|
|
362
|
-
const perimeter = approximateEllipsePerimeter(rx, ry);
|
|
363
|
-
const targetScallopLength = Math.max(10, amplitude * 2);
|
|
357
|
+
function architecturalCloudScallopCount(perimeter, amplitude) {
|
|
358
|
+
const targetScallopLength = Math.max(18, amplitude * 2.45);
|
|
364
359
|
let count = Math.max(12, Math.round(perimeter / targetScallopLength));
|
|
365
360
|
if (count % 2 === 1) count += 1;
|
|
366
361
|
return count;
|
|
367
362
|
}
|
|
363
|
+
function roundedRectMetrics(width, height, inset, radius) {
|
|
364
|
+
const left = inset;
|
|
365
|
+
const top = inset;
|
|
366
|
+
const right = width - inset;
|
|
367
|
+
const bottom = height - inset;
|
|
368
|
+
const rectWidth = Math.max(0, right - left);
|
|
369
|
+
const rectHeight = Math.max(0, bottom - top);
|
|
370
|
+
const normalizedRadius = Math.max(
|
|
371
|
+
0,
|
|
372
|
+
Math.min(radius, rectWidth / 2, rectHeight / 2)
|
|
373
|
+
);
|
|
374
|
+
const centerX = width / 2;
|
|
375
|
+
const topHalfLength = Math.max(0, right - normalizedRadius - centerX);
|
|
376
|
+
const horizontalLength = Math.max(0, rectWidth - normalizedRadius * 2);
|
|
377
|
+
const verticalLength = Math.max(0, rectHeight - normalizedRadius * 2);
|
|
378
|
+
const arcLength = normalizedRadius * (Math.PI / 2);
|
|
379
|
+
return {
|
|
380
|
+
left,
|
|
381
|
+
top,
|
|
382
|
+
right,
|
|
383
|
+
bottom,
|
|
384
|
+
radius: normalizedRadius,
|
|
385
|
+
centerX,
|
|
386
|
+
topHalfLength,
|
|
387
|
+
horizontalLength,
|
|
388
|
+
verticalLength,
|
|
389
|
+
arcLength,
|
|
390
|
+
perimeter: horizontalLength * 2 + verticalLength * 2 + Math.PI * 2 * normalizedRadius
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
function pointOnLine(startX, startY, endX, endY, t) {
|
|
394
|
+
return [startX + (endX - startX) * t, startY + (endY - startY) * t];
|
|
395
|
+
}
|
|
396
|
+
function pointOnArc(centerX, centerY, radius, startAngle, endAngle, t) {
|
|
397
|
+
const theta = startAngle + (endAngle - startAngle) * t;
|
|
398
|
+
return [centerX + Math.cos(theta) * radius, centerY + Math.sin(theta) * radius];
|
|
399
|
+
}
|
|
400
|
+
function pointOnRoundedRectPath(metrics, distance) {
|
|
401
|
+
if (metrics.perimeter <= 0) return [metrics.centerX, metrics.top];
|
|
402
|
+
let remaining = (distance % metrics.perimeter + metrics.perimeter) % metrics.perimeter;
|
|
403
|
+
const consume = (length) => {
|
|
404
|
+
if (length <= 1e-9) return null;
|
|
405
|
+
if (remaining <= length) return remaining / length;
|
|
406
|
+
remaining -= length;
|
|
407
|
+
return null;
|
|
408
|
+
};
|
|
409
|
+
let t = consume(metrics.topHalfLength);
|
|
410
|
+
if (t != null) {
|
|
411
|
+
return pointOnLine(
|
|
412
|
+
metrics.centerX,
|
|
413
|
+
metrics.top,
|
|
414
|
+
metrics.right - metrics.radius,
|
|
415
|
+
metrics.top,
|
|
416
|
+
t
|
|
417
|
+
);
|
|
418
|
+
}
|
|
419
|
+
t = consume(metrics.arcLength);
|
|
420
|
+
if (t != null) {
|
|
421
|
+
return pointOnArc(
|
|
422
|
+
metrics.right - metrics.radius,
|
|
423
|
+
metrics.top + metrics.radius,
|
|
424
|
+
metrics.radius,
|
|
425
|
+
-Math.PI / 2,
|
|
426
|
+
0,
|
|
427
|
+
t
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
t = consume(metrics.verticalLength);
|
|
431
|
+
if (t != null) {
|
|
432
|
+
return pointOnLine(
|
|
433
|
+
metrics.right,
|
|
434
|
+
metrics.top + metrics.radius,
|
|
435
|
+
metrics.right,
|
|
436
|
+
metrics.bottom - metrics.radius,
|
|
437
|
+
t
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
t = consume(metrics.arcLength);
|
|
441
|
+
if (t != null) {
|
|
442
|
+
return pointOnArc(
|
|
443
|
+
metrics.right - metrics.radius,
|
|
444
|
+
metrics.bottom - metrics.radius,
|
|
445
|
+
metrics.radius,
|
|
446
|
+
0,
|
|
447
|
+
Math.PI / 2,
|
|
448
|
+
t
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
t = consume(metrics.horizontalLength);
|
|
452
|
+
if (t != null) {
|
|
453
|
+
return pointOnLine(
|
|
454
|
+
metrics.right - metrics.radius,
|
|
455
|
+
metrics.bottom,
|
|
456
|
+
metrics.left + metrics.radius,
|
|
457
|
+
metrics.bottom,
|
|
458
|
+
t
|
|
459
|
+
);
|
|
460
|
+
}
|
|
461
|
+
t = consume(metrics.arcLength);
|
|
462
|
+
if (t != null) {
|
|
463
|
+
return pointOnArc(
|
|
464
|
+
metrics.left + metrics.radius,
|
|
465
|
+
metrics.bottom - metrics.radius,
|
|
466
|
+
metrics.radius,
|
|
467
|
+
Math.PI / 2,
|
|
468
|
+
Math.PI,
|
|
469
|
+
t
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
t = consume(metrics.verticalLength);
|
|
473
|
+
if (t != null) {
|
|
474
|
+
return pointOnLine(
|
|
475
|
+
metrics.left,
|
|
476
|
+
metrics.bottom - metrics.radius,
|
|
477
|
+
metrics.left,
|
|
478
|
+
metrics.top + metrics.radius,
|
|
479
|
+
t
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
t = consume(metrics.arcLength);
|
|
483
|
+
if (t != null) {
|
|
484
|
+
return pointOnArc(
|
|
485
|
+
metrics.left + metrics.radius,
|
|
486
|
+
metrics.top + metrics.radius,
|
|
487
|
+
metrics.radius,
|
|
488
|
+
Math.PI,
|
|
489
|
+
Math.PI * 1.5,
|
|
490
|
+
t
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
t = consume(metrics.topHalfLength);
|
|
494
|
+
if (t != null) {
|
|
495
|
+
return pointOnLine(
|
|
496
|
+
metrics.left + metrics.radius,
|
|
497
|
+
metrics.top,
|
|
498
|
+
metrics.centerX,
|
|
499
|
+
metrics.top,
|
|
500
|
+
t
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
return [metrics.centerX, metrics.top];
|
|
504
|
+
}
|
|
368
505
|
function buildRectSvg(width, height, style = DEFAULT_STROKE_STYLE) {
|
|
369
506
|
return `<rect width="${width}" height="${height}" fill="none" stroke="${style.stroke}" stroke-width="${style.strokeWidth}" rx="4"${strokeOpacityAttr(style)} />`;
|
|
370
507
|
}
|
|
@@ -378,33 +515,34 @@ function buildArchitecturalCloudPathD(width, height, strokeWidth = DEFAULT_STROK
|
|
|
378
515
|
const h = Math.max(0, height);
|
|
379
516
|
if (w <= 0 || h <= 0) return "";
|
|
380
517
|
const inset = Math.max(0.5, strokeWidth / 2);
|
|
381
|
-
const
|
|
382
|
-
const
|
|
383
|
-
if (
|
|
518
|
+
const outerWidth = Math.max(0, w - inset * 2);
|
|
519
|
+
const outerHeight = Math.max(0, h - inset * 2);
|
|
520
|
+
if (outerWidth <= 0 || outerHeight <= 0) return "";
|
|
384
521
|
const amplitude = Math.min(
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
Math.max(
|
|
522
|
+
outerWidth * 0.12,
|
|
523
|
+
outerHeight * 0.12,
|
|
524
|
+
Math.max(5, Math.min(14, Math.min(w, h) * 0.07))
|
|
388
525
|
);
|
|
389
|
-
const
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
const
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
526
|
+
const radius = Math.min(
|
|
527
|
+
outerWidth / 2,
|
|
528
|
+
outerHeight / 2,
|
|
529
|
+
Math.max(amplitude * 2.5, outerHeight * 0.43)
|
|
530
|
+
);
|
|
531
|
+
const outer = roundedRectMetrics(w, h, inset, radius);
|
|
532
|
+
const inner = roundedRectMetrics(
|
|
533
|
+
w,
|
|
534
|
+
h,
|
|
535
|
+
inset + amplitude,
|
|
536
|
+
Math.max(0, radius - amplitude)
|
|
537
|
+
);
|
|
538
|
+
const scallopCount = architecturalCloudScallopCount(outer.perimeter, amplitude);
|
|
539
|
+
const [startX, startY] = pointOnRoundedRectPath(inner, 0);
|
|
401
540
|
const segments = [`M${svgNumber(startX)} ${svgNumber(startY)}`];
|
|
402
541
|
for (let index = 0; index < scallopCount; index += 1) {
|
|
403
|
-
const
|
|
404
|
-
const
|
|
405
|
-
const
|
|
406
|
-
const [
|
|
407
|
-
const [endX, endY] = pointOnEllipse(segmentEnd, innerRx, innerRy);
|
|
542
|
+
const controlDistance = (index + 0.5) / scallopCount * outer.perimeter;
|
|
543
|
+
const endDistance = (index + 1) / scallopCount * inner.perimeter;
|
|
544
|
+
const [controlX, controlY] = pointOnRoundedRectPath(outer, controlDistance);
|
|
545
|
+
const [endX, endY] = pointOnRoundedRectPath(inner, endDistance);
|
|
408
546
|
segments.push(
|
|
409
547
|
`Q${svgNumber(controlX)} ${svgNumber(controlY)} ${svgNumber(endX)} ${svgNumber(endY)}`
|
|
410
548
|
);
|