@dcg-overseas/number-line 0.1.22 → 0.1.24

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
@@ -492,8 +492,10 @@ function NumberLineProvider({
492
492
  }
493
493
  );
494
494
  }
495
+ const ARC_BASELINE_LIFT = 12;
495
496
  function buildArcPath({ x1, x2, y, rx, ry }) {
496
- return `M ${x1} ${y - 20} A ${rx} ${ry} 0 0 1 ${x2} ${y - 20}`;
497
+ const base = y - ARC_BASELINE_LIFT;
498
+ return `M ${x1} ${base} A ${rx} ${ry} 0 0 1 ${x2} ${base}`;
497
499
  }
498
500
  function computeLabelStep(containerWidth, range) {
499
501
  const maxLabels = Math.floor(containerWidth / 40);
@@ -552,8 +554,8 @@ const ARC_COLORS = [
552
554
  "#16a34a"
553
555
  ];
554
556
  const ARC_RY_RATIO = 0.9;
555
- const ARC_ANIMATION_STAGGER_MS = 400;
556
- const ARC_ANIMATION_DRAW_MS = 500;
557
+ const ARC_ANIMATION_STAGGER_MS = 700;
558
+ const ARC_ANIMATION_DRAW_MS = 800;
557
559
  function gcd(a, b) {
558
560
  let x = Math.max(1, Math.abs(Math.round(a)));
559
561
  let y = Math.max(1, Math.abs(Math.round(b)));
@@ -587,6 +589,7 @@ const AxisLayer = React.memo(function AxisLayer2({
587
589
  const rawLabelStep = computeLabelStep(containerWidth, range);
588
590
  const labelStep = Math.max(step, Math.ceil(rawLabelStep / step) * step);
589
591
  const minorStep = showMinorTicks ? computeMinorTickStep(step, containerWidth, range) : 0;
592
+ const halfTickOffset = minorStep > 0 && step === minorStep * 10 ? step / 2 : 0;
590
593
  const MAX_TICKS = 500;
591
594
  const capStep = Math.max(1, Math.ceil(range / MAX_TICKS));
592
595
  const visibleStep = groupSize > 0 ? gcd(step, groupSize) : step;
@@ -623,6 +626,7 @@ const AxisLayer = React.memo(function AxisLayer2({
623
626
  if (!visible) return null;
624
627
  const renderAsGroup = groupActive;
625
628
  const renderAsMajor = !renderAsGroup && majorActive;
629
+ const renderAsHalf = !renderAsGroup && !renderAsMajor && halfTickOffset > 0 && Math.abs(offset % step - halfTickOffset) < 1e-9;
626
630
  const showLabel = (renderAsGroup || renderAsMajor) && offset % labelStep === 0;
627
631
  const currentShowLabelStep = typeof getShowLabelStep !== "function" ? false : getShowLabelStep == null ? void 0 : getShowLabelStep({
628
632
  viewMin,
@@ -632,9 +636,9 @@ const AxisLayer = React.memo(function AxisLayer2({
632
636
  length,
633
637
  v
634
638
  });
635
- const tickH = renderAsGroup ? 7 : renderAsMajor ? 10 : 6;
636
- const strokeW = renderAsGroup ? 4 : renderAsMajor ? 2 : 1;
637
- const color = renderAsGroup || renderAsMajor ? "#374151" : "#4b5563";
639
+ const tickH = renderAsGroup ? 7 : renderAsMajor ? 10 : renderAsHalf ? 8 : 6;
640
+ const strokeW = renderAsGroup ? 4 : renderAsMajor ? 2 : renderAsHalf ? 2 : 1;
641
+ const color = renderAsGroup || renderAsMajor || renderAsHalf ? "#374151" : "#4b5563";
638
642
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { children: [
639
643
  /* @__PURE__ */ jsxRuntime.jsx(
640
644
  "line",
@@ -693,6 +697,7 @@ function AnimatedArc({
693
697
  const strokeColor = isSelected ? "#1d4ed8" : color;
694
698
  const arrowHeadH = 7;
695
699
  const arrowHeadHW = 4;
700
+ const tipY = axisY - ARC_BASELINE_LIFT + 4;
696
701
  React.useLayoutEffect(() => {
697
702
  var _a;
698
703
  const len = ((_a = measureRef.current) == null ? void 0 : _a.getTotalLength()) ?? 0;
@@ -803,11 +808,14 @@ function AnimatedArc({
803
808
  x: x2,
804
809
  y: textY,
805
810
  textAnchor: edgeTextAnchor(),
806
- fontSize: 14,
811
+ fontSize: 16,
807
812
  fill: strokeColor,
808
813
  fontWeight: "600",
809
814
  pointerEvents: "none",
810
- style: { userSelect: "none", WebkitUserSelect: "none" },
815
+ style: {
816
+ userSelect: "none",
817
+ WebkitUserSelect: "none"
818
+ },
811
819
  children: end
812
820
  }
813
821
  ),
@@ -817,7 +825,7 @@ function AnimatedArc({
817
825
  x1: x2,
818
826
  y1: textY + 5,
819
827
  x2,
820
- y2: axisY - arrowHeadH - 10,
828
+ y2: tipY - arrowHeadH,
821
829
  stroke: strokeColor,
822
830
  strokeWidth: 1.5,
823
831
  pointerEvents: "none"
@@ -826,7 +834,7 @@ function AnimatedArc({
826
834
  /* @__PURE__ */ jsxRuntime.jsx(
827
835
  "polygon",
828
836
  {
829
- points: `${x2},${axisY - 16} ${x2 - arrowHeadHW},${axisY - arrowHeadH - 16} ${x2 + arrowHeadHW},${axisY - arrowHeadH - 16}`,
837
+ points: `${x2},${tipY} ${x2 - arrowHeadHW},${tipY - arrowHeadH} ${x2 + arrowHeadHW},${tipY - arrowHeadH}`,
830
838
  fill: strokeColor,
831
839
  pointerEvents: "none"
832
840
  }
@@ -869,7 +877,10 @@ const GroupArcsLayer = React.memo(function GroupArcsLayer2({
869
877
  const ry = Math.min(rx * ARC_RY_RATIO, arcMaxHeight);
870
878
  const color = arcColors[g % arcColors.length];
871
879
  const MIN_ARROW_SPAN = 24;
872
- const textY = Math.min(axisY - ry - 26, axisY - MIN_ARROW_SPAN);
880
+ const textY = Math.min(
881
+ axisY - ry - ARC_BASELINE_LIFT - 6,
882
+ axisY - MIN_ARROW_SPAN
883
+ );
873
884
  const arcPath = buildArcPath({ x1, x2, y: axisY, rx, ry });
874
885
  const isSelected = selectedArcIndices.has(g);
875
886
  const hitCursor = tool === "eraser" ? "cell" : tool === "none" ? "pointer" : "default";
@@ -969,7 +980,7 @@ function DrawingLayer({ strokes, liveStroke, tool, width, height, onStrokeClick
969
980
  ] });
970
981
  }
971
982
  const LABEL_SPACE_BELOW_AXIS = 42;
972
- const LABEL_ABOVE_AXIS_SLOP = 38;
983
+ const LABEL_ABOVE_AXIS_SLOP = 30;
973
984
  const ARC_TOP_PADDING = 16;
974
985
  const MIN_ARC_HEIGHT = 24;
975
986
  function NumberLine({ className }) {
package/dist/index.js CHANGED
@@ -490,8 +490,10 @@ function NumberLineProvider({
490
490
  }
491
491
  );
492
492
  }
493
+ const ARC_BASELINE_LIFT = 12;
493
494
  function buildArcPath({ x1, x2, y, rx, ry }) {
494
- return `M ${x1} ${y - 20} A ${rx} ${ry} 0 0 1 ${x2} ${y - 20}`;
495
+ const base = y - ARC_BASELINE_LIFT;
496
+ return `M ${x1} ${base} A ${rx} ${ry} 0 0 1 ${x2} ${base}`;
495
497
  }
496
498
  function computeLabelStep(containerWidth, range) {
497
499
  const maxLabels = Math.floor(containerWidth / 40);
@@ -550,8 +552,8 @@ const ARC_COLORS = [
550
552
  "#16a34a"
551
553
  ];
552
554
  const ARC_RY_RATIO = 0.9;
553
- const ARC_ANIMATION_STAGGER_MS = 400;
554
- const ARC_ANIMATION_DRAW_MS = 500;
555
+ const ARC_ANIMATION_STAGGER_MS = 700;
556
+ const ARC_ANIMATION_DRAW_MS = 800;
555
557
  function gcd(a, b) {
556
558
  let x = Math.max(1, Math.abs(Math.round(a)));
557
559
  let y = Math.max(1, Math.abs(Math.round(b)));
@@ -585,6 +587,7 @@ const AxisLayer = React.memo(function AxisLayer2({
585
587
  const rawLabelStep = computeLabelStep(containerWidth, range);
586
588
  const labelStep = Math.max(step, Math.ceil(rawLabelStep / step) * step);
587
589
  const minorStep = showMinorTicks ? computeMinorTickStep(step, containerWidth, range) : 0;
590
+ const halfTickOffset = minorStep > 0 && step === minorStep * 10 ? step / 2 : 0;
588
591
  const MAX_TICKS = 500;
589
592
  const capStep = Math.max(1, Math.ceil(range / MAX_TICKS));
590
593
  const visibleStep = groupSize > 0 ? gcd(step, groupSize) : step;
@@ -621,6 +624,7 @@ const AxisLayer = React.memo(function AxisLayer2({
621
624
  if (!visible) return null;
622
625
  const renderAsGroup = groupActive;
623
626
  const renderAsMajor = !renderAsGroup && majorActive;
627
+ const renderAsHalf = !renderAsGroup && !renderAsMajor && halfTickOffset > 0 && Math.abs(offset % step - halfTickOffset) < 1e-9;
624
628
  const showLabel = (renderAsGroup || renderAsMajor) && offset % labelStep === 0;
625
629
  const currentShowLabelStep = typeof getShowLabelStep !== "function" ? false : getShowLabelStep == null ? void 0 : getShowLabelStep({
626
630
  viewMin,
@@ -630,9 +634,9 @@ const AxisLayer = React.memo(function AxisLayer2({
630
634
  length,
631
635
  v
632
636
  });
633
- const tickH = renderAsGroup ? 7 : renderAsMajor ? 10 : 6;
634
- const strokeW = renderAsGroup ? 4 : renderAsMajor ? 2 : 1;
635
- const color = renderAsGroup || renderAsMajor ? "#374151" : "#4b5563";
637
+ const tickH = renderAsGroup ? 7 : renderAsMajor ? 10 : renderAsHalf ? 8 : 6;
638
+ const strokeW = renderAsGroup ? 4 : renderAsMajor ? 2 : renderAsHalf ? 2 : 1;
639
+ const color = renderAsGroup || renderAsMajor || renderAsHalf ? "#374151" : "#4b5563";
636
640
  return /* @__PURE__ */ jsxs("g", { children: [
637
641
  /* @__PURE__ */ jsx(
638
642
  "line",
@@ -691,6 +695,7 @@ function AnimatedArc({
691
695
  const strokeColor = isSelected ? "#1d4ed8" : color;
692
696
  const arrowHeadH = 7;
693
697
  const arrowHeadHW = 4;
698
+ const tipY = axisY - ARC_BASELINE_LIFT + 4;
694
699
  useLayoutEffect(() => {
695
700
  var _a;
696
701
  const len = ((_a = measureRef.current) == null ? void 0 : _a.getTotalLength()) ?? 0;
@@ -801,11 +806,14 @@ function AnimatedArc({
801
806
  x: x2,
802
807
  y: textY,
803
808
  textAnchor: edgeTextAnchor(),
804
- fontSize: 14,
809
+ fontSize: 16,
805
810
  fill: strokeColor,
806
811
  fontWeight: "600",
807
812
  pointerEvents: "none",
808
- style: { userSelect: "none", WebkitUserSelect: "none" },
813
+ style: {
814
+ userSelect: "none",
815
+ WebkitUserSelect: "none"
816
+ },
809
817
  children: end
810
818
  }
811
819
  ),
@@ -815,7 +823,7 @@ function AnimatedArc({
815
823
  x1: x2,
816
824
  y1: textY + 5,
817
825
  x2,
818
- y2: axisY - arrowHeadH - 10,
826
+ y2: tipY - arrowHeadH,
819
827
  stroke: strokeColor,
820
828
  strokeWidth: 1.5,
821
829
  pointerEvents: "none"
@@ -824,7 +832,7 @@ function AnimatedArc({
824
832
  /* @__PURE__ */ jsx(
825
833
  "polygon",
826
834
  {
827
- points: `${x2},${axisY - 16} ${x2 - arrowHeadHW},${axisY - arrowHeadH - 16} ${x2 + arrowHeadHW},${axisY - arrowHeadH - 16}`,
835
+ points: `${x2},${tipY} ${x2 - arrowHeadHW},${tipY - arrowHeadH} ${x2 + arrowHeadHW},${tipY - arrowHeadH}`,
828
836
  fill: strokeColor,
829
837
  pointerEvents: "none"
830
838
  }
@@ -867,7 +875,10 @@ const GroupArcsLayer = memo(function GroupArcsLayer2({
867
875
  const ry = Math.min(rx * ARC_RY_RATIO, arcMaxHeight);
868
876
  const color = arcColors[g % arcColors.length];
869
877
  const MIN_ARROW_SPAN = 24;
870
- const textY = Math.min(axisY - ry - 26, axisY - MIN_ARROW_SPAN);
878
+ const textY = Math.min(
879
+ axisY - ry - ARC_BASELINE_LIFT - 6,
880
+ axisY - MIN_ARROW_SPAN
881
+ );
871
882
  const arcPath = buildArcPath({ x1, x2, y: axisY, rx, ry });
872
883
  const isSelected = selectedArcIndices.has(g);
873
884
  const hitCursor = tool === "eraser" ? "cell" : tool === "none" ? "pointer" : "default";
@@ -967,7 +978,7 @@ function DrawingLayer({ strokes, liveStroke, tool, width, height, onStrokeClick
967
978
  ] });
968
979
  }
969
980
  const LABEL_SPACE_BELOW_AXIS = 42;
970
- const LABEL_ABOVE_AXIS_SLOP = 38;
981
+ const LABEL_ABOVE_AXIS_SLOP = 30;
971
982
  const ARC_TOP_PADDING = 16;
972
983
  const MIN_ARC_HEIGHT = 24;
973
984
  function NumberLine({ className }) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dcg-overseas/number-line",
3
- "version": "0.1.22",
3
+ "version": "0.1.24",
4
4
  "description": "Interactive number line component with group arcs and freehand drawing",
5
5
  "type": "module",
6
6
  "license": "MIT",