number-flow-react-native 0.1.0
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/LICENSE +21 -0
- package/README.md +44 -0
- package/lib/module/core/constants.js +21 -0
- package/lib/module/core/constants.js.map +1 -0
- package/lib/module/core/intlHelpers.js +310 -0
- package/lib/module/core/intlHelpers.js.map +1 -0
- package/lib/module/core/layout.js +71 -0
- package/lib/module/core/layout.js.map +1 -0
- package/lib/module/core/mask.js +50 -0
- package/lib/module/core/mask.js.map +1 -0
- package/lib/module/core/numerals/detection.js +105 -0
- package/lib/module/core/numerals/detection.js.map +1 -0
- package/lib/module/core/numerals/digits.js +128 -0
- package/lib/module/core/numerals/digits.js.map +1 -0
- package/lib/module/core/numerals/index.js +5 -0
- package/lib/module/core/numerals/index.js.map +1 -0
- package/lib/module/core/numerals/tables.js +114 -0
- package/lib/module/core/numerals/tables.js.map +1 -0
- package/lib/module/core/superscript.js +31 -0
- package/lib/module/core/superscript.js.map +1 -0
- package/lib/module/core/timeLayout.js +98 -0
- package/lib/module/core/timeLayout.js.map +1 -0
- package/lib/module/core/timeTypes.js +4 -0
- package/lib/module/core/timeTypes.js.map +1 -0
- package/lib/module/core/timing.js +45 -0
- package/lib/module/core/timing.js.map +1 -0
- package/lib/module/core/types.js +58 -0
- package/lib/module/core/types.js.map +1 -0
- package/lib/module/core/useAccessibilityAnnouncement.js +27 -0
- package/lib/module/core/useAccessibilityAnnouncement.js.map +1 -0
- package/lib/module/core/useAnimatedX.js +25 -0
- package/lib/module/core/useAnimatedX.js.map +1 -0
- package/lib/module/core/useAnimationLifecycle.js +37 -0
- package/lib/module/core/useAnimationLifecycle.js.map +1 -0
- package/lib/module/core/useCanAnimate.js +22 -0
- package/lib/module/core/useCanAnimate.js.map +1 -0
- package/lib/module/core/useContinuousSpin.js +89 -0
- package/lib/module/core/useContinuousSpin.js.map +1 -0
- package/lib/module/core/useDebouncedWidths.js +74 -0
- package/lib/module/core/useDebouncedWidths.js.map +1 -0
- package/lib/module/core/useDigitAnimation.js +138 -0
- package/lib/module/core/useDigitAnimation.js.map +1 -0
- package/lib/module/core/useFlowPipeline.js +85 -0
- package/lib/module/core/useFlowPipeline.js.map +1 -0
- package/lib/module/core/useFormattedValue.js +28 -0
- package/lib/module/core/useFormattedValue.js.map +1 -0
- package/lib/module/core/useLayoutDiff.js +59 -0
- package/lib/module/core/useLayoutDiff.js.map +1 -0
- package/lib/module/core/useNumberFormatting.js +158 -0
- package/lib/module/core/useNumberFormatting.js.map +1 -0
- package/lib/module/core/useSlotOpacity.js +53 -0
- package/lib/module/core/useSlotOpacity.js.map +1 -0
- package/lib/module/core/useTimeFormatting.js +74 -0
- package/lib/module/core/useTimeFormatting.js.map +1 -0
- package/lib/module/core/useTimingResolution.js +21 -0
- package/lib/module/core/useTimingResolution.js.map +1 -0
- package/lib/module/core/useWorkletFormatting.js +49 -0
- package/lib/module/core/useWorkletFormatting.js.map +1 -0
- package/lib/module/core/utils.js +132 -0
- package/lib/module/core/utils.js.map +1 -0
- package/lib/module/core/warnings.js +10 -0
- package/lib/module/core/warnings.js.map +1 -0
- package/lib/module/index.js +7 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/native/DigitSlot.js +163 -0
- package/lib/module/native/DigitSlot.js.map +1 -0
- package/lib/module/native/NumberFlow.js +244 -0
- package/lib/module/native/NumberFlow.js.map +1 -0
- package/lib/module/native/SymbolSlot.js +52 -0
- package/lib/module/native/SymbolSlot.js.map +1 -0
- package/lib/module/native/TimeFlow.js +270 -0
- package/lib/module/native/TimeFlow.js.map +1 -0
- package/lib/module/native/index.js +5 -0
- package/lib/module/native/index.js.map +1 -0
- package/lib/module/native/renderSlots.js +108 -0
- package/lib/module/native/renderSlots.js.map +1 -0
- package/lib/module/native/types.js +4 -0
- package/lib/module/native/types.js.map +1 -0
- package/lib/module/native/useMeasuredGlyphMetrics.js +156 -0
- package/lib/module/native/useMeasuredGlyphMetrics.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/skia/DigitSlot.js +171 -0
- package/lib/module/skia/DigitSlot.js.map +1 -0
- package/lib/module/skia/SkiaNumberFlow.js +430 -0
- package/lib/module/skia/SkiaNumberFlow.js.map +1 -0
- package/lib/module/skia/SkiaTimeFlow.js +226 -0
- package/lib/module/skia/SkiaTimeFlow.js.map +1 -0
- package/lib/module/skia/SymbolSlot.js +92 -0
- package/lib/module/skia/SymbolSlot.js.map +1 -0
- package/lib/module/skia/index.js +6 -0
- package/lib/module/skia/index.js.map +1 -0
- package/lib/module/skia/renderSlots.js +131 -0
- package/lib/module/skia/renderSlots.js.map +1 -0
- package/lib/module/skia/useGlyphMetrics.js +72 -0
- package/lib/module/skia/useGlyphMetrics.js.map +1 -0
- package/lib/module/skia/useScrubbing.js +165 -0
- package/lib/module/skia/useScrubbing.js.map +1 -0
- package/lib/module/skia/useSkiaFont.js +23 -0
- package/lib/module/skia/useSkiaFont.js.map +1 -0
- package/lib/typescript/core/constants.d.ts +15 -0
- package/lib/typescript/core/constants.d.ts.map +1 -0
- package/lib/typescript/core/intlHelpers.d.ts +10 -0
- package/lib/typescript/core/intlHelpers.d.ts.map +1 -0
- package/lib/typescript/core/layout.d.ts +22 -0
- package/lib/typescript/core/layout.d.ts.map +1 -0
- package/lib/typescript/core/mask.d.ts +18 -0
- package/lib/typescript/core/mask.d.ts.map +1 -0
- package/lib/typescript/core/numerals/detection.d.ts +17 -0
- package/lib/typescript/core/numerals/detection.d.ts.map +1 -0
- package/lib/typescript/core/numerals/digits.d.ts +43 -0
- package/lib/typescript/core/numerals/digits.d.ts.map +1 -0
- package/lib/typescript/core/numerals/index.d.ts +3 -0
- package/lib/typescript/core/numerals/index.d.ts.map +1 -0
- package/lib/typescript/core/numerals/tables.d.ts +32 -0
- package/lib/typescript/core/numerals/tables.d.ts.map +1 -0
- package/lib/typescript/core/superscript.d.ts +16 -0
- package/lib/typescript/core/superscript.d.ts.map +1 -0
- package/lib/typescript/core/timeLayout.d.ts +19 -0
- package/lib/typescript/core/timeLayout.d.ts.map +1 -0
- package/lib/typescript/core/timeTypes.d.ts +80 -0
- package/lib/typescript/core/timeTypes.d.ts.map +1 -0
- package/lib/typescript/core/timing.d.ts +6 -0
- package/lib/typescript/core/timing.d.ts.map +1 -0
- package/lib/typescript/core/types.d.ts +165 -0
- package/lib/typescript/core/types.d.ts.map +1 -0
- package/lib/typescript/core/useAccessibilityAnnouncement.d.ts +10 -0
- package/lib/typescript/core/useAccessibilityAnnouncement.d.ts.map +1 -0
- package/lib/typescript/core/useAnimatedX.d.ts +9 -0
- package/lib/typescript/core/useAnimatedX.d.ts.map +1 -0
- package/lib/typescript/core/useAnimationLifecycle.d.ts +14 -0
- package/lib/typescript/core/useAnimationLifecycle.d.ts.map +1 -0
- package/lib/typescript/core/useCanAnimate.d.ts +14 -0
- package/lib/typescript/core/useCanAnimate.d.ts.map +1 -0
- package/lib/typescript/core/useContinuousSpin.d.ts +23 -0
- package/lib/typescript/core/useContinuousSpin.d.ts.map +1 -0
- package/lib/typescript/core/useDebouncedWidths.d.ts +17 -0
- package/lib/typescript/core/useDebouncedWidths.d.ts.map +1 -0
- package/lib/typescript/core/useDigitAnimation.d.ts +38 -0
- package/lib/typescript/core/useDigitAnimation.d.ts.map +1 -0
- package/lib/typescript/core/useFlowPipeline.d.ts +46 -0
- package/lib/typescript/core/useFlowPipeline.d.ts.map +1 -0
- package/lib/typescript/core/useFormattedValue.d.ts +14 -0
- package/lib/typescript/core/useFormattedValue.d.ts.map +1 -0
- package/lib/typescript/core/useLayoutDiff.d.ts +18 -0
- package/lib/typescript/core/useLayoutDiff.d.ts.map +1 -0
- package/lib/typescript/core/useNumberFormatting.d.ts +18 -0
- package/lib/typescript/core/useNumberFormatting.d.ts.map +1 -0
- package/lib/typescript/core/useSlotOpacity.d.ts +18 -0
- package/lib/typescript/core/useSlotOpacity.d.ts.map +1 -0
- package/lib/typescript/core/useTimeFormatting.d.ts +22 -0
- package/lib/typescript/core/useTimeFormatting.d.ts.map +1 -0
- package/lib/typescript/core/useTimingResolution.d.ts +13 -0
- package/lib/typescript/core/useTimingResolution.d.ts.map +1 -0
- package/lib/typescript/core/useWorkletFormatting.d.ts +14 -0
- package/lib/typescript/core/useWorkletFormatting.d.ts.map +1 -0
- package/lib/typescript/core/utils.d.ts +44 -0
- package/lib/typescript/core/utils.d.ts.map +1 -0
- package/lib/typescript/core/warnings.d.ts +2 -0
- package/lib/typescript/core/warnings.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +8 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/lib/typescript/native/DigitSlot.d.ts +27 -0
- package/lib/typescript/native/DigitSlot.d.ts.map +1 -0
- package/lib/typescript/native/NumberFlow.d.ts +3 -0
- package/lib/typescript/native/NumberFlow.d.ts.map +1 -0
- package/lib/typescript/native/SymbolSlot.d.ts +19 -0
- package/lib/typescript/native/SymbolSlot.d.ts.map +1 -0
- package/lib/typescript/native/TimeFlow.d.ts +3 -0
- package/lib/typescript/native/TimeFlow.d.ts.map +1 -0
- package/lib/typescript/native/index.d.ts +3 -0
- package/lib/typescript/native/index.d.ts.map +1 -0
- package/lib/typescript/native/renderSlots.d.ts +31 -0
- package/lib/typescript/native/renderSlots.d.ts.map +1 -0
- package/lib/typescript/native/types.d.ts +36 -0
- package/lib/typescript/native/types.d.ts.map +1 -0
- package/lib/typescript/native/useMeasuredGlyphMetrics.d.ts +8 -0
- package/lib/typescript/native/useMeasuredGlyphMetrics.d.ts.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/skia/DigitSlot.d.ts +35 -0
- package/lib/typescript/skia/DigitSlot.d.ts.map +1 -0
- package/lib/typescript/skia/SkiaNumberFlow.d.ts +3 -0
- package/lib/typescript/skia/SkiaNumberFlow.d.ts.map +1 -0
- package/lib/typescript/skia/SkiaTimeFlow.d.ts +3 -0
- package/lib/typescript/skia/SkiaTimeFlow.d.ts.map +1 -0
- package/lib/typescript/skia/SymbolSlot.d.ts +26 -0
- package/lib/typescript/skia/SymbolSlot.d.ts.map +1 -0
- package/lib/typescript/skia/index.d.ts +6 -0
- package/lib/typescript/skia/index.d.ts.map +1 -0
- package/lib/typescript/skia/renderSlots.d.ts +40 -0
- package/lib/typescript/skia/renderSlots.d.ts.map +1 -0
- package/lib/typescript/skia/useGlyphMetrics.d.ts +16 -0
- package/lib/typescript/skia/useGlyphMetrics.d.ts.map +1 -0
- package/lib/typescript/skia/useScrubbing.d.ts +59 -0
- package/lib/typescript/skia/useScrubbing.d.ts.map +1 -0
- package/lib/typescript/skia/useSkiaFont.d.ts +13 -0
- package/lib/typescript/skia/useSkiaFont.d.ts.map +1 -0
- package/package.json +104 -0
- package/src/core/constants.ts +20 -0
- package/src/core/intlHelpers.ts +351 -0
- package/src/core/layout.ts +108 -0
- package/src/core/mask.ts +72 -0
- package/src/core/numerals/detection.ts +112 -0
- package/src/core/numerals/digits.ts +102 -0
- package/src/core/numerals/index.ts +9 -0
- package/src/core/numerals/tables.ts +112 -0
- package/src/core/superscript.ts +27 -0
- package/src/core/timeLayout.ts +119 -0
- package/src/core/timeTypes.ts +88 -0
- package/src/core/timing.ts +60 -0
- package/src/core/types.ts +189 -0
- package/src/core/useAccessibilityAnnouncement.ts +27 -0
- package/src/core/useAnimatedX.ts +30 -0
- package/src/core/useAnimationLifecycle.ts +54 -0
- package/src/core/useCanAnimate.ts +21 -0
- package/src/core/useContinuousSpin.ts +112 -0
- package/src/core/useDebouncedWidths.ts +93 -0
- package/src/core/useDigitAnimation.ts +192 -0
- package/src/core/useFlowPipeline.ts +126 -0
- package/src/core/useFormattedValue.ts +32 -0
- package/src/core/useLayoutDiff.ts +71 -0
- package/src/core/useNumberFormatting.ts +164 -0
- package/src/core/useSlotOpacity.ts +66 -0
- package/src/core/useTimeFormatting.ts +95 -0
- package/src/core/useTimingResolution.ts +47 -0
- package/src/core/useWorkletFormatting.ts +59 -0
- package/src/core/utils.ts +149 -0
- package/src/core/warnings.ts +8 -0
- package/src/index.ts +15 -0
- package/src/native/DigitSlot.tsx +203 -0
- package/src/native/NumberFlow.tsx +287 -0
- package/src/native/SymbolSlot.tsx +68 -0
- package/src/native/TimeFlow.tsx +287 -0
- package/src/native/index.ts +2 -0
- package/src/native/renderSlots.tsx +150 -0
- package/src/native/types.ts +40 -0
- package/src/native/useMeasuredGlyphMetrics.tsx +205 -0
- package/src/skia/DigitSlot.tsx +221 -0
- package/src/skia/SkiaNumberFlow.tsx +506 -0
- package/src/skia/SkiaTimeFlow.tsx +257 -0
- package/src/skia/SymbolSlot.tsx +120 -0
- package/src/skia/index.ts +5 -0
- package/src/skia/renderSlots.tsx +180 -0
- package/src/skia/useGlyphMetrics.ts +79 -0
- package/src/skia/useScrubbing.ts +223 -0
- package/src/skia/useSkiaFont.ts +25 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Group, LinearGradient, Paint, Rect as SkiaRect, vec } from "@shopify/react-native-skia";
|
|
4
|
+
import { useMemo } from "react";
|
|
5
|
+
import { MASK_WIDTH_RATIO } from "../core/constants.js";
|
|
6
|
+
import { computeKeyedLayout } from "../core/layout.js";
|
|
7
|
+
import { computeTimeStringLayout } from "../core/timeLayout.js";
|
|
8
|
+
import { useAccessibilityAnnouncement } from "../core/useAccessibilityAnnouncement.js";
|
|
9
|
+
import { useFlowPipeline } from "../core/useFlowPipeline.js";
|
|
10
|
+
import { useTimeFormatting } from "../core/useTimeFormatting.js";
|
|
11
|
+
import { useWorkletFormatting } from "../core/useWorkletFormatting.js";
|
|
12
|
+
import { TIME_DIGIT_COUNTS } from "../core/utils.js";
|
|
13
|
+
import { warnOnce } from "../core/warnings.js";
|
|
14
|
+
import { renderSlots } from "./renderSlots.js";
|
|
15
|
+
import { useGlyphMetrics } from "./useGlyphMetrics.js";
|
|
16
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
17
|
+
export const SkiaTimeFlow = ({
|
|
18
|
+
hours,
|
|
19
|
+
minutes,
|
|
20
|
+
seconds,
|
|
21
|
+
timestamp,
|
|
22
|
+
timezoneOffset,
|
|
23
|
+
sharedValue,
|
|
24
|
+
is24Hour = true,
|
|
25
|
+
padHours = true,
|
|
26
|
+
font,
|
|
27
|
+
color = "#000000",
|
|
28
|
+
x = 0,
|
|
29
|
+
y = 0,
|
|
30
|
+
width = 0,
|
|
31
|
+
textAlign = "left",
|
|
32
|
+
opacity,
|
|
33
|
+
spinTiming,
|
|
34
|
+
opacityTiming,
|
|
35
|
+
transformTiming,
|
|
36
|
+
trend,
|
|
37
|
+
animated,
|
|
38
|
+
respectMotionPreference,
|
|
39
|
+
continuous,
|
|
40
|
+
mask,
|
|
41
|
+
onAnimationsStart,
|
|
42
|
+
onAnimationsFinish
|
|
43
|
+
}) => {
|
|
44
|
+
const metrics = useGlyphMetrics(font);
|
|
45
|
+
if (__DEV__) {
|
|
46
|
+
if (!font) {
|
|
47
|
+
warnOnce("skia-tf-font", "font is null — pass a loaded SkFont from useFont(). Component renders empty until font loads.");
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const resolved = useMemo(() => {
|
|
51
|
+
if (timestamp !== undefined) {
|
|
52
|
+
const d = new Date(timestamp + (timezoneOffset ?? 0));
|
|
53
|
+
return {
|
|
54
|
+
hours: d.getUTCHours(),
|
|
55
|
+
minutes: d.getUTCMinutes(),
|
|
56
|
+
seconds: d.getUTCSeconds()
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return {
|
|
60
|
+
hours,
|
|
61
|
+
minutes,
|
|
62
|
+
seconds
|
|
63
|
+
};
|
|
64
|
+
}, [timestamp, timezoneOffset, hours, minutes, seconds]);
|
|
65
|
+
const resolvedHours = resolved.hours;
|
|
66
|
+
const resolvedMinutes = resolved.minutes;
|
|
67
|
+
const resolvedSeconds = resolved.seconds;
|
|
68
|
+
const hasHours = resolvedHours !== undefined;
|
|
69
|
+
const hasSeconds = resolvedSeconds !== undefined;
|
|
70
|
+
if (__DEV__) {
|
|
71
|
+
if (resolvedHours !== undefined && (resolvedHours < 0 || resolvedHours > 23)) {
|
|
72
|
+
warnOnce("skia-tf-hours", "hours must be 0-23.");
|
|
73
|
+
}
|
|
74
|
+
if (resolvedMinutes !== undefined && (resolvedMinutes < 0 || resolvedMinutes > 59)) {
|
|
75
|
+
warnOnce("skia-tf-minutes", "minutes must be 0-59.");
|
|
76
|
+
}
|
|
77
|
+
if (resolvedSeconds !== undefined && (resolvedSeconds < 0 || resolvedSeconds > 59)) {
|
|
78
|
+
warnOnce("skia-tf-seconds", "seconds must be 0-59.");
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
const totalSeconds = (resolvedHours ?? 0) * 3600 + (resolvedMinutes ?? 0) * 60 + (resolvedSeconds ?? 0);
|
|
82
|
+
const keyedParts = useTimeFormatting(resolvedHours,
|
|
83
|
+
// Fallback for sharedValue mode where minutes is undefined (unused — layout comes from string path)
|
|
84
|
+
resolvedMinutes ?? 0, resolvedSeconds, is24Hour, padHours);
|
|
85
|
+
const workletDigitValues = useWorkletFormatting(sharedValue, "", "");
|
|
86
|
+
const layout = useMemo(() => {
|
|
87
|
+
if (!metrics) return [];
|
|
88
|
+
if (sharedValue && resolvedHours === undefined && resolvedMinutes === undefined) {
|
|
89
|
+
return computeTimeStringLayout(sharedValue.value, metrics, width, textAlign, hasHours, hasSeconds);
|
|
90
|
+
}
|
|
91
|
+
if (keyedParts.length === 0) return [];
|
|
92
|
+
return computeKeyedLayout(keyedParts, metrics, width, textAlign);
|
|
93
|
+
}, [metrics, keyedParts, width, textAlign, sharedValue, resolvedHours, resolvedMinutes, hasHours, hasSeconds]);
|
|
94
|
+
const pipeline = useFlowPipeline({
|
|
95
|
+
keyedParts,
|
|
96
|
+
trendValue: totalSeconds,
|
|
97
|
+
layout,
|
|
98
|
+
metrics,
|
|
99
|
+
animated,
|
|
100
|
+
respectMotionPreference,
|
|
101
|
+
spinTiming,
|
|
102
|
+
opacityTiming,
|
|
103
|
+
transformTiming,
|
|
104
|
+
trend,
|
|
105
|
+
continuous,
|
|
106
|
+
mask,
|
|
107
|
+
onAnimationsStart,
|
|
108
|
+
onAnimationsFinish
|
|
109
|
+
});
|
|
110
|
+
const {
|
|
111
|
+
resolvedSpinTiming,
|
|
112
|
+
resolvedOpacityTiming,
|
|
113
|
+
resolvedTransformTiming,
|
|
114
|
+
resolvedTrend,
|
|
115
|
+
spinGenerations,
|
|
116
|
+
prevMap,
|
|
117
|
+
isInitialRender,
|
|
118
|
+
exitingEntries,
|
|
119
|
+
onExitComplete,
|
|
120
|
+
accessibilityLabel,
|
|
121
|
+
adaptiveMask
|
|
122
|
+
} = pipeline;
|
|
123
|
+
useAccessibilityAnnouncement(accessibilityLabel);
|
|
124
|
+
if (!font || !metrics) {
|
|
125
|
+
return /*#__PURE__*/_jsx(Group, {});
|
|
126
|
+
}
|
|
127
|
+
if (layout.length === 0 && exitingEntries.size === 0) {
|
|
128
|
+
return /*#__PURE__*/_jsx(Group, {});
|
|
129
|
+
}
|
|
130
|
+
const baseY = y;
|
|
131
|
+
const resolvedMask = mask ?? true;
|
|
132
|
+
const maskTopHeight = resolvedMask ? adaptiveMask.top : 0;
|
|
133
|
+
const maskBottomHeight = resolvedMask ? adaptiveMask.bottom : 0;
|
|
134
|
+
const maskWidth = resolvedMask ? MASK_WIDTH_RATIO * metrics.lineHeight : 0;
|
|
135
|
+
|
|
136
|
+
// Content bounds from layout (in local coordinate space before translateX)
|
|
137
|
+
const contentLeft = layout.reduce((min, entry) => Math.min(min, entry.x), Infinity);
|
|
138
|
+
const contentRight = layout.reduce((max, entry) => Math.max(max, entry.x + entry.width), 0);
|
|
139
|
+
const contentWidth = layout.length > 0 ? contentRight - contentLeft : 0;
|
|
140
|
+
const content = /*#__PURE__*/_jsx(Group, {
|
|
141
|
+
transform: [{
|
|
142
|
+
translateX: x
|
|
143
|
+
}],
|
|
144
|
+
children: renderSlots({
|
|
145
|
+
layout,
|
|
146
|
+
exitingEntries,
|
|
147
|
+
prevMap,
|
|
148
|
+
isInitialRender,
|
|
149
|
+
onExitComplete,
|
|
150
|
+
metrics,
|
|
151
|
+
font,
|
|
152
|
+
color,
|
|
153
|
+
baseY,
|
|
154
|
+
resolvedTrend,
|
|
155
|
+
spinTiming: resolvedSpinTiming,
|
|
156
|
+
opacityTiming: resolvedOpacityTiming,
|
|
157
|
+
transformTiming: resolvedTransformTiming,
|
|
158
|
+
spinGenerations,
|
|
159
|
+
digitCountResolver: key => TIME_DIGIT_COUNTS[key],
|
|
160
|
+
maskTop: maskTopHeight,
|
|
161
|
+
maskBottom: maskBottomHeight,
|
|
162
|
+
workletDigitValues
|
|
163
|
+
})
|
|
164
|
+
});
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Container-level 2D gradient mask matching web NumberFlow's vignette.
|
|
168
|
+
* Horizontal: fade extends outside text edges (for enter/exit animations).
|
|
169
|
+
* Vertical: fade is within the text line height (digits roll through it).
|
|
170
|
+
* Two DstIn layers compose: final_alpha = content * h_alpha * v_alpha.
|
|
171
|
+
*/
|
|
172
|
+
const maskLeft = x + contentLeft - maskWidth;
|
|
173
|
+
const maskRight = x + contentRight + maskWidth;
|
|
174
|
+
const maskY = baseY + metrics.ascent;
|
|
175
|
+
const maskTotalWidth = contentWidth + 2 * maskWidth;
|
|
176
|
+
const maskTotalHeight = metrics.lineHeight;
|
|
177
|
+
const hRatio = maskTotalWidth > 0 ? maskWidth / maskTotalWidth : 0;
|
|
178
|
+
const vRatioTop = maskTotalHeight > 0 ? maskTopHeight / maskTotalHeight : 0;
|
|
179
|
+
const vRatioBottom = maskTotalHeight > 0 ? maskBottomHeight / maskTotalHeight : 0;
|
|
180
|
+
const maskedContent = resolvedMask ? /*#__PURE__*/_jsxs(Group, {
|
|
181
|
+
layer: /*#__PURE__*/_jsx(Paint, {}),
|
|
182
|
+
children: [content, /*#__PURE__*/_jsx(Group, {
|
|
183
|
+
layer: /*#__PURE__*/_jsx(Paint, {
|
|
184
|
+
blendMode: "dstIn"
|
|
185
|
+
}),
|
|
186
|
+
children: /*#__PURE__*/_jsx(SkiaRect, {
|
|
187
|
+
height: maskTotalHeight,
|
|
188
|
+
width: maskTotalWidth,
|
|
189
|
+
x: maskLeft,
|
|
190
|
+
y: maskY,
|
|
191
|
+
children: /*#__PURE__*/_jsx(LinearGradient, {
|
|
192
|
+
colors: ["transparent", "black", "black", "transparent"],
|
|
193
|
+
end: vec(maskRight, 0),
|
|
194
|
+
positions: [0, hRatio, 1 - hRatio, 1],
|
|
195
|
+
start: vec(maskLeft, 0)
|
|
196
|
+
})
|
|
197
|
+
})
|
|
198
|
+
}), /*#__PURE__*/_jsx(Group, {
|
|
199
|
+
layer: /*#__PURE__*/_jsx(Paint, {
|
|
200
|
+
blendMode: "dstIn"
|
|
201
|
+
}),
|
|
202
|
+
children: /*#__PURE__*/_jsx(SkiaRect, {
|
|
203
|
+
height: maskTotalHeight,
|
|
204
|
+
width: maskTotalWidth,
|
|
205
|
+
x: maskLeft,
|
|
206
|
+
y: maskY,
|
|
207
|
+
children: /*#__PURE__*/_jsx(LinearGradient, {
|
|
208
|
+
colors: ["transparent", "black", "black", "transparent"],
|
|
209
|
+
end: vec(0, maskY + maskTotalHeight),
|
|
210
|
+
positions: [0, vRatioTop, 1 - vRatioBottom, 1],
|
|
211
|
+
start: vec(0, maskY)
|
|
212
|
+
})
|
|
213
|
+
})
|
|
214
|
+
})]
|
|
215
|
+
}) : content;
|
|
216
|
+
if (opacity) {
|
|
217
|
+
return /*#__PURE__*/_jsx(Group, {
|
|
218
|
+
layer: /*#__PURE__*/_jsx(Paint, {
|
|
219
|
+
opacity: opacity
|
|
220
|
+
}),
|
|
221
|
+
children: maskedContent
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
return maskedContent;
|
|
225
|
+
};
|
|
226
|
+
//# sourceMappingURL=SkiaTimeFlow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Group","LinearGradient","Paint","Rect","SkiaRect","vec","useMemo","MASK_WIDTH_RATIO","computeKeyedLayout","computeTimeStringLayout","useAccessibilityAnnouncement","useFlowPipeline","useTimeFormatting","useWorkletFormatting","TIME_DIGIT_COUNTS","warnOnce","renderSlots","useGlyphMetrics","jsx","_jsx","jsxs","_jsxs","SkiaTimeFlow","hours","minutes","seconds","timestamp","timezoneOffset","sharedValue","is24Hour","padHours","font","color","x","y","width","textAlign","opacity","spinTiming","opacityTiming","transformTiming","trend","animated","respectMotionPreference","continuous","mask","onAnimationsStart","onAnimationsFinish","metrics","__DEV__","resolved","undefined","d","Date","getUTCHours","getUTCMinutes","getUTCSeconds","resolvedHours","resolvedMinutes","resolvedSeconds","hasHours","hasSeconds","totalSeconds","keyedParts","workletDigitValues","layout","value","length","pipeline","trendValue","resolvedSpinTiming","resolvedOpacityTiming","resolvedTransformTiming","resolvedTrend","spinGenerations","prevMap","isInitialRender","exitingEntries","onExitComplete","accessibilityLabel","adaptiveMask","size","baseY","resolvedMask","maskTopHeight","top","maskBottomHeight","bottom","maskWidth","lineHeight","contentLeft","reduce","min","entry","Math","Infinity","contentRight","max","contentWidth","content","transform","translateX","children","digitCountResolver","key","maskTop","maskBottom","maskLeft","maskRight","maskY","ascent","maskTotalWidth","maskTotalHeight","hRatio","vRatioTop","vRatioBottom","maskedContent","layer","blendMode","height","colors","end","positions","start"],"sourceRoot":"../../../src","sources":["skia/SkiaTimeFlow.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { Group, Paint, Text as SkiaText } from "@shopify/react-native-skia";
|
|
4
|
+
import React, { useMemo, useState } from "react";
|
|
5
|
+
import { Easing, makeMutable, useAnimatedReaction, useDerivedValue, withTiming } from "react-native-reanimated";
|
|
6
|
+
import { getSuperscriptTransform } from "../core/superscript.js";
|
|
7
|
+
import { useAnimatedX } from "../core/useAnimatedX.js";
|
|
8
|
+
import { useSlotOpacity } from "../core/useSlotOpacity.js";
|
|
9
|
+
|
|
10
|
+
// Timing for smooth prefix/suffix animation during scrubbing
|
|
11
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
12
|
+
const WORKLET_X_ANIMATION_MS = 150;
|
|
13
|
+
export const SymbolSlot = /*#__PURE__*/React.memo(({
|
|
14
|
+
char,
|
|
15
|
+
targetX,
|
|
16
|
+
baseY,
|
|
17
|
+
ascent,
|
|
18
|
+
color,
|
|
19
|
+
font,
|
|
20
|
+
opacityTiming,
|
|
21
|
+
transformTiming,
|
|
22
|
+
entering,
|
|
23
|
+
exiting,
|
|
24
|
+
exitKey,
|
|
25
|
+
onExitComplete,
|
|
26
|
+
workletLayout,
|
|
27
|
+
slotIndex,
|
|
28
|
+
superscript
|
|
29
|
+
}) => {
|
|
30
|
+
const slotOpacity = useSlotOpacity({
|
|
31
|
+
entering,
|
|
32
|
+
exiting,
|
|
33
|
+
opacityTiming,
|
|
34
|
+
exitKey,
|
|
35
|
+
onExitComplete
|
|
36
|
+
});
|
|
37
|
+
const animatedX = useAnimatedX(targetX, exiting, transformTiming);
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Animated X position (worklet-driven).
|
|
41
|
+
* Unlike digits (which need instant response for scrubbing),
|
|
42
|
+
* symbols (prefix/suffix) should animate smoothly when the layout
|
|
43
|
+
* shifts due to digit count changes. This prevents jarring jumps.
|
|
44
|
+
*/
|
|
45
|
+
const [workletAnimatedX] = useState(() => makeMutable(targetX));
|
|
46
|
+
useAnimatedReaction(() => {
|
|
47
|
+
const wl = workletLayout?.value;
|
|
48
|
+
if (wl && slotIndex !== undefined && slotIndex < wl.length) {
|
|
49
|
+
return wl[slotIndex].x;
|
|
50
|
+
}
|
|
51
|
+
return null;
|
|
52
|
+
}, (newX, prevX) => {
|
|
53
|
+
if (newX !== null && newX !== prevX) {
|
|
54
|
+
workletAnimatedX.value = withTiming(newX, {
|
|
55
|
+
duration: WORKLET_X_ANIMATION_MS,
|
|
56
|
+
easing: Easing.out(Easing.ease)
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const groupTransform = useDerivedValue(() => {
|
|
61
|
+
const wl = workletLayout?.value;
|
|
62
|
+
if (wl && slotIndex !== undefined && slotIndex < wl.length) {
|
|
63
|
+
return [{
|
|
64
|
+
translateX: workletAnimatedX.value
|
|
65
|
+
}];
|
|
66
|
+
}
|
|
67
|
+
return [{
|
|
68
|
+
translateX: animatedX.value
|
|
69
|
+
}];
|
|
70
|
+
});
|
|
71
|
+
const superscriptTransform = useMemo(() => superscript ? getSuperscriptTransform(baseY, ascent) : undefined, [superscript, baseY, ascent]);
|
|
72
|
+
const opacityPaint = useMemo(() => /*#__PURE__*/_jsx(Paint, {
|
|
73
|
+
opacity: slotOpacity
|
|
74
|
+
}), [slotOpacity]);
|
|
75
|
+
const textElement = /*#__PURE__*/_jsx(SkiaText, {
|
|
76
|
+
color: color,
|
|
77
|
+
font: font,
|
|
78
|
+
text: char,
|
|
79
|
+
x: 0,
|
|
80
|
+
y: baseY
|
|
81
|
+
});
|
|
82
|
+
return /*#__PURE__*/_jsx(Group, {
|
|
83
|
+
layer: opacityPaint,
|
|
84
|
+
transform: groupTransform,
|
|
85
|
+
children: superscriptTransform ? /*#__PURE__*/_jsx(Group, {
|
|
86
|
+
transform: superscriptTransform,
|
|
87
|
+
children: textElement
|
|
88
|
+
}) : textElement
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
SymbolSlot.displayName = "SymbolSlot";
|
|
92
|
+
//# sourceMappingURL=SymbolSlot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Group","Paint","Text","SkiaText","React","useMemo","useState","Easing","makeMutable","useAnimatedReaction","useDerivedValue","withTiming","getSuperscriptTransform","useAnimatedX","useSlotOpacity","jsx","_jsx","WORKLET_X_ANIMATION_MS","SymbolSlot","memo","char","targetX","baseY","ascent","color","font","opacityTiming","transformTiming","entering","exiting","exitKey","onExitComplete","workletLayout","slotIndex","superscript","slotOpacity","animatedX","workletAnimatedX","wl","value","undefined","length","x","newX","prevX","duration","easing","out","ease","groupTransform","translateX","superscriptTransform","opacityPaint","opacity","textElement","text","y","layer","transform","children","displayName"],"sourceRoot":"../../../src","sources":["skia/SymbolSlot.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["SkiaNumberFlow","SkiaTimeFlow","useSkiaFont"],"sourceRoot":"../../../src","sources":["skia/index.ts"],"mappings":";;AAAA,SAASA,cAAc,QAAQ,qBAAkB;AACjD,SAASC,YAAY,QAAQ,mBAAgB;AAC7C,SAASC,WAAW,QAAQ,kBAAe","ignoreList":[]}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { DigitSlot } from "./DigitSlot.js";
|
|
4
|
+
import { SymbolSlot } from "./SymbolSlot.js";
|
|
5
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
6
|
+
/**
|
|
7
|
+
* Renders the active and exiting digit/symbol slot tree for Skia.
|
|
8
|
+
*
|
|
9
|
+
* Shared between SkiaNumberFlow and SkiaTimeFlow. Behavioral differences:
|
|
10
|
+
* - `digitCountResolver`: NumberFlow uses getDigitCount, TimeFlow uses TIME_DIGIT_COUNTS
|
|
11
|
+
* - `digitStrings`: NumberFlow passes locale-specific digits, TimeFlow omits (Latin fallback)
|
|
12
|
+
* - `workletLayout`: NumberFlow passes for scrubbing positioning, TimeFlow omits
|
|
13
|
+
*/
|
|
14
|
+
export function renderSlots({
|
|
15
|
+
layout,
|
|
16
|
+
exitingEntries,
|
|
17
|
+
prevMap,
|
|
18
|
+
isInitialRender,
|
|
19
|
+
onExitComplete,
|
|
20
|
+
metrics,
|
|
21
|
+
font,
|
|
22
|
+
color,
|
|
23
|
+
baseY,
|
|
24
|
+
resolvedTrend,
|
|
25
|
+
spinTiming,
|
|
26
|
+
opacityTiming,
|
|
27
|
+
transformTiming,
|
|
28
|
+
spinGenerations,
|
|
29
|
+
digitCountResolver,
|
|
30
|
+
maskTop,
|
|
31
|
+
maskBottom,
|
|
32
|
+
digitStrings,
|
|
33
|
+
workletDigitValues,
|
|
34
|
+
workletLayout
|
|
35
|
+
}) {
|
|
36
|
+
let digitIndex = 0;
|
|
37
|
+
let slotIndex = 0;
|
|
38
|
+
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
39
|
+
children: [layout.map(entry => {
|
|
40
|
+
const isEntering = !isInitialRender && !prevMap.has(entry.key);
|
|
41
|
+
const currentSlotIndex = slotIndex++;
|
|
42
|
+
if (entry.isDigit) {
|
|
43
|
+
const wdv = workletDigitValues?.[digitIndex];
|
|
44
|
+
const digitCount = digitCountResolver(entry.key);
|
|
45
|
+
const spinGeneration = spinGenerations?.get(entry.key);
|
|
46
|
+
digitIndex++;
|
|
47
|
+
return /*#__PURE__*/_jsx(DigitSlot, {
|
|
48
|
+
baseY: baseY,
|
|
49
|
+
charWidth: entry.width,
|
|
50
|
+
color: color,
|
|
51
|
+
continuousSpinGeneration: spinGeneration,
|
|
52
|
+
digitCount: digitCount,
|
|
53
|
+
digitStrings: digitStrings,
|
|
54
|
+
digitValue: entry.digitValue,
|
|
55
|
+
entering: isEntering,
|
|
56
|
+
exiting: false,
|
|
57
|
+
font: font,
|
|
58
|
+
maskTop: maskTop,
|
|
59
|
+
maskBottom: maskBottom,
|
|
60
|
+
metrics: metrics,
|
|
61
|
+
opacityTiming: opacityTiming,
|
|
62
|
+
slotIndex: workletLayout ? currentSlotIndex : undefined,
|
|
63
|
+
spinTiming: spinTiming,
|
|
64
|
+
superscript: entry.superscript,
|
|
65
|
+
targetX: entry.x,
|
|
66
|
+
transformTiming: transformTiming,
|
|
67
|
+
trend: resolvedTrend,
|
|
68
|
+
workletDigitValue: wdv,
|
|
69
|
+
workletLayout: workletLayout
|
|
70
|
+
}, entry.key);
|
|
71
|
+
}
|
|
72
|
+
return /*#__PURE__*/_jsx(SymbolSlot, {
|
|
73
|
+
ascent: metrics.ascent,
|
|
74
|
+
baseY: baseY,
|
|
75
|
+
char: entry.char,
|
|
76
|
+
color: color,
|
|
77
|
+
entering: isEntering,
|
|
78
|
+
exiting: false,
|
|
79
|
+
font: font,
|
|
80
|
+
opacityTiming: opacityTiming,
|
|
81
|
+
slotIndex: workletLayout ? currentSlotIndex : undefined,
|
|
82
|
+
superscript: entry.superscript,
|
|
83
|
+
targetX: entry.x,
|
|
84
|
+
transformTiming: transformTiming,
|
|
85
|
+
workletLayout: workletLayout
|
|
86
|
+
}, entry.key);
|
|
87
|
+
}), Array.from(exitingEntries.entries()).map(([key, entry]) => {
|
|
88
|
+
if (entry.isDigit) {
|
|
89
|
+
const digitCount = digitCountResolver(key);
|
|
90
|
+
return /*#__PURE__*/_jsx(DigitSlot, {
|
|
91
|
+
baseY: baseY,
|
|
92
|
+
charWidth: entry.width,
|
|
93
|
+
color: color,
|
|
94
|
+
digitCount: digitCount,
|
|
95
|
+
digitStrings: digitStrings,
|
|
96
|
+
digitValue: entry.digitValue,
|
|
97
|
+
entering: false,
|
|
98
|
+
exitKey: key,
|
|
99
|
+
exiting: true,
|
|
100
|
+
font: font,
|
|
101
|
+
maskTop: maskTop,
|
|
102
|
+
maskBottom: maskBottom,
|
|
103
|
+
metrics: metrics,
|
|
104
|
+
onExitComplete: onExitComplete,
|
|
105
|
+
opacityTiming: opacityTiming,
|
|
106
|
+
spinTiming: spinTiming,
|
|
107
|
+
superscript: entry.superscript,
|
|
108
|
+
targetX: entry.x,
|
|
109
|
+
transformTiming: transformTiming,
|
|
110
|
+
trend: resolvedTrend
|
|
111
|
+
}, key);
|
|
112
|
+
}
|
|
113
|
+
return /*#__PURE__*/_jsx(SymbolSlot, {
|
|
114
|
+
ascent: metrics.ascent,
|
|
115
|
+
baseY: baseY,
|
|
116
|
+
char: entry.char,
|
|
117
|
+
color: color,
|
|
118
|
+
entering: false,
|
|
119
|
+
exitKey: key,
|
|
120
|
+
exiting: true,
|
|
121
|
+
font: font,
|
|
122
|
+
onExitComplete: onExitComplete,
|
|
123
|
+
opacityTiming: opacityTiming,
|
|
124
|
+
superscript: entry.superscript,
|
|
125
|
+
targetX: entry.x,
|
|
126
|
+
transformTiming: transformTiming
|
|
127
|
+
}, key);
|
|
128
|
+
})]
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=renderSlots.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["DigitSlot","SymbolSlot","jsx","_jsx","Fragment","_Fragment","jsxs","_jsxs","renderSlots","layout","exitingEntries","prevMap","isInitialRender","onExitComplete","metrics","font","color","baseY","resolvedTrend","spinTiming","opacityTiming","transformTiming","spinGenerations","digitCountResolver","maskTop","maskBottom","digitStrings","workletDigitValues","workletLayout","digitIndex","slotIndex","children","map","entry","isEntering","has","key","currentSlotIndex","isDigit","wdv","digitCount","spinGeneration","get","charWidth","width","continuousSpinGeneration","digitValue","entering","exiting","undefined","superscript","targetX","x","trend","workletDigitValue","ascent","char","Array","from","entries","exitKey"],"sourceRoot":"../../../src","sources":["skia/renderSlots.tsx"],"mappings":";;AAIA,SAASA,SAAS,QAAQ,gBAAa;AACvC,SAASC,UAAU,QAAQ,iBAAc;AAAC,SAAAC,GAAA,IAAAC,IAAA,EAAAC,QAAA,IAAAC,SAAA,EAAAC,IAAA,IAAAC,KAAA;AAyB1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,WAAWA,CAAC;EAC1BC,MAAM;EACNC,cAAc;EACdC,OAAO;EACPC,eAAe;EACfC,cAAc;EACdC,OAAO;EACPC,IAAI;EACJC,KAAK;EACLC,KAAK;EACLC,aAAa;EACbC,UAAU;EACVC,aAAa;EACbC,eAAe;EACfC,eAAe;EACfC,kBAAkB;EAClBC,OAAO;EACPC,UAAU;EACVC,YAAY;EACZC,kBAAkB;EAClBC;AACiB,CAAC,EAAE;EACpB,IAAIC,UAAU,GAAG,CAAC;EAClB,IAAIC,SAAS,GAAG,CAAC;EAEjB,oBACEvB,KAAA,CAAAF,SAAA;IAAA0B,QAAA,GAEGtB,MAAM,CAACuB,GAAG,CAAEC,KAAK,IAAK;MACrB,MAAMC,UAAU,GAAG,CAACtB,eAAe,IAAI,CAACD,OAAO,CAACwB,GAAG,CAACF,KAAK,CAACG,GAAG,CAAC;MAC9D,MAAMC,gBAAgB,GAAGP,SAAS,EAAE;MAEpC,IAAIG,KAAK,CAACK,OAAO,EAAE;QACjB,MAAMC,GAAG,GAAGZ,kBAAkB,GAAGE,UAAU,CAAC;QAC5C,MAAMW,UAAU,GAAGjB,kBAAkB,CAACU,KAAK,CAACG,GAAG,CAAC;QAChD,MAAMK,cAAc,GAAGnB,eAAe,EAAEoB,GAAG,CAACT,KAAK,CAACG,GAAG,CAAC;QAEtDP,UAAU,EAAE;QAEZ,oBACE1B,IAAA,CAACH,SAAS;UACRiB,KAAK,EAAEA,KAAM;UACb0B,SAAS,EAAEV,KAAK,CAACW,KAAM;UACvB5B,KAAK,EAAEA,KAAM;UACb6B,wBAAwB,EAAEJ,cAAe;UACzCD,UAAU,EAAEA,UAAW;UACvBd,YAAY,EAAEA,YAAa;UAC3BoB,UAAU,EAAEb,KAAK,CAACa,UAAW;UAC7BC,QAAQ,EAAEb,UAAW;UACrBc,OAAO,EAAE,KAAM;UACfjC,IAAI,EAAEA,IAAK;UAEXS,OAAO,EAAEA,OAAQ;UACjBC,UAAU,EAAEA,UAAW;UACvBX,OAAO,EAAEA,OAAQ;UACjBM,aAAa,EAAEA,aAAc;UAC7BU,SAAS,EAAEF,aAAa,GAAGS,gBAAgB,GAAGY,SAAU;UACxD9B,UAAU,EAAEA,UAAW;UACvB+B,WAAW,EAAEjB,KAAK,CAACiB,WAAY;UAC/BC,OAAO,EAAElB,KAAK,CAACmB,CAAE;UACjB/B,eAAe,EAAEA,eAAgB;UACjCgC,KAAK,EAAEnC,aAAc;UACrBoC,iBAAiB,EAAEf,GAAI;UACvBX,aAAa,EAAEA;QAAc,GAZxBK,KAAK,CAACG,GAaZ,CAAC;MAEN;MAEA,oBACEjC,IAAA,CAACF,UAAU;QACTsD,MAAM,EAAEzC,OAAO,CAACyC,MAAO;QACvBtC,KAAK,EAAEA,KAAM;QACbuC,IAAI,EAAEvB,KAAK,CAACuB,IAAK;QACjBxC,KAAK,EAAEA,KAAM;QACb+B,QAAQ,EAAEb,UAAW;QACrBc,OAAO,EAAE,KAAM;QACfjC,IAAI,EAAEA,IAAK;QAEXK,aAAa,EAAEA,aAAc;QAC7BU,SAAS,EAAEF,aAAa,GAAGS,gBAAgB,GAAGY,SAAU;QACxDC,WAAW,EAAEjB,KAAK,CAACiB,WAAY;QAC/BC,OAAO,EAAElB,KAAK,CAACmB,CAAE;QACjB/B,eAAe,EAAEA,eAAgB;QACjCO,aAAa,EAAEA;MAAc,GANxBK,KAAK,CAACG,GAOZ,CAAC;IAEN,CAAC,CAAC,EAGDqB,KAAK,CAACC,IAAI,CAAChD,cAAc,CAACiD,OAAO,CAAC,CAAC,CAAC,CAAC3B,GAAG,CAAC,CAAC,CAACI,GAAG,EAAEH,KAAK,CAAC,KAAK;MAC1D,IAAIA,KAAK,CAACK,OAAO,EAAE;QACjB,MAAME,UAAU,GAAGjB,kBAAkB,CAACa,GAAG,CAAC;QAE1C,oBACEjC,IAAA,CAACH,SAAS;UACRiB,KAAK,EAAEA,KAAM;UACb0B,SAAS,EAAEV,KAAK,CAACW,KAAM;UACvB5B,KAAK,EAAEA,KAAM;UACbwB,UAAU,EAAEA,UAAW;UACvBd,YAAY,EAAEA,YAAa;UAC3BoB,UAAU,EAAEb,KAAK,CAACa,UAAW;UAC7BC,QAAQ,EAAE,KAAM;UAChBa,OAAO,EAAExB,GAAI;UACbY,OAAO;UACPjC,IAAI,EAAEA,IAAK;UAEXS,OAAO,EAAEA,OAAQ;UACjBC,UAAU,EAAEA,UAAW;UACvBX,OAAO,EAAEA,OAAQ;UACjBD,cAAc,EAAEA,cAAe;UAC/BO,aAAa,EAAEA,aAAc;UAC7BD,UAAU,EAAEA,UAAW;UACvB+B,WAAW,EAAEjB,KAAK,CAACiB,WAAY;UAC/BC,OAAO,EAAElB,KAAK,CAACmB,CAAE;UACjB/B,eAAe,EAAEA,eAAgB;UACjCgC,KAAK,EAAEnC;QAAc,GAVhBkB,GAWN,CAAC;MAEN;MAEA,oBACEjC,IAAA,CAACF,UAAU;QACTsD,MAAM,EAAEzC,OAAO,CAACyC,MAAO;QACvBtC,KAAK,EAAEA,KAAM;QACbuC,IAAI,EAAEvB,KAAK,CAACuB,IAAK;QACjBxC,KAAK,EAAEA,KAAM;QACb+B,QAAQ,EAAE,KAAM;QAChBa,OAAO,EAAExB,GAAI;QACbY,OAAO;QACPjC,IAAI,EAAEA,IAAK;QAEXF,cAAc,EAAEA,cAAe;QAC/BO,aAAa,EAAEA,aAAc;QAC7B8B,WAAW,EAAEjB,KAAK,CAACiB,WAAY;QAC/BC,OAAO,EAAElB,KAAK,CAACmB,CAAE;QACjB/B,eAAe,EAAEA;MAAgB,GAL5Be,GAMN,CAAC;IAEN,CAAC,CAAC;EAAA,CACF,CAAC;AAEP","ignoreList":[]}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useMemo } from "react";
|
|
4
|
+
import { MEASURABLE_CHARS } from "../core/constants.js";
|
|
5
|
+
/**
|
|
6
|
+
* Pre-computes glyph width lookup table and line metrics from an SkFont.
|
|
7
|
+
* Runs once on font load. All measurements use advance widths (not bounding boxes)
|
|
8
|
+
* for correct text layout spacing.
|
|
9
|
+
*
|
|
10
|
+
* Digit slots use `maxDigitWidth` (the widest of 0-9) for the clip window
|
|
11
|
+
* so all 10 digit glyphs fit during rolling. Individual digit positions
|
|
12
|
+
* within the clip use proportional charWidths for natural spacing.
|
|
13
|
+
*
|
|
14
|
+
* @param font - The SkFont to measure
|
|
15
|
+
* @param additionalChars - Optional additional characters to measure (e.g., from prefix/suffix with diacritics)
|
|
16
|
+
*/
|
|
17
|
+
export function useGlyphMetrics(font, additionalChars, localeDigitStrings) {
|
|
18
|
+
return useMemo(() => {
|
|
19
|
+
if (!font) return null;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Combine base chars with any additional chars from prefix/suffix so
|
|
23
|
+
* diacritics and special characters get proper width measurements.
|
|
24
|
+
*/
|
|
25
|
+
let charsToMeasure = MEASURABLE_CHARS;
|
|
26
|
+
if (additionalChars) {
|
|
27
|
+
const uniqueAdditional = additionalChars.split("").filter(c => !MEASURABLE_CHARS.includes(c)).join("");
|
|
28
|
+
if (uniqueAdditional) {
|
|
29
|
+
charsToMeasure = MEASURABLE_CHARS + uniqueAdditional;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const glyphIDs = font.getGlyphIDs(charsToMeasure);
|
|
33
|
+
const widths = font.getGlyphWidths(glyphIDs);
|
|
34
|
+
const charWidths = {};
|
|
35
|
+
for (let i = 0; i < charsToMeasure.length; i++) {
|
|
36
|
+
charWidths[charsToMeasure[i]] = widths[i];
|
|
37
|
+
}
|
|
38
|
+
let maxDigitWidth = 0;
|
|
39
|
+
const digitChars = localeDigitStrings ?? Array.from({
|
|
40
|
+
length: 10
|
|
41
|
+
}, (_, d) => String(d));
|
|
42
|
+
for (const dc of digitChars) {
|
|
43
|
+
const w = charWidths[dc] ?? 0;
|
|
44
|
+
if (w > maxDigitWidth) maxDigitWidth = w;
|
|
45
|
+
}
|
|
46
|
+
const metrics = font.getMetrics();
|
|
47
|
+
// ascent is negative (above baseline), descent is positive (below baseline)
|
|
48
|
+
const lineHeight = Math.ceil(metrics.descent - metrics.ascent);
|
|
49
|
+
|
|
50
|
+
// Per-character tight vertical bounds from measureText SkRect.
|
|
51
|
+
// rect.y = top of glyph (negative = above baseline),
|
|
52
|
+
// rect.y + rect.height = bottom of glyph (positive = below baseline).
|
|
53
|
+
const charBounds = {};
|
|
54
|
+
for (let i = 0; i < charsToMeasure.length; i++) {
|
|
55
|
+
const char = charsToMeasure[i];
|
|
56
|
+
const rect = font.measureText(char);
|
|
57
|
+
charBounds[char] = {
|
|
58
|
+
top: rect.y,
|
|
59
|
+
bottom: rect.y + rect.height
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
charWidths,
|
|
64
|
+
maxDigitWidth,
|
|
65
|
+
lineHeight,
|
|
66
|
+
ascent: metrics.ascent,
|
|
67
|
+
descent: metrics.descent,
|
|
68
|
+
charBounds
|
|
69
|
+
};
|
|
70
|
+
}, [font, additionalChars, localeDigitStrings]);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=useGlyphMetrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useMemo","MEASURABLE_CHARS","useGlyphMetrics","font","additionalChars","localeDigitStrings","charsToMeasure","uniqueAdditional","split","filter","c","includes","join","glyphIDs","getGlyphIDs","widths","getGlyphWidths","charWidths","i","length","maxDigitWidth","digitChars","Array","from","_","d","String","dc","w","metrics","getMetrics","lineHeight","Math","ceil","descent","ascent","charBounds","char","rect","measureText","top","y","bottom","height"],"sourceRoot":"../../../src","sources":["skia/useGlyphMetrics.ts"],"mappings":";;AACA,SAASA,OAAO,QAAQ,OAAO;AAC/B,SAASC,gBAAgB,QAAQ,sBAAmB;AAGpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASC,eAAeA,CAC7BC,IAAmB,EACnBC,eAAwB,EACxBC,kBAA6B,EACR;EACrB,OAAOL,OAAO,CAAC,MAAM;IACnB,IAAI,CAACG,IAAI,EAAE,OAAO,IAAI;;IAEtB;AACJ;AACA;AACA;IACI,IAAIG,cAAc,GAAGL,gBAAgB;IACrC,IAAIG,eAAe,EAAE;MACnB,MAAMG,gBAAgB,GAAGH,eAAe,CACrCI,KAAK,CAAC,EAAE,CAAC,CACTC,MAAM,CAAEC,CAAC,IAAK,CAACT,gBAAgB,CAACU,QAAQ,CAACD,CAAC,CAAC,CAAC,CAC5CE,IAAI,CAAC,EAAE,CAAC;MACX,IAAIL,gBAAgB,EAAE;QACpBD,cAAc,GAAGL,gBAAgB,GAAGM,gBAAgB;MACtD;IACF;IAEA,MAAMM,QAAQ,GAAGV,IAAI,CAACW,WAAW,CAACR,cAAc,CAAC;IACjD,MAAMS,MAAM,GAAGZ,IAAI,CAACa,cAAc,CAACH,QAAQ,CAAC;IAE5C,MAAMI,UAAkC,GAAG,CAAC,CAAC;IAC7C,KAAK,IAAIC,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGZ,cAAc,CAACa,MAAM,EAAED,CAAC,EAAE,EAAE;MAC9CD,UAAU,CAACX,cAAc,CAACY,CAAC,CAAC,CAAC,GAAGH,MAAM,CAACG,CAAC,CAAC;IAC3C;IAEA,IAAIE,aAAa,GAAG,CAAC;IACrB,MAAMC,UAAU,GAAGhB,kBAAkB,IAAIiB,KAAK,CAACC,IAAI,CAAC;MAAEJ,MAAM,EAAE;IAAG,CAAC,EAAE,CAACK,CAAC,EAAEC,CAAC,KAAKC,MAAM,CAACD,CAAC,CAAC,CAAC;IACxF,KAAK,MAAME,EAAE,IAAIN,UAAU,EAAE;MAC3B,MAAMO,CAAC,GAAGX,UAAU,CAACU,EAAE,CAAC,IAAI,CAAC;MAC7B,IAAIC,CAAC,GAAGR,aAAa,EAAEA,aAAa,GAAGQ,CAAC;IAC1C;IAEA,MAAMC,OAAO,GAAG1B,IAAI,CAAC2B,UAAU,CAAC,CAAC;IACjC;IACA,MAAMC,UAAU,GAAGC,IAAI,CAACC,IAAI,CAACJ,OAAO,CAACK,OAAO,GAAGL,OAAO,CAACM,MAAM,CAAC;;IAE9D;IACA;IACA;IACA,MAAMC,UAA2D,GAAG,CAAC,CAAC;IACtE,KAAK,IAAIlB,CAAC,GAAG,CAAC,EAAEA,CAAC,GAAGZ,cAAc,CAACa,MAAM,EAAED,CAAC,EAAE,EAAE;MAC9C,MAAMmB,IAAI,GAAG/B,cAAc,CAACY,CAAC,CAAC;MAC9B,MAAMoB,IAAI,GAAGnC,IAAI,CAACoC,WAAW,CAACF,IAAI,CAAC;MACnCD,UAAU,CAACC,IAAI,CAAC,GAAG;QAAEG,GAAG,EAAEF,IAAI,CAACG,CAAC;QAAEC,MAAM,EAAEJ,IAAI,CAACG,CAAC,GAAGH,IAAI,CAACK;MAAO,CAAC;IAClE;IAEA,OAAO;MACL1B,UAAU;MACVG,aAAa;MACbW,UAAU;MACVI,MAAM,EAAEN,OAAO,CAACM,MAAM;MACtBD,OAAO,EAAEL,OAAO,CAACK,OAAO;MACxBE;IACF,CAAC;EACH,CAAC,EAAE,CAACjC,IAAI,EAAEC,eAAe,EAAEC,kBAAkB,CAAC,CAAC;AACjD","ignoreList":[]}
|