@dcg-overseas/number-line 1.0.0-beta.2 → 1.0.0-beta.4

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 CHANGED
@@ -223,6 +223,7 @@ function useNumberLineContext() {
223
223
  if (!ctx) throw new Error("Must be used inside <NumberLineProvider>");
224
224
  return ctx;
225
225
  }
226
+ const DEFAULT_DRAWING_STROKE_WIDTH = 2.5;
226
227
  function normalizeDomain(lo, hi) {
227
228
  const a = Number(lo);
228
229
  const b = Number(hi);
@@ -255,6 +256,7 @@ function NumberLineProvider({
255
256
  groupSize,
256
257
  groupCount,
257
258
  tickStep,
259
+ strokeWidth: configuredStrokeWidth,
258
260
  arcColors,
259
261
  showGroupTicks = true,
260
262
  showMajorTicks = true,
@@ -270,6 +272,7 @@ function NumberLineProvider({
270
272
  children
271
273
  }) {
272
274
  const { min: domainMin, max: domainMax } = normalizeDomain(min, max);
275
+ const strokeWidth = typeof configuredStrokeWidth === "number" && Number.isFinite(configuredStrokeWidth) && configuredStrokeWidth > 0 ? configuredStrokeWidth : DEFAULT_DRAWING_STROKE_WIDTH;
273
276
  const [selectedArcIndices, setSelectedArcIndices] = React.useState(/* @__PURE__ */ new Set());
274
277
  const [deletedArcIndices, setDeletedArcIndices] = React.useState(/* @__PURE__ */ new Set());
275
278
  const [groupTicksHidden, setGroupTicksHidden] = React.useState(false);
@@ -286,7 +289,6 @@ function NumberLineProvider({
286
289
  onChange: onViewChange
287
290
  });
288
291
  const [liveStroke, setLiveStroke] = React.useState(null);
289
- const svgPoint = React.useRef(null);
290
292
  const [eraseHoverIds, setEraseHoverIds] = React.useState(/* @__PURE__ */ new Set());
291
293
  const eraseGesture = React.useRef(null);
292
294
  const createHistorySnapshot = React.useCallback(
@@ -316,20 +318,17 @@ function NumberLineProvider({
316
318
  drawing.resetStrokes,
317
319
  history.clear
318
320
  ]);
319
- const getLocalCoords = React.useCallback(
320
- (e) => {
321
- const svg = svgRef.current;
322
- if (!svg) return null;
323
- const ctm = svg.getScreenCTM();
324
- if (!ctm) return null;
325
- if (!svgPoint.current) svgPoint.current = svg.createSVGPoint();
326
- svgPoint.current.x = e.clientX;
327
- svgPoint.current.y = e.clientY;
328
- const pt = svgPoint.current.matrixTransform(ctm.inverse());
329
- return [pt.x, pt.y];
330
- },
331
- [svgRef]
332
- );
321
+ const getLocalCoords = React.useCallback((event) => {
322
+ const svg = svgRef.current;
323
+ if (!svg) return null;
324
+ const rect = svg.getBoundingClientRect();
325
+ const viewBox = svg.viewBox.baseVal;
326
+ if (rect.width <= 0 || rect.height <= 0 || viewBox.width <= 0 || viewBox.height <= 0) return null;
327
+ return [
328
+ viewBox.x + (event.clientX - rect.left) / rect.width * viewBox.width,
329
+ viewBox.y + (event.clientY - rect.top) / rect.height * viewBox.height
330
+ ];
331
+ }, [svgRef]);
333
332
  const strokeIdsNear = React.useCallback(
334
333
  (x, y, radius) => {
335
334
  const ids = [];
@@ -551,6 +550,7 @@ function NumberLineProvider({
551
550
  groupSize,
552
551
  groupCount,
553
552
  tickStep,
553
+ strokeWidth,
554
554
  arcColors,
555
555
  showGroupTicks: showGroupTicks && !groupTicksHidden,
556
556
  showMajorTicks,
@@ -1023,7 +1023,7 @@ const GroupArcsLayer = React.memo(function GroupArcsLayer2({
1023
1023
  }
1024
1024
  return /* @__PURE__ */ jsxRuntime.jsx("g", { className: "nl-arcs-layer", children: arcs });
1025
1025
  });
1026
- function DrawingLayer({ strokes, liveStroke, tool, width, height, eraseHoverIds, onStrokeClick }) {
1026
+ function DrawingLayer({ strokes, liveStroke, tool, width, height, strokeWidth, eraseHoverIds, onStrokeClick }) {
1027
1027
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { className: "nl-drawing-layer", transform: `scale(${width} ${height})`, children: [
1028
1028
  strokes.map((s) => /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
1029
1029
  (s.selected || tool === "eraser" && eraseHoverIds.has(s.id)) && /* @__PURE__ */ jsxRuntime.jsx(
@@ -1065,7 +1065,7 @@ function DrawingLayer({ strokes, liveStroke, tool, width, height, eraseHoverIds,
1065
1065
  d: s.d,
1066
1066
  fill: "none",
1067
1067
  stroke: "#7c3aed",
1068
- strokeWidth: 2.5,
1068
+ strokeWidth,
1069
1069
  strokeLinecap: "round",
1070
1070
  strokeLinejoin: "round",
1071
1071
  vectorEffect: "non-scaling-stroke",
@@ -1079,7 +1079,7 @@ function DrawingLayer({ strokes, liveStroke, tool, width, height, eraseHoverIds,
1079
1079
  d: liveStroke.d,
1080
1080
  fill: "none",
1081
1081
  stroke: "#7c3aed",
1082
- strokeWidth: 2.5,
1082
+ strokeWidth,
1083
1083
  strokeLinecap: "round",
1084
1084
  strokeLinejoin: "round",
1085
1085
  vectorEffect: "non-scaling-stroke",
@@ -1104,6 +1104,7 @@ function NumberLine({ className }) {
1104
1104
  groupSize,
1105
1105
  groupCount,
1106
1106
  tickStep,
1107
+ strokeWidth,
1107
1108
  arcColors,
1108
1109
  showGroupTicks,
1109
1110
  showMajorTicks,
@@ -1355,6 +1356,7 @@ function NumberLine({ className }) {
1355
1356
  tool,
1356
1357
  width: w,
1357
1358
  height: h,
1359
+ strokeWidth,
1358
1360
  eraseHoverIds,
1359
1361
  onStrokeClick
1360
1362
  }
package/dist/index.d.ts CHANGED
@@ -15,6 +15,8 @@ export declare interface NumberLineContextValue {
15
15
  groupSize: number;
16
16
  groupCount: number;
17
17
  tickStep: number;
18
+ /** 用户自由绘制笔迹的固定视觉线宽,单位为 CSS 像素。 */
19
+ strokeWidth: number;
18
20
  arcColors?: string[];
19
21
  showGroupTicks: boolean;
20
22
  showMajorTicks: boolean;
@@ -60,6 +62,8 @@ export declare interface NumberLineProps {
60
62
  groupSize: number;
61
63
  groupCount: number;
62
64
  tickStep: number;
65
+ /** 用户自由绘制笔迹的固定视觉线宽,单位为 CSS 像素;默认 2.5。 */
66
+ strokeWidth?: number;
63
67
  arcColors?: string[];
64
68
  /** show group boundary ticks (tallest). Default: true */
65
69
  showGroupTicks?: boolean;
@@ -87,7 +91,7 @@ export declare interface NumberLineProps {
87
91
  getShowLabelStep?: (params: unknown) => boolean;
88
92
  }
89
93
 
90
- export declare function NumberLineProvider({ min, max, groupSize, groupCount, tickStep, arcColors, showGroupTicks, showMajorTicks, showMinorTicks, enableZoom, minZoom, maxZoom, showLabelStep, viewMin: controlledViewMin, viewMax: controlledViewMax, getShowLabelStep, onViewChange, children, }: NumberLineProviderProps): JSX_2.Element;
94
+ export declare function NumberLineProvider({ min, max, groupSize, groupCount, tickStep, strokeWidth: configuredStrokeWidth, arcColors, showGroupTicks, showMajorTicks, showMinorTicks, enableZoom, minZoom, maxZoom, showLabelStep, viewMin: controlledViewMin, viewMax: controlledViewMax, getShowLabelStep, onViewChange, children, }: NumberLineProviderProps): JSX_2.Element;
91
95
 
92
96
  declare interface NumberLineProviderProps extends NumberLineProps {
93
97
  children: default_2.ReactNode;
package/dist/index.js CHANGED
@@ -221,6 +221,7 @@ function useNumberLineContext() {
221
221
  if (!ctx) throw new Error("Must be used inside <NumberLineProvider>");
222
222
  return ctx;
223
223
  }
224
+ const DEFAULT_DRAWING_STROKE_WIDTH = 2.5;
224
225
  function normalizeDomain(lo, hi) {
225
226
  const a = Number(lo);
226
227
  const b = Number(hi);
@@ -253,6 +254,7 @@ function NumberLineProvider({
253
254
  groupSize,
254
255
  groupCount,
255
256
  tickStep,
257
+ strokeWidth: configuredStrokeWidth,
256
258
  arcColors,
257
259
  showGroupTicks = true,
258
260
  showMajorTicks = true,
@@ -268,6 +270,7 @@ function NumberLineProvider({
268
270
  children
269
271
  }) {
270
272
  const { min: domainMin, max: domainMax } = normalizeDomain(min, max);
273
+ const strokeWidth = typeof configuredStrokeWidth === "number" && Number.isFinite(configuredStrokeWidth) && configuredStrokeWidth > 0 ? configuredStrokeWidth : DEFAULT_DRAWING_STROKE_WIDTH;
271
274
  const [selectedArcIndices, setSelectedArcIndices] = useState(/* @__PURE__ */ new Set());
272
275
  const [deletedArcIndices, setDeletedArcIndices] = useState(/* @__PURE__ */ new Set());
273
276
  const [groupTicksHidden, setGroupTicksHidden] = useState(false);
@@ -284,7 +287,6 @@ function NumberLineProvider({
284
287
  onChange: onViewChange
285
288
  });
286
289
  const [liveStroke, setLiveStroke] = useState(null);
287
- const svgPoint = useRef(null);
288
290
  const [eraseHoverIds, setEraseHoverIds] = useState(/* @__PURE__ */ new Set());
289
291
  const eraseGesture = useRef(null);
290
292
  const createHistorySnapshot = useCallback(
@@ -314,20 +316,17 @@ function NumberLineProvider({
314
316
  drawing.resetStrokes,
315
317
  history.clear
316
318
  ]);
317
- const getLocalCoords = useCallback(
318
- (e) => {
319
- const svg = svgRef.current;
320
- if (!svg) return null;
321
- const ctm = svg.getScreenCTM();
322
- if (!ctm) return null;
323
- if (!svgPoint.current) svgPoint.current = svg.createSVGPoint();
324
- svgPoint.current.x = e.clientX;
325
- svgPoint.current.y = e.clientY;
326
- const pt = svgPoint.current.matrixTransform(ctm.inverse());
327
- return [pt.x, pt.y];
328
- },
329
- [svgRef]
330
- );
319
+ const getLocalCoords = useCallback((event) => {
320
+ const svg = svgRef.current;
321
+ if (!svg) return null;
322
+ const rect = svg.getBoundingClientRect();
323
+ const viewBox = svg.viewBox.baseVal;
324
+ if (rect.width <= 0 || rect.height <= 0 || viewBox.width <= 0 || viewBox.height <= 0) return null;
325
+ return [
326
+ viewBox.x + (event.clientX - rect.left) / rect.width * viewBox.width,
327
+ viewBox.y + (event.clientY - rect.top) / rect.height * viewBox.height
328
+ ];
329
+ }, [svgRef]);
331
330
  const strokeIdsNear = useCallback(
332
331
  (x, y, radius) => {
333
332
  const ids = [];
@@ -549,6 +548,7 @@ function NumberLineProvider({
549
548
  groupSize,
550
549
  groupCount,
551
550
  tickStep,
551
+ strokeWidth,
552
552
  arcColors,
553
553
  showGroupTicks: showGroupTicks && !groupTicksHidden,
554
554
  showMajorTicks,
@@ -1021,7 +1021,7 @@ const GroupArcsLayer = memo(function GroupArcsLayer2({
1021
1021
  }
1022
1022
  return /* @__PURE__ */ jsx("g", { className: "nl-arcs-layer", children: arcs });
1023
1023
  });
1024
- function DrawingLayer({ strokes, liveStroke, tool, width, height, eraseHoverIds, onStrokeClick }) {
1024
+ function DrawingLayer({ strokes, liveStroke, tool, width, height, strokeWidth, eraseHoverIds, onStrokeClick }) {
1025
1025
  return /* @__PURE__ */ jsxs("g", { className: "nl-drawing-layer", transform: `scale(${width} ${height})`, children: [
1026
1026
  strokes.map((s) => /* @__PURE__ */ jsxs("g", { children: [
1027
1027
  (s.selected || tool === "eraser" && eraseHoverIds.has(s.id)) && /* @__PURE__ */ jsx(
@@ -1063,7 +1063,7 @@ function DrawingLayer({ strokes, liveStroke, tool, width, height, eraseHoverIds,
1063
1063
  d: s.d,
1064
1064
  fill: "none",
1065
1065
  stroke: "#7c3aed",
1066
- strokeWidth: 2.5,
1066
+ strokeWidth,
1067
1067
  strokeLinecap: "round",
1068
1068
  strokeLinejoin: "round",
1069
1069
  vectorEffect: "non-scaling-stroke",
@@ -1077,7 +1077,7 @@ function DrawingLayer({ strokes, liveStroke, tool, width, height, eraseHoverIds,
1077
1077
  d: liveStroke.d,
1078
1078
  fill: "none",
1079
1079
  stroke: "#7c3aed",
1080
- strokeWidth: 2.5,
1080
+ strokeWidth,
1081
1081
  strokeLinecap: "round",
1082
1082
  strokeLinejoin: "round",
1083
1083
  vectorEffect: "non-scaling-stroke",
@@ -1102,6 +1102,7 @@ function NumberLine({ className }) {
1102
1102
  groupSize,
1103
1103
  groupCount,
1104
1104
  tickStep,
1105
+ strokeWidth,
1105
1106
  arcColors,
1106
1107
  showGroupTicks,
1107
1108
  showMajorTicks,
@@ -1353,6 +1354,7 @@ function NumberLine({ className }) {
1353
1354
  tool,
1354
1355
  width: w,
1355
1356
  height: h,
1357
+ strokeWidth,
1356
1358
  eraseHoverIds,
1357
1359
  onStrokeClick
1358
1360
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcg-overseas/number-line",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.4",
4
4
  "description": "Interactive number line component with group arcs and freehand drawing",
5
5
  "type": "module",
6
6
  "license": "MIT",