canvu-react 0.3.6 → 0.3.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.js CHANGED
@@ -123,32 +123,6 @@ function getRotationHandleWorldPosition(bounds, rotationRad, handleOffsetWorld)
123
123
  }
124
124
 
125
125
  // src/scene/freehand-path.ts
126
- function dedupeFreehandPoints(points, minDist) {
127
- if (points.length <= 2) {
128
- return points.map((p) => ({ ...p }));
129
- }
130
- const minSq = minDist * minDist;
131
- const first = points[0];
132
- if (!first) return [];
133
- const out = [{ ...first }];
134
- for (let i = 1; i < points.length - 1; i++) {
135
- const p = points[i];
136
- const last = out[out.length - 1];
137
- if (!p || !last) continue;
138
- const dx = p.x - last.x;
139
- const dy = p.y - last.y;
140
- if (dx * dx + dy * dy >= minSq) {
141
- out.push({ ...p });
142
- }
143
- }
144
- const end = points[points.length - 1];
145
- const lastKept = out[out.length - 1];
146
- if (!end || !lastKept) return out;
147
- if ((end.x - lastKept.x) ** 2 + (end.y - lastKept.y) ** 2 > 1e-12) {
148
- out.push({ ...end });
149
- }
150
- return out;
151
- }
152
126
  function smoothFreehandPointsToPathD(points) {
153
127
  const n = points.length;
154
128
  if (n === 0) return "";
@@ -181,29 +155,6 @@ function smoothFreehandPointsToPathD(points) {
181
155
  d += ` Q ${pLast.x} ${pLast.y} ${pEnd.x} ${pEnd.y}`;
182
156
  return d;
183
157
  }
184
- function outlineStrokeToClosedPathD(outline) {
185
- const len = outline.length;
186
- if (len === 0) return "";
187
- const first = outline[0];
188
- if (!first) return "";
189
- if (len < 3) {
190
- let d2 = `M ${first[0]} ${first[1]}`;
191
- for (let i = 1; i < len; i++) {
192
- const pt = outline[i];
193
- if (!pt) continue;
194
- d2 += ` L ${pt[0]} ${pt[1]}`;
195
- }
196
- return `${d2} Z`;
197
- }
198
- let d = `M ${first[0]} ${first[1]} Q`;
199
- for (let i = 0; i < len; i++) {
200
- const p0 = outline[i];
201
- const p1 = outline[(i + 1) % len];
202
- if (!p0 || !p1) continue;
203
- d += ` ${p0[0]} ${p0[1]} ${(p0[0] + p1[0]) / 2} ${(p0[1] + p1[1]) / 2}`;
204
- }
205
- return `${d} Z`;
206
- }
207
158
 
208
159
  // src/scene/custom-shape.ts
209
160
  function buildCustomShapeChildrenSvg(inner, intrinsic, bounds) {
@@ -333,7 +284,7 @@ var DEFAULT_STROKE_STYLE = {
333
284
  strokeWidth: 2
334
285
  };
335
286
  var TOOL_FREEHAND_DEFAULTS = {
336
- draw: { strokeWidth: 3 },
287
+ draw: { strokeWidth: 10 },
337
288
  pencil: { strokeWidth: 3 },
338
289
  brush: { strokeWidth: 10 },
339
290
  marker: { stroke: "#fde047", strokeWidth: 16, strokeOpacity: 0.5 }
@@ -350,18 +301,18 @@ function perfectFreehandOptions(toolKind, style, strokeComplete, pressureAware =
350
301
  ...base,
351
302
  size: Math.max(2, sw * 1.05),
352
303
  thinning: 0.42,
353
- smoothing: 0.56,
354
- streamline: 0.18,
355
- simulatePressure: false
304
+ smoothing: 0.78,
305
+ streamline: 0.62,
306
+ simulatePressure: true
356
307
  };
357
308
  }
358
309
  return {
359
310
  ...base,
360
311
  size: Math.max(2, sw * 1.18),
361
312
  thinning: 0.12,
362
- smoothing: 0.72,
363
- streamline: 0.42,
364
- simulatePressure: false
313
+ smoothing: 0.85,
314
+ streamline: 0.78,
315
+ simulatePressure: true
365
316
  };
366
317
  }
367
318
  if (toolKind === "brush") {
@@ -379,7 +330,7 @@ function perfectFreehandOptions(toolKind, style, strokeComplete, pressureAware =
379
330
  thinning: 0.08,
380
331
  smoothing: 0.88,
381
332
  streamline: 0.84,
382
- simulatePressure: false
333
+ simulatePressure: true
383
334
  };
384
335
  }
385
336
  function resolveStrokeStyle(item) {
@@ -449,70 +400,41 @@ function computeFreehandSvgPayload(pathPointsLocal, style, toolKind, strokeCompl
449
400
  if (pathPointsLocal.length === 1) {
450
401
  const p = pathPointsLocal[0];
451
402
  if (!p) return null;
452
- const r = Math.max(0.5, style.strokeWidth / 2);
453
403
  return {
454
404
  kind: "circle",
455
405
  cx: p.x,
456
406
  cy: p.y,
457
- r,
407
+ r: Math.max(0.5, style.strokeWidth / 2),
458
408
  fill: style.stroke,
459
409
  fillOpacity: style.strokeOpacity
460
410
  };
461
411
  }
462
- const minDist = Math.min(0.25, Math.max(0.02, style.strokeWidth * 0.02));
463
- const pts = dedupeFreehandPoints(pathPointsLocal, minDist);
464
- if (pts.length === 0) return null;
465
- if (pts.length === 1) {
466
- const p = pts[0];
467
- if (!p) return null;
468
- const r = Math.max(0.5, style.strokeWidth / 2);
469
- return {
470
- kind: "circle",
471
- cx: p.x,
472
- cy: p.y,
473
- r,
474
- fill: style.stroke,
475
- fillOpacity: style.strokeOpacity
476
- };
477
- }
478
- const hasPressure = toolKind === "draw" && pts.some((p) => p.pressure != null && Number.isFinite(p.pressure));
479
- if (toolKind === "draw" && !hasPressure) {
480
- const d2 = smoothFreehandPointsToPathD(pts);
481
- return {
482
- kind: "strokePath",
483
- d: d2,
484
- stroke: style.stroke,
485
- strokeWidth: style.strokeWidth,
486
- strokeOpacity: style.strokeOpacity
487
- };
488
- }
489
- const input = hasPressure ? pts.map(
412
+ const hasPressure = pathPointsLocal.some(
413
+ (p) => p.pressure != null && Number.isFinite(p.pressure)
414
+ );
415
+ const input = hasPressure ? pathPointsLocal.map(
490
416
  (p) => [p.x, p.y, Math.min(1, Math.max(0, p.pressure ?? 0.5))]
491
- ) : pts.map((p) => [p.x, p.y]);
492
- const opts = perfectFreehandOptions(toolKind, style, strokeComplete, hasPressure);
493
- let outline = [];
494
- try {
495
- const raw = getStroke(input, opts);
496
- outline = raw.map(([x, y]) => [x, y]);
497
- } catch {
498
- outline = [];
499
- }
500
- if (outline.length >= 3) {
501
- const d2 = outlineStrokeToClosedPathD(outline);
502
- return {
503
- kind: "fillPath",
504
- d: d2,
505
- fill: style.stroke,
506
- fillOpacity: style.strokeOpacity
507
- };
417
+ ) : pathPointsLocal.map((p) => [p.x, p.y]);
418
+ const stroke = getStroke(
419
+ input,
420
+ perfectFreehandOptions(toolKind, style, strokeComplete, hasPressure)
421
+ );
422
+ if (stroke.length < 3) return null;
423
+ const first = stroke[0];
424
+ if (!first) return null;
425
+ let d = `M ${first[0]} ${first[1]} Q`;
426
+ for (let i = 0; i < stroke.length; i++) {
427
+ const a = stroke[i];
428
+ const b = stroke[(i + 1) % stroke.length];
429
+ if (!a || !b) continue;
430
+ d += ` ${a[0]} ${a[1]} ${(a[0] + b[0]) / 2} ${(a[1] + b[1]) / 2}`;
508
431
  }
509
- const d = smoothFreehandPointsToPathD(pts);
432
+ d += " Z";
510
433
  return {
511
- kind: "strokePath",
434
+ kind: "fillPath",
512
435
  d,
513
- stroke: style.stroke,
514
- strokeWidth: style.strokeWidth,
515
- strokeOpacity: style.strokeOpacity
436
+ fill: style.stroke,
437
+ fillOpacity: style.strokeOpacity
516
438
  };
517
439
  }
518
440
  function freehandPayloadToSvgString(payload) {