@xom11/whiteboard 0.6.1 → 0.6.2

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.mjs CHANGED
@@ -1,9 +1,9 @@
1
1
  "use client";
2
+ import './index.css';
2
3
  import dynamic from 'next/dynamic';
3
4
  import { forwardRef, useRef, useState, useEffect, useCallback, useImperativeHandle, useMemo, useId } from 'react';
4
5
  import { createPortal } from 'react-dom';
5
6
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
6
- import JXG from 'jsxgraph';
7
7
  import '@excalidraw/excalidraw/index.css';
8
8
 
9
9
  // src/Whiteboard.tsx
@@ -637,9 +637,9 @@ function handleMove(ctx, e) {
637
637
  if (!ctx.boardRef.current || !ctx.phantomRef.current) return;
638
638
  try {
639
639
  const coords = ctx.boardRef.current.getUsrCoordsOfMouse(e);
640
- const JXG3 = ctx.jxgRef.current;
641
- if (!JXG3) return;
642
- ctx.phantomRef.current.setPositionDirectly(JXG3.COORDS_BY_USER, [coords[0], coords[1]]);
640
+ const JXG = ctx.jxgRef.current;
641
+ if (!JXG) return;
642
+ ctx.phantomRef.current.setPositionDirectly(JXG.COORDS_BY_USER, [coords[0], coords[1]]);
643
643
  ctx.boardRef.current.update();
644
644
  } catch {
645
645
  }
@@ -1446,11 +1446,11 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
1446
1446
  if (typeof window === "undefined" || !containerRef.current) return;
1447
1447
  let cancelled = false;
1448
1448
  (async () => {
1449
- const JXG3 = (await import('jsxgraph')).default;
1449
+ const JXG = (await import('jsxgraph')).default;
1450
1450
  if (cancelled || !containerRef.current) return;
1451
- jxgRef.current = JXG3;
1451
+ jxgRef.current = JXG;
1452
1452
  try {
1453
- const opts = JXG3.Options;
1453
+ const opts = JXG.Options;
1454
1454
  if (opts) {
1455
1455
  opts.text = opts.text || {};
1456
1456
  opts.text.display = "internal";
@@ -1464,7 +1464,7 @@ var JSXGraphMiniBoard = ({ onReady, initialState, isDark }) => {
1464
1464
  }
1465
1465
  } catch {
1466
1466
  }
1467
- const board = JXG3.JSXGraph.initBoard(containerId, {
1467
+ const board = JXG.JSXGraph.initBoard(containerId, {
1468
1468
  boundingbox: initialState?.bbox ?? [-10, 10, 10, -10],
1469
1469
  axis: false,
1470
1470
  // We manage axis manually via toggle for clean default
@@ -2096,9 +2096,9 @@ function renderGeometryToSvg(boardContainer) {
2096
2096
  async function renderGeometrySvgFromState(jsonState) {
2097
2097
  const parsed = JSON.parse(jsonState);
2098
2098
  const palette = paletteFor(false);
2099
- const JXG3 = (await import('jsxgraph')).default;
2099
+ const JXG = (await import('jsxgraph')).default;
2100
2100
  try {
2101
- const opts = JXG3.Options;
2101
+ const opts = JXG.Options;
2102
2102
  if (opts) {
2103
2103
  opts.text = opts.text || {};
2104
2104
  opts.text.display = "internal";
@@ -2123,7 +2123,7 @@ async function renderGeometrySvgFromState(jsonState) {
2123
2123
  document.body.appendChild(container);
2124
2124
  let board = null;
2125
2125
  try {
2126
- board = JXG3.JSXGraph.initBoard(containerId, {
2126
+ board = JXG.JSXGraph.initBoard(containerId, {
2127
2127
  boundingbox: parsed.bbox,
2128
2128
  axis: !!parsed.showAxis,
2129
2129
  grid: !!parsed.showGrid,
@@ -2136,7 +2136,7 @@ async function renderGeometrySvgFromState(jsonState) {
2136
2136
  return renderGeometryToSvg(container);
2137
2137
  } finally {
2138
2138
  try {
2139
- if (board) JXG3.JSXGraph.freeBoard(board);
2139
+ if (board) JXG.JSXGraph.freeBoard(board);
2140
2140
  } catch {
2141
2141
  }
2142
2142
  if (container.parentNode) container.parentNode.removeChild(container);
@@ -3808,126 +3808,134 @@ var MiniBoard3D = forwardRef(function MiniBoard3D2({ isDark, initialState }, ref
3808
3808
  useEffect(() => {
3809
3809
  const div = containerRef.current;
3810
3810
  if (!div) return;
3811
- JXG.Options.text.display = "internal";
3812
- const board = JXG.JSXGraph.initBoard(div, {
3813
- boundingbox: [-6, 6, 6, -6],
3814
- axis: false,
3815
- showCopyright: false,
3816
- showNavigation: false,
3817
- renderer: "svg"
3818
- });
3819
- boardRef.current = board;
3820
- const initView = initialState?.view ?? DEFAULT_VIEW3D;
3821
- const baseAttrs = VIEW3D_ATTRS(isDark);
3822
- const view = board.create(
3823
- "view3d",
3824
- [
3825
- [-5, -5],
3826
- [10, 10],
3811
+ let cancelled = false;
3812
+ let JXG = null;
3813
+ let board = null;
3814
+ void (async () => {
3815
+ JXG = (await import('jsxgraph')).default;
3816
+ if (cancelled || !containerRef.current) return;
3817
+ JXG.Options.text.display = "internal";
3818
+ board = JXG.JSXGraph.initBoard(div, {
3819
+ boundingbox: [-6, 6, 6, -6],
3820
+ axis: false,
3821
+ showCopyright: false,
3822
+ showNavigation: false,
3823
+ renderer: "svg"
3824
+ });
3825
+ boardRef.current = board;
3826
+ const initView = initialState?.view ?? DEFAULT_VIEW3D;
3827
+ const baseAttrs = VIEW3D_ATTRS(isDark);
3828
+ const view = board.create(
3829
+ "view3d",
3827
3830
  [
3828
- [initView.bbox3D[0], initView.bbox3D[3]],
3829
- [initView.bbox3D[1], initView.bbox3D[4]],
3830
- [initView.bbox3D[2], initView.bbox3D[5]]
3831
- ]
3832
- ],
3833
- {
3834
- ...baseAttrs,
3835
- az: { ...baseAttrs.az, value: initView.azimuth },
3836
- el: { ...baseAttrs.el, value: initView.elevation }
3837
- }
3838
- );
3839
- viewRef.current = view;
3840
- let idCounter = 1;
3841
- const ctx = createHandlerContext({
3842
- view,
3843
- pushLog: (e) => {
3844
- logRef.current.push(e);
3845
- notify();
3846
- },
3847
- objMap: objMapRef.current,
3848
- nextId: () => `obj_${Date.now().toString(36)}_${(idCounter++).toString(36)}`,
3849
- isDark,
3850
- promptCoords: (label) => {
3851
- const raw = window.prompt(`${label}
3831
+ [-5, -5],
3832
+ [10, 10],
3833
+ [
3834
+ [initView.bbox3D[0], initView.bbox3D[3]],
3835
+ [initView.bbox3D[1], initView.bbox3D[4]],
3836
+ [initView.bbox3D[2], initView.bbox3D[5]]
3837
+ ]
3838
+ ],
3839
+ {
3840
+ ...baseAttrs,
3841
+ az: { ...baseAttrs.az, value: initView.azimuth },
3842
+ el: { ...baseAttrs.el, value: initView.elevation }
3843
+ }
3844
+ );
3845
+ viewRef.current = view;
3846
+ let idCounter = 1;
3847
+ const ctx = createHandlerContext({
3848
+ view,
3849
+ pushLog: (e) => {
3850
+ logRef.current.push(e);
3851
+ notify();
3852
+ },
3853
+ objMap: objMapRef.current,
3854
+ nextId: () => `obj_${Date.now().toString(36)}_${(idCounter++).toString(36)}`,
3855
+ isDark,
3856
+ promptCoords: (label) => {
3857
+ const raw = window.prompt(`${label}
3852
3858
  (\u0111\u1ECBnh d\u1EA1ng "x,y,z")`, "0,0,0");
3853
- if (!raw) return null;
3854
- const parts = raw.split(",").map((s) => Number(s.trim()));
3855
- if (parts.length !== 3 || parts.some((n) => !isFinite(n))) return null;
3856
- return { x: parts[0], y: parts[1], z: parts[2] };
3857
- },
3858
- promptNumber: (label) => {
3859
- const raw = window.prompt(label, "1");
3860
- if (raw == null) return null;
3861
- const n = Number(raw);
3862
- return isFinite(n) ? n : null;
3863
- },
3864
- promptText: (label) => {
3865
- const raw = window.prompt(label, "");
3866
- return raw == null ? null : raw;
3867
- },
3868
- notify
3869
- });
3870
- ctxRef.current = ctx;
3871
- function findExistingPointAt(clientX, clientY) {
3872
- const containerRect = div.getBoundingClientRect();
3873
- const localX = clientX - containerRect.left;
3874
- const localY = clientY - containerRect.top;
3875
- const PICK = 18;
3876
- const svg = div.querySelector("svg");
3877
- if (!svg) return void 0;
3878
- for (const [id, obj] of objMapRef.current) {
3879
- const entry = obj;
3880
- if (entry?.elType !== "point3d") continue;
3881
- const sc = entry.element2D?.coords?.scrCoords;
3882
- if (!sc || sc.length < 3) continue;
3883
- const dx = sc[1] - localX;
3884
- const dy = sc[2] - localY;
3885
- if (dx * dx + dy * dy <= PICK * PICK) return id;
3859
+ if (!raw) return null;
3860
+ const parts = raw.split(",").map((s) => Number(s.trim()));
3861
+ if (parts.length !== 3 || parts.some((n) => !isFinite(n))) return null;
3862
+ return { x: parts[0], y: parts[1], z: parts[2] };
3863
+ },
3864
+ promptNumber: (label) => {
3865
+ const raw = window.prompt(label, "1");
3866
+ if (raw == null) return null;
3867
+ const n = Number(raw);
3868
+ return isFinite(n) ? n : null;
3869
+ },
3870
+ promptText: (label) => {
3871
+ const raw = window.prompt(label, "");
3872
+ return raw == null ? null : raw;
3873
+ },
3874
+ notify
3875
+ });
3876
+ ctxRef.current = ctx;
3877
+ function findExistingPointAt(clientX, clientY) {
3878
+ const containerRect = div.getBoundingClientRect();
3879
+ const localX = clientX - containerRect.left;
3880
+ const localY = clientY - containerRect.top;
3881
+ const PICK = 18;
3882
+ const svg = div.querySelector("svg");
3883
+ if (!svg) return void 0;
3884
+ for (const [id, obj] of objMapRef.current) {
3885
+ const entry = obj;
3886
+ if (entry?.elType !== "point3d") continue;
3887
+ const sc = entry.element2D?.coords?.scrCoords;
3888
+ if (!sc || sc.length < 3) continue;
3889
+ const dx = sc[1] - localX;
3890
+ const dy = sc[2] - localY;
3891
+ if (dx * dx + dy * dy <= PICK * PICK) return id;
3892
+ }
3893
+ return void 0;
3886
3894
  }
3887
- return void 0;
3888
- }
3889
- const handlePointerDown = (e) => {
3890
- const tool = toolRef.current;
3891
- if (tool === "move") return;
3892
- const existingPointId = findExistingPointAt(e.clientX, e.clientY);
3893
- let x3 = 0;
3894
- let y3 = 0;
3895
- const z3 = 0;
3896
- try {
3897
- const board2d = boardRef.current;
3898
- if (board2d?.getUsrCoordsOfMouse) {
3899
- const uc = board2d.getUsrCoordsOfMouse(e);
3900
- if (Array.isArray(uc) && uc.length >= 2) {
3901
- x3 = uc[0];
3902
- y3 = uc[1];
3895
+ const handlePointerDown = (e) => {
3896
+ const tool = toolRef.current;
3897
+ if (tool === "move") return;
3898
+ const existingPointId = findExistingPointAt(e.clientX, e.clientY);
3899
+ let x3 = 0;
3900
+ let y3 = 0;
3901
+ const z3 = 0;
3902
+ try {
3903
+ const board2d = boardRef.current;
3904
+ if (board2d?.getUsrCoordsOfMouse) {
3905
+ const uc = board2d.getUsrCoordsOfMouse(e);
3906
+ if (Array.isArray(uc) && uc.length >= 2) {
3907
+ x3 = uc[0];
3908
+ y3 = uc[1];
3909
+ }
3903
3910
  }
3911
+ } catch {
3912
+ }
3913
+ const hit = { x3, y3, z3, existingPointId };
3914
+ handleToolStep(ctx, tool, hit);
3915
+ };
3916
+ const svgEl = div.querySelector("svg");
3917
+ const targetEl = svgEl ?? div;
3918
+ const handlePointerDownEv = (e) => handlePointerDown(e);
3919
+ targetEl.addEventListener("pointerdown", handlePointerDownEv);
3920
+ pointerHandlerRef.current = { el: targetEl, fn: handlePointerDownEv };
3921
+ if (initialState?.elements?.length) {
3922
+ const map = objMapRef.current;
3923
+ for (const el of initialState.elements) {
3924
+ const parents = el.parents.map(
3925
+ (p2) => typeof p2 === "string" && p2.startsWith("@id:") ? map.get(p2.slice(4)) : p2
3926
+ );
3927
+ const obj = view.create(el.type, parents, {
3928
+ ...el.attributes,
3929
+ id: el.id,
3930
+ name: el.label
3931
+ });
3932
+ map.set(el.id, obj);
3933
+ logRef.current.push(el);
3904
3934
  }
3905
- } catch {
3906
- }
3907
- const hit = { x3, y3, z3, existingPointId };
3908
- handleToolStep(ctx, tool, hit);
3909
- };
3910
- const svgEl = div.querySelector("svg");
3911
- const targetEl = svgEl ?? div;
3912
- const handlePointerDownEv = (e) => handlePointerDown(e);
3913
- targetEl.addEventListener("pointerdown", handlePointerDownEv);
3914
- pointerHandlerRef.current = { el: targetEl, fn: handlePointerDownEv };
3915
- if (initialState?.elements?.length) {
3916
- const map = objMapRef.current;
3917
- for (const el of initialState.elements) {
3918
- const parents = el.parents.map(
3919
- (p2) => typeof p2 === "string" && p2.startsWith("@id:") ? map.get(p2.slice(4)) : p2
3920
- );
3921
- const obj = view.create(el.type, parents, {
3922
- ...el.attributes,
3923
- id: el.id,
3924
- name: el.label
3925
- });
3926
- map.set(el.id, obj);
3927
- logRef.current.push(el);
3928
3935
  }
3929
- }
3936
+ })();
3930
3937
  return () => {
3938
+ cancelled = true;
3931
3939
  if (pointerHandlerRef.current) {
3932
3940
  pointerHandlerRef.current.el.removeEventListener(
3933
3941
  "pointerdown",
@@ -3936,7 +3944,7 @@ var MiniBoard3D = forwardRef(function MiniBoard3D2({ isDark, initialState }, ref
3936
3944
  pointerHandlerRef.current = null;
3937
3945
  }
3938
3946
  try {
3939
- JXG.JSXGraph.freeBoard(board);
3947
+ if (board && JXG) JXG.JSXGraph.freeBoard(board);
3940
3948
  } catch {
3941
3949
  }
3942
3950
  boardRef.current = null;
@@ -4460,10 +4468,13 @@ function parseSerializedBoard3D(json) {
4460
4468
  }
4461
4469
  return parsed;
4462
4470
  }
4471
+
4472
+ // src/stamps/geometry-3d/render.ts
4463
4473
  var OUTPUT_WIDTH = 1024;
4464
4474
  var OUTPUT_HEIGHT = 768;
4465
4475
  async function renderGeometry3DSvgFromState(jsonState) {
4466
4476
  const state = parseSerializedBoard3D(jsonState);
4477
+ const JXG = (await import('jsxgraph')).default;
4467
4478
  const div = document.createElement("div");
4468
4479
  div.style.cssText = `position:absolute;left:-9999px;top:-9999px;width:${OUTPUT_WIDTH}px;height:${OUTPUT_HEIGHT}px;`;
4469
4480
  document.body.appendChild(div);