@scrawl-board/board 0.1.0-beta.5 → 0.1.0-beta.6
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/browser.js +60 -13
- package/dist/index.js +82 -28
- package/dist/react.js +82 -28
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -36336,13 +36336,26 @@ var INK_Z = .02;
|
|
|
36336
36336
|
var HIGHLIGHT_Z = .016;
|
|
36337
36337
|
/** Ghosts sit under everything so live strokes always read on top. */
|
|
36338
36338
|
var GHOST_Z = .012;
|
|
36339
|
+
/**
|
|
36340
|
+
* A miter join at each centerline point — averaging the incoming and
|
|
36341
|
+
* outgoing segment directions into one width offset — under-covers the
|
|
36342
|
+
* outside of a sharp turn: the two segments' edges diverge there, leaving a
|
|
36343
|
+
* real geometric gap (the board shows through, not just a shader artifact).
|
|
36344
|
+
* Barely visible on opaque ink, but glaring on the highlighter's lower,
|
|
36345
|
+
* multiply-blended opacity, which is why this reads as "goes transparent
|
|
36346
|
+
* at corners" specifically there even though the underlying strip geometry
|
|
36347
|
+
* is shared with ink. Below this turn angle a miter join is a fine
|
|
36348
|
+
* approximation and not worth the extra geometry.
|
|
36349
|
+
*/
|
|
36350
|
+
var JOIN_ANGLE_THRESHOLD = .35;
|
|
36351
|
+
var JOIN_SEGMENTS = 10;
|
|
36339
36352
|
function buildRibbonGeometry(points, baseWidth, z = INK_Z, handDrawn = true) {
|
|
36340
36353
|
const edges = ribbonEdges(points, baseWidth, handDrawn);
|
|
36341
36354
|
const n = edges.length;
|
|
36342
|
-
const positions = new
|
|
36343
|
-
const uvs = new
|
|
36344
|
-
const alphas = new
|
|
36345
|
-
const indices = new
|
|
36355
|
+
const positions = new Array(n * 2 * 3);
|
|
36356
|
+
const uvs = new Array(n * 2 * 2);
|
|
36357
|
+
const alphas = new Array(n * 2);
|
|
36358
|
+
const indices = new Array((n - 1) * 6);
|
|
36346
36359
|
for (let i = 0; i < n; i++) {
|
|
36347
36360
|
const e = edges[i];
|
|
36348
36361
|
const vi = i * 6;
|
|
@@ -36371,11 +36384,45 @@ function buildRibbonGeometry(points, baseWidth, z = INK_Z, handDrawn = true) {
|
|
|
36371
36384
|
indices[ii + 5] = a + 2;
|
|
36372
36385
|
}
|
|
36373
36386
|
}
|
|
36387
|
+
for (let i = 1; i < n - 1; i++) {
|
|
36388
|
+
const prev = points[Math.max(0, i - 1)];
|
|
36389
|
+
const point = points[i];
|
|
36390
|
+
const next = points[Math.min(n - 1, i + 1)];
|
|
36391
|
+
const inX = point.x - prev.x, inY = point.y - prev.y;
|
|
36392
|
+
const outX = next.x - point.x, outY = next.y - point.y;
|
|
36393
|
+
const inLen = Math.hypot(inX, inY) || 1;
|
|
36394
|
+
const outLen = Math.hypot(outX, outY) || 1;
|
|
36395
|
+
const inDx = inX / inLen, inDy = inY / inLen;
|
|
36396
|
+
const outDx = outX / outLen, outDy = outY / outLen;
|
|
36397
|
+
const cos = inDx * outDx + inDy * outDy;
|
|
36398
|
+
if (Math.acos(Math.min(1, Math.max(-1, cos))) < JOIN_ANGLE_THRESHOLD) continue;
|
|
36399
|
+
const radius = (handDrawn ? baseWidth * (MIN_WIDTH_FACTOR + (1 - MIN_WIDTH_FACTOR) * point.pressure) : baseWidth) / 2;
|
|
36400
|
+
const t = i / (n - 1);
|
|
36401
|
+
const alpha = edges[i].alpha;
|
|
36402
|
+
const side = inDx * outDy - inDy * outDx > 0 ? -1 : 1;
|
|
36403
|
+
const inEdgeX = point.x + side * -inDy * radius, inEdgeY = point.y + side * inDx * radius;
|
|
36404
|
+
const outEdgeX = point.x + side * -outDy * radius, outEdgeY = point.y + side * outDx * radius;
|
|
36405
|
+
const angle1 = Math.atan2(inEdgeY - point.y, inEdgeX - point.x);
|
|
36406
|
+
let sweep = Math.atan2(outEdgeY - point.y, outEdgeX - point.x) - angle1;
|
|
36407
|
+
while (sweep > Math.PI) sweep -= Math.PI * 2;
|
|
36408
|
+
while (sweep < -Math.PI) sweep += Math.PI * 2;
|
|
36409
|
+
const center = positions.length / 3;
|
|
36410
|
+
positions.push(point.x, point.y, z);
|
|
36411
|
+
uvs.push(t, .5);
|
|
36412
|
+
alphas.push(alpha);
|
|
36413
|
+
for (let s = 0; s <= JOIN_SEGMENTS; s++) {
|
|
36414
|
+
const theta = angle1 + sweep * (s / JOIN_SEGMENTS);
|
|
36415
|
+
positions.push(point.x + Math.cos(theta) * radius, point.y + Math.sin(theta) * radius, z);
|
|
36416
|
+
uvs.push(t, .5);
|
|
36417
|
+
alphas.push(alpha);
|
|
36418
|
+
if (s > 0) indices.push(center, center + s, center + s + 1);
|
|
36419
|
+
}
|
|
36420
|
+
}
|
|
36374
36421
|
const geometry = new BufferGeometry();
|
|
36375
|
-
geometry.setAttribute("position", new BufferAttribute(positions, 3));
|
|
36376
|
-
geometry.setAttribute("uv", new BufferAttribute(uvs, 2));
|
|
36377
|
-
geometry.setAttribute("aAlpha", new BufferAttribute(alphas, 1));
|
|
36378
|
-
geometry.setIndex(
|
|
36422
|
+
geometry.setAttribute("position", new BufferAttribute(new Float32Array(positions), 3));
|
|
36423
|
+
geometry.setAttribute("uv", new BufferAttribute(new Float32Array(uvs), 2));
|
|
36424
|
+
geometry.setAttribute("aAlpha", new BufferAttribute(new Float32Array(alphas), 1));
|
|
36425
|
+
geometry.setIndex(indices);
|
|
36379
36426
|
geometry.computeBoundingSphere();
|
|
36380
36427
|
return geometry;
|
|
36381
36428
|
}
|
|
@@ -36517,9 +36564,9 @@ function syncMatrix(mesh, stroke) {
|
|
|
36517
36564
|
}
|
|
36518
36565
|
//#endregion
|
|
36519
36566
|
//#region src/renderer/shapes/markerProp.ts
|
|
36520
|
-
var BODY_LENGTH =
|
|
36521
|
-
var BODY_RADIUS = .
|
|
36522
|
-
var TIP_LENGTH = 1.
|
|
36567
|
+
var BODY_LENGTH = 7;
|
|
36568
|
+
var BODY_RADIUS = .55;
|
|
36569
|
+
var TIP_LENGTH = 1.05;
|
|
36523
36570
|
var BASE_TILT = .42;
|
|
36524
36571
|
var VELOCITY_TILT = .22;
|
|
36525
36572
|
var MAX_EXTRA_TILT = .35;
|
|
@@ -36550,12 +36597,12 @@ var MarkerProp = class {
|
|
|
36550
36597
|
const tip = new Mesh(new ConeGeometry(BODY_RADIUS * .55, TIP_LENGTH, 14), tipMaterial);
|
|
36551
36598
|
tip.rotation.x = Math.PI;
|
|
36552
36599
|
tip.position.y = TIP_LENGTH / 2;
|
|
36553
|
-
this.body.position.y =
|
|
36600
|
+
this.body.position.y = 4.55;
|
|
36554
36601
|
const pen = new Group();
|
|
36555
36602
|
pen.add(this.body, tip);
|
|
36556
36603
|
pen.rotation.x = Math.PI / 2;
|
|
36557
36604
|
this.group.add(pen);
|
|
36558
|
-
this.shadow = new Mesh(new CircleGeometry(
|
|
36605
|
+
this.shadow = new Mesh(new CircleGeometry(.9, 24), new MeshBasicMaterial({
|
|
36559
36606
|
color: 0,
|
|
36560
36607
|
transparent: true,
|
|
36561
36608
|
opacity: .13,
|
package/dist/index.js
CHANGED
|
@@ -36416,13 +36416,26 @@ var INK_Z = .02;
|
|
|
36416
36416
|
var HIGHLIGHT_Z = .016;
|
|
36417
36417
|
/** Ghosts sit under everything so live strokes always read on top. */
|
|
36418
36418
|
var GHOST_Z = .012;
|
|
36419
|
+
/**
|
|
36420
|
+
* A miter join at each centerline point — averaging the incoming and
|
|
36421
|
+
* outgoing segment directions into one width offset — under-covers the
|
|
36422
|
+
* outside of a sharp turn: the two segments' edges diverge there, leaving a
|
|
36423
|
+
* real geometric gap (the board shows through, not just a shader artifact).
|
|
36424
|
+
* Barely visible on opaque ink, but glaring on the highlighter's lower,
|
|
36425
|
+
* multiply-blended opacity, which is why this reads as "goes transparent
|
|
36426
|
+
* at corners" specifically there even though the underlying strip geometry
|
|
36427
|
+
* is shared with ink. Below this turn angle a miter join is a fine
|
|
36428
|
+
* approximation and not worth the extra geometry.
|
|
36429
|
+
*/
|
|
36430
|
+
var JOIN_ANGLE_THRESHOLD = .35;
|
|
36431
|
+
var JOIN_SEGMENTS = 10;
|
|
36419
36432
|
function buildRibbonGeometry(points, baseWidth, z = INK_Z, handDrawn = true) {
|
|
36420
36433
|
const edges = ribbonEdges(points, baseWidth, handDrawn);
|
|
36421
36434
|
const n = edges.length;
|
|
36422
|
-
const positions = new
|
|
36423
|
-
const uvs = new
|
|
36424
|
-
const alphas = new
|
|
36425
|
-
const indices = new
|
|
36435
|
+
const positions = new Array(n * 2 * 3);
|
|
36436
|
+
const uvs = new Array(n * 2 * 2);
|
|
36437
|
+
const alphas = new Array(n * 2);
|
|
36438
|
+
const indices = new Array((n - 1) * 6);
|
|
36426
36439
|
for (let i = 0; i < n; i++) {
|
|
36427
36440
|
const e = edges[i];
|
|
36428
36441
|
const vi = i * 6;
|
|
@@ -36451,11 +36464,45 @@ function buildRibbonGeometry(points, baseWidth, z = INK_Z, handDrawn = true) {
|
|
|
36451
36464
|
indices[ii + 5] = a + 2;
|
|
36452
36465
|
}
|
|
36453
36466
|
}
|
|
36467
|
+
for (let i = 1; i < n - 1; i++) {
|
|
36468
|
+
const prev = points[Math.max(0, i - 1)];
|
|
36469
|
+
const point = points[i];
|
|
36470
|
+
const next = points[Math.min(n - 1, i + 1)];
|
|
36471
|
+
const inX = point.x - prev.x, inY = point.y - prev.y;
|
|
36472
|
+
const outX = next.x - point.x, outY = next.y - point.y;
|
|
36473
|
+
const inLen = Math.hypot(inX, inY) || 1;
|
|
36474
|
+
const outLen = Math.hypot(outX, outY) || 1;
|
|
36475
|
+
const inDx = inX / inLen, inDy = inY / inLen;
|
|
36476
|
+
const outDx = outX / outLen, outDy = outY / outLen;
|
|
36477
|
+
const cos = inDx * outDx + inDy * outDy;
|
|
36478
|
+
if (Math.acos(Math.min(1, Math.max(-1, cos))) < JOIN_ANGLE_THRESHOLD) continue;
|
|
36479
|
+
const radius = (handDrawn ? baseWidth * (MIN_WIDTH_FACTOR + (1 - MIN_WIDTH_FACTOR) * point.pressure) : baseWidth) / 2;
|
|
36480
|
+
const t = i / (n - 1);
|
|
36481
|
+
const alpha = edges[i].alpha;
|
|
36482
|
+
const side = inDx * outDy - inDy * outDx > 0 ? -1 : 1;
|
|
36483
|
+
const inEdgeX = point.x + side * -inDy * radius, inEdgeY = point.y + side * inDx * radius;
|
|
36484
|
+
const outEdgeX = point.x + side * -outDy * radius, outEdgeY = point.y + side * outDx * radius;
|
|
36485
|
+
const angle1 = Math.atan2(inEdgeY - point.y, inEdgeX - point.x);
|
|
36486
|
+
let sweep = Math.atan2(outEdgeY - point.y, outEdgeX - point.x) - angle1;
|
|
36487
|
+
while (sweep > Math.PI) sweep -= Math.PI * 2;
|
|
36488
|
+
while (sweep < -Math.PI) sweep += Math.PI * 2;
|
|
36489
|
+
const center = positions.length / 3;
|
|
36490
|
+
positions.push(point.x, point.y, z);
|
|
36491
|
+
uvs.push(t, .5);
|
|
36492
|
+
alphas.push(alpha);
|
|
36493
|
+
for (let s = 0; s <= JOIN_SEGMENTS; s++) {
|
|
36494
|
+
const theta = angle1 + sweep * (s / JOIN_SEGMENTS);
|
|
36495
|
+
positions.push(point.x + Math.cos(theta) * radius, point.y + Math.sin(theta) * radius, z);
|
|
36496
|
+
uvs.push(t, .5);
|
|
36497
|
+
alphas.push(alpha);
|
|
36498
|
+
if (s > 0) indices.push(center, center + s, center + s + 1);
|
|
36499
|
+
}
|
|
36500
|
+
}
|
|
36454
36501
|
const geometry = new BufferGeometry();
|
|
36455
|
-
geometry.setAttribute("position", new BufferAttribute(positions, 3));
|
|
36456
|
-
geometry.setAttribute("uv", new BufferAttribute(uvs, 2));
|
|
36457
|
-
geometry.setAttribute("aAlpha", new BufferAttribute(alphas, 1));
|
|
36458
|
-
geometry.setIndex(
|
|
36502
|
+
geometry.setAttribute("position", new BufferAttribute(new Float32Array(positions), 3));
|
|
36503
|
+
geometry.setAttribute("uv", new BufferAttribute(new Float32Array(uvs), 2));
|
|
36504
|
+
geometry.setAttribute("aAlpha", new BufferAttribute(new Float32Array(alphas), 1));
|
|
36505
|
+
geometry.setIndex(indices);
|
|
36459
36506
|
geometry.computeBoundingSphere();
|
|
36460
36507
|
return geometry;
|
|
36461
36508
|
}
|
|
@@ -36597,9 +36644,9 @@ function syncMatrix(mesh, stroke) {
|
|
|
36597
36644
|
}
|
|
36598
36645
|
//#endregion
|
|
36599
36646
|
//#region src/renderer/shapes/markerProp.ts
|
|
36600
|
-
var BODY_LENGTH =
|
|
36601
|
-
var BODY_RADIUS = .
|
|
36602
|
-
var TIP_LENGTH = 1.
|
|
36647
|
+
var BODY_LENGTH = 7;
|
|
36648
|
+
var BODY_RADIUS = .55;
|
|
36649
|
+
var TIP_LENGTH = 1.05;
|
|
36603
36650
|
var BASE_TILT = .42;
|
|
36604
36651
|
var VELOCITY_TILT = .22;
|
|
36605
36652
|
var MAX_EXTRA_TILT = .35;
|
|
@@ -36630,12 +36677,12 @@ var MarkerProp = class {
|
|
|
36630
36677
|
const tip = new Mesh(new ConeGeometry(BODY_RADIUS * .55, TIP_LENGTH, 14), tipMaterial);
|
|
36631
36678
|
tip.rotation.x = Math.PI;
|
|
36632
36679
|
tip.position.y = TIP_LENGTH / 2;
|
|
36633
|
-
this.body.position.y =
|
|
36680
|
+
this.body.position.y = 4.55;
|
|
36634
36681
|
const pen = new Group();
|
|
36635
36682
|
pen.add(this.body, tip);
|
|
36636
36683
|
pen.rotation.x = Math.PI / 2;
|
|
36637
36684
|
this.group.add(pen);
|
|
36638
|
-
this.shadow = new Mesh(new CircleGeometry(
|
|
36685
|
+
this.shadow = new Mesh(new CircleGeometry(.9, 24), new MeshBasicMaterial({
|
|
36639
36686
|
color: 0,
|
|
36640
36687
|
transparent: true,
|
|
36641
36688
|
opacity: .13,
|
|
@@ -49896,6 +49943,24 @@ function InlineEditors({ controller, renderPortal }) {
|
|
|
49896
49943
|
};
|
|
49897
49944
|
useEffect(() => controller.on("edit-request", (event) => {
|
|
49898
49945
|
const offset = rootOffset();
|
|
49946
|
+
if (event.kind === "text" && event.id === null) {
|
|
49947
|
+
const newId = controller.content.add({
|
|
49948
|
+
type: "text",
|
|
49949
|
+
x: event.boardX,
|
|
49950
|
+
y: event.boardY,
|
|
49951
|
+
text: "",
|
|
49952
|
+
color: event.color,
|
|
49953
|
+
fontSize: TEXT_DEFAULT_SIZE
|
|
49954
|
+
});
|
|
49955
|
+
controller.content.select([newId]);
|
|
49956
|
+
setEditor({
|
|
49957
|
+
...event,
|
|
49958
|
+
id: newId,
|
|
49959
|
+
left: event.screenRect.left - offset.left,
|
|
49960
|
+
top: event.screenRect.top - offset.top
|
|
49961
|
+
});
|
|
49962
|
+
return;
|
|
49963
|
+
}
|
|
49899
49964
|
setEditor({
|
|
49900
49965
|
...event,
|
|
49901
49966
|
left: event.screenRect.left - offset.left,
|
|
@@ -49907,22 +49972,11 @@ function InlineEditors({ controller, renderPortal }) {
|
|
|
49907
49972
|
setEditor(null);
|
|
49908
49973
|
};
|
|
49909
49974
|
const commitText = () => {
|
|
49910
|
-
if (editor?.kind === "text") {
|
|
49975
|
+
if (editor?.kind === "text" && editor.id !== null) {
|
|
49911
49976
|
const text = editor.text;
|
|
49912
|
-
|
|
49913
|
-
|
|
49914
|
-
|
|
49915
|
-
type: "text",
|
|
49916
|
-
x: editor.boardX,
|
|
49917
|
-
y: editor.boardY,
|
|
49918
|
-
text,
|
|
49919
|
-
color: editor.color,
|
|
49920
|
-
fontSize: TEXT_DEFAULT_SIZE
|
|
49921
|
-
});
|
|
49922
|
-
controller.content.select([newId]);
|
|
49923
|
-
}
|
|
49924
|
-
} else if (!text.trim()) controller.content.remove([editor.id]);
|
|
49925
|
-
else controller.content.update(editor.id, { text });
|
|
49977
|
+
const existing = controller.query.get(editor.id);
|
|
49978
|
+
if (!text.trim()) controller.content.remove([editor.id]);
|
|
49979
|
+
else if (existing?.type !== "text" || existing.text !== text) controller.content.update(editor.id, { text });
|
|
49926
49980
|
}
|
|
49927
49981
|
setEditor(null);
|
|
49928
49982
|
};
|
package/dist/react.js
CHANGED
|
@@ -36378,13 +36378,26 @@ var INK_Z = .02;
|
|
|
36378
36378
|
var HIGHLIGHT_Z = .016;
|
|
36379
36379
|
/** Ghosts sit under everything so live strokes always read on top. */
|
|
36380
36380
|
var GHOST_Z = .012;
|
|
36381
|
+
/**
|
|
36382
|
+
* A miter join at each centerline point — averaging the incoming and
|
|
36383
|
+
* outgoing segment directions into one width offset — under-covers the
|
|
36384
|
+
* outside of a sharp turn: the two segments' edges diverge there, leaving a
|
|
36385
|
+
* real geometric gap (the board shows through, not just a shader artifact).
|
|
36386
|
+
* Barely visible on opaque ink, but glaring on the highlighter's lower,
|
|
36387
|
+
* multiply-blended opacity, which is why this reads as "goes transparent
|
|
36388
|
+
* at corners" specifically there even though the underlying strip geometry
|
|
36389
|
+
* is shared with ink. Below this turn angle a miter join is a fine
|
|
36390
|
+
* approximation and not worth the extra geometry.
|
|
36391
|
+
*/
|
|
36392
|
+
var JOIN_ANGLE_THRESHOLD = .35;
|
|
36393
|
+
var JOIN_SEGMENTS = 10;
|
|
36381
36394
|
function buildRibbonGeometry(points, baseWidth, z = INK_Z, handDrawn = true) {
|
|
36382
36395
|
const edges = ribbonEdges(points, baseWidth, handDrawn);
|
|
36383
36396
|
const n = edges.length;
|
|
36384
|
-
const positions = new
|
|
36385
|
-
const uvs = new
|
|
36386
|
-
const alphas = new
|
|
36387
|
-
const indices = new
|
|
36397
|
+
const positions = new Array(n * 2 * 3);
|
|
36398
|
+
const uvs = new Array(n * 2 * 2);
|
|
36399
|
+
const alphas = new Array(n * 2);
|
|
36400
|
+
const indices = new Array((n - 1) * 6);
|
|
36388
36401
|
for (let i = 0; i < n; i++) {
|
|
36389
36402
|
const e = edges[i];
|
|
36390
36403
|
const vi = i * 6;
|
|
@@ -36413,11 +36426,45 @@ function buildRibbonGeometry(points, baseWidth, z = INK_Z, handDrawn = true) {
|
|
|
36413
36426
|
indices[ii + 5] = a + 2;
|
|
36414
36427
|
}
|
|
36415
36428
|
}
|
|
36429
|
+
for (let i = 1; i < n - 1; i++) {
|
|
36430
|
+
const prev = points[Math.max(0, i - 1)];
|
|
36431
|
+
const point = points[i];
|
|
36432
|
+
const next = points[Math.min(n - 1, i + 1)];
|
|
36433
|
+
const inX = point.x - prev.x, inY = point.y - prev.y;
|
|
36434
|
+
const outX = next.x - point.x, outY = next.y - point.y;
|
|
36435
|
+
const inLen = Math.hypot(inX, inY) || 1;
|
|
36436
|
+
const outLen = Math.hypot(outX, outY) || 1;
|
|
36437
|
+
const inDx = inX / inLen, inDy = inY / inLen;
|
|
36438
|
+
const outDx = outX / outLen, outDy = outY / outLen;
|
|
36439
|
+
const cos = inDx * outDx + inDy * outDy;
|
|
36440
|
+
if (Math.acos(Math.min(1, Math.max(-1, cos))) < JOIN_ANGLE_THRESHOLD) continue;
|
|
36441
|
+
const radius = (handDrawn ? baseWidth * (MIN_WIDTH_FACTOR + (1 - MIN_WIDTH_FACTOR) * point.pressure) : baseWidth) / 2;
|
|
36442
|
+
const t = i / (n - 1);
|
|
36443
|
+
const alpha = edges[i].alpha;
|
|
36444
|
+
const side = inDx * outDy - inDy * outDx > 0 ? -1 : 1;
|
|
36445
|
+
const inEdgeX = point.x + side * -inDy * radius, inEdgeY = point.y + side * inDx * radius;
|
|
36446
|
+
const outEdgeX = point.x + side * -outDy * radius, outEdgeY = point.y + side * outDx * radius;
|
|
36447
|
+
const angle1 = Math.atan2(inEdgeY - point.y, inEdgeX - point.x);
|
|
36448
|
+
let sweep = Math.atan2(outEdgeY - point.y, outEdgeX - point.x) - angle1;
|
|
36449
|
+
while (sweep > Math.PI) sweep -= Math.PI * 2;
|
|
36450
|
+
while (sweep < -Math.PI) sweep += Math.PI * 2;
|
|
36451
|
+
const center = positions.length / 3;
|
|
36452
|
+
positions.push(point.x, point.y, z);
|
|
36453
|
+
uvs.push(t, .5);
|
|
36454
|
+
alphas.push(alpha);
|
|
36455
|
+
for (let s = 0; s <= JOIN_SEGMENTS; s++) {
|
|
36456
|
+
const theta = angle1 + sweep * (s / JOIN_SEGMENTS);
|
|
36457
|
+
positions.push(point.x + Math.cos(theta) * radius, point.y + Math.sin(theta) * radius, z);
|
|
36458
|
+
uvs.push(t, .5);
|
|
36459
|
+
alphas.push(alpha);
|
|
36460
|
+
if (s > 0) indices.push(center, center + s, center + s + 1);
|
|
36461
|
+
}
|
|
36462
|
+
}
|
|
36416
36463
|
const geometry = new BufferGeometry();
|
|
36417
|
-
geometry.setAttribute("position", new BufferAttribute(positions, 3));
|
|
36418
|
-
geometry.setAttribute("uv", new BufferAttribute(uvs, 2));
|
|
36419
|
-
geometry.setAttribute("aAlpha", new BufferAttribute(alphas, 1));
|
|
36420
|
-
geometry.setIndex(
|
|
36464
|
+
geometry.setAttribute("position", new BufferAttribute(new Float32Array(positions), 3));
|
|
36465
|
+
geometry.setAttribute("uv", new BufferAttribute(new Float32Array(uvs), 2));
|
|
36466
|
+
geometry.setAttribute("aAlpha", new BufferAttribute(new Float32Array(alphas), 1));
|
|
36467
|
+
geometry.setIndex(indices);
|
|
36421
36468
|
geometry.computeBoundingSphere();
|
|
36422
36469
|
return geometry;
|
|
36423
36470
|
}
|
|
@@ -36559,9 +36606,9 @@ function syncMatrix(mesh, stroke) {
|
|
|
36559
36606
|
}
|
|
36560
36607
|
//#endregion
|
|
36561
36608
|
//#region src/renderer/shapes/markerProp.ts
|
|
36562
|
-
var BODY_LENGTH =
|
|
36563
|
-
var BODY_RADIUS = .
|
|
36564
|
-
var TIP_LENGTH = 1.
|
|
36609
|
+
var BODY_LENGTH = 7;
|
|
36610
|
+
var BODY_RADIUS = .55;
|
|
36611
|
+
var TIP_LENGTH = 1.05;
|
|
36565
36612
|
var BASE_TILT = .42;
|
|
36566
36613
|
var VELOCITY_TILT = .22;
|
|
36567
36614
|
var MAX_EXTRA_TILT = .35;
|
|
@@ -36592,12 +36639,12 @@ var MarkerProp = class {
|
|
|
36592
36639
|
const tip = new Mesh(new ConeGeometry(BODY_RADIUS * .55, TIP_LENGTH, 14), tipMaterial);
|
|
36593
36640
|
tip.rotation.x = Math.PI;
|
|
36594
36641
|
tip.position.y = TIP_LENGTH / 2;
|
|
36595
|
-
this.body.position.y =
|
|
36642
|
+
this.body.position.y = 4.55;
|
|
36596
36643
|
const pen = new Group();
|
|
36597
36644
|
pen.add(this.body, tip);
|
|
36598
36645
|
pen.rotation.x = Math.PI / 2;
|
|
36599
36646
|
this.group.add(pen);
|
|
36600
|
-
this.shadow = new Mesh(new CircleGeometry(
|
|
36647
|
+
this.shadow = new Mesh(new CircleGeometry(.9, 24), new MeshBasicMaterial({
|
|
36601
36648
|
color: 0,
|
|
36602
36649
|
transparent: true,
|
|
36603
36650
|
opacity: .13,
|
|
@@ -49858,6 +49905,24 @@ function InlineEditors({ controller, renderPortal }) {
|
|
|
49858
49905
|
};
|
|
49859
49906
|
useEffect(() => controller.on("edit-request", (event) => {
|
|
49860
49907
|
const offset = rootOffset();
|
|
49908
|
+
if (event.kind === "text" && event.id === null) {
|
|
49909
|
+
const newId = controller.content.add({
|
|
49910
|
+
type: "text",
|
|
49911
|
+
x: event.boardX,
|
|
49912
|
+
y: event.boardY,
|
|
49913
|
+
text: "",
|
|
49914
|
+
color: event.color,
|
|
49915
|
+
fontSize: TEXT_DEFAULT_SIZE
|
|
49916
|
+
});
|
|
49917
|
+
controller.content.select([newId]);
|
|
49918
|
+
setEditor({
|
|
49919
|
+
...event,
|
|
49920
|
+
id: newId,
|
|
49921
|
+
left: event.screenRect.left - offset.left,
|
|
49922
|
+
top: event.screenRect.top - offset.top
|
|
49923
|
+
});
|
|
49924
|
+
return;
|
|
49925
|
+
}
|
|
49861
49926
|
setEditor({
|
|
49862
49927
|
...event,
|
|
49863
49928
|
left: event.screenRect.left - offset.left,
|
|
@@ -49869,22 +49934,11 @@ function InlineEditors({ controller, renderPortal }) {
|
|
|
49869
49934
|
setEditor(null);
|
|
49870
49935
|
};
|
|
49871
49936
|
const commitText = () => {
|
|
49872
|
-
if (editor?.kind === "text") {
|
|
49937
|
+
if (editor?.kind === "text" && editor.id !== null) {
|
|
49873
49938
|
const text = editor.text;
|
|
49874
|
-
|
|
49875
|
-
|
|
49876
|
-
|
|
49877
|
-
type: "text",
|
|
49878
|
-
x: editor.boardX,
|
|
49879
|
-
y: editor.boardY,
|
|
49880
|
-
text,
|
|
49881
|
-
color: editor.color,
|
|
49882
|
-
fontSize: TEXT_DEFAULT_SIZE
|
|
49883
|
-
});
|
|
49884
|
-
controller.content.select([newId]);
|
|
49885
|
-
}
|
|
49886
|
-
} else if (!text.trim()) controller.content.remove([editor.id]);
|
|
49887
|
-
else controller.content.update(editor.id, { text });
|
|
49939
|
+
const existing = controller.query.get(editor.id);
|
|
49940
|
+
if (!text.trim()) controller.content.remove([editor.id]);
|
|
49941
|
+
else if (existing?.type !== "text" || existing.text !== text) controller.content.update(editor.id, { text });
|
|
49888
49942
|
}
|
|
49889
49943
|
setEditor(null);
|
|
49890
49944
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scrawl-board/board",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.6",
|
|
4
4
|
"description": "The Scrawl Board SDK: an embeddable, collaborative infinite-canvas whiteboard for React and vanilla JS/TS apps.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|