react-native-vroom-chart 0.13.0 → 0.14.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/android/CMakeLists.txt +8 -0
- package/android/README.md +11 -10
- package/cpp/VroomChartHostObject.cpp +155 -54
- package/cpp/VroomChartHostObject.h +1 -1
- package/cpp/VroomJsiInstaller.cpp +1 -1
- package/cpp/_core_include/vroom/vroom_chart.h +6 -7
- package/cpp/_core_src/candles.h +7 -5
- package/cpp/_core_src/chart.cpp +271 -152
- package/cpp/_core_src/chart.h +6 -3
- package/cpp/_core_src/chart_facade.cpp +5 -1
- package/cpp/_core_src/viewport.h +4 -0
- package/lib/index.d.mts +52 -6
- package/lib/index.d.ts +52 -6
- package/lib/index.js +68 -36
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +77 -38
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/VroomChart.tsx +94 -44
- package/src/index.ts +2 -0
- package/src/jsi.d.ts +18 -17
- package/src/types.ts +2 -0
- package/src/useChartCore.ts +11 -7
package/lib/index.d.ts
CHANGED
|
@@ -187,6 +187,13 @@ type ChartType = 'candles' | 'line';
|
|
|
187
187
|
* Defaults to `'ease-in-out'`.
|
|
188
188
|
*/
|
|
189
189
|
type TransitionEasing = 'linear' | 'ease-in' | 'ease-out' | 'ease-in-out';
|
|
190
|
+
/**
|
|
191
|
+
* How a same-asset interval switch animates. `'transform'` (default) lerps
|
|
192
|
+
* each visible column into its counterpart. `'fade'` fades the old scene out
|
|
193
|
+
* then the new one in — use when the two windows don’t share a 1:1 pairing
|
|
194
|
+
* (e.g. a fixed lookback).
|
|
195
|
+
*/
|
|
196
|
+
type IntervalTransition = 'transform' | 'fade';
|
|
190
197
|
/** Active drawing tool while in `draw` mode. `null` draws nothing. */
|
|
191
198
|
type DrawTool = null | 'line' | 'box' | 'pencil' | 'path';
|
|
192
199
|
/** A drawing anchor in data space, so it stays glued to the candles on pan/zoom. */
|
|
@@ -200,9 +207,12 @@ type DrawPoint = {
|
|
|
200
207
|
type DrawingBase = {
|
|
201
208
|
/** Stable unique id (the chart generates one for drawings it creates). */
|
|
202
209
|
id: string;
|
|
203
|
-
/**
|
|
210
|
+
/**
|
|
211
|
+
* Stroke color (hex string or packed ARGB number). New drawings take
|
|
212
|
+
* `drawingStyle.color` when set; otherwise `#ff2962ff`.
|
|
213
|
+
*/
|
|
204
214
|
color?: VroomColor;
|
|
205
|
-
/** Stroke width in px.
|
|
215
|
+
/** Stroke width in px. New drawings take `drawingStyle.width` when set; otherwise 2. */
|
|
206
216
|
width?: number;
|
|
207
217
|
/**
|
|
208
218
|
* Protect the drawing from editing. A locked drawing still renders and can
|
|
@@ -295,6 +305,29 @@ type DrawingStyle = {
|
|
|
295
305
|
fill?: VroomColor;
|
|
296
306
|
locked?: boolean;
|
|
297
307
|
};
|
|
308
|
+
/**
|
|
309
|
+
* Default appearance for drawings the user creates — the live draft and the
|
|
310
|
+
* object handed to `onDrawingComplete`. Paste copies the source drawing's
|
|
311
|
+
* style instead of this default.
|
|
312
|
+
*
|
|
313
|
+
* Omitted fields keep the library defaults: a 2px `#ff2962ff` stroke, and for
|
|
314
|
+
* boxes a 10% tint of the stroke as fill.
|
|
315
|
+
*
|
|
316
|
+
* Prefer 6-digit hex for `color` (`'#00FFFF'`). vroom treats that as opaque,
|
|
317
|
+
* and CSS swatches preview it correctly. 8-digit hex is `#aarrggbb`, not CSS
|
|
318
|
+
* `#rrggbbaa`.
|
|
319
|
+
*/
|
|
320
|
+
type DefaultDrawingStyle = {
|
|
321
|
+
/** Stroke color, used for the live draft and stamped onto the committed drawing. */
|
|
322
|
+
color?: VroomColor;
|
|
323
|
+
/** Stroke width in px. Default 2. */
|
|
324
|
+
width?: number;
|
|
325
|
+
/**
|
|
326
|
+
* Box interior fill. Omitted, new boxes keep the default 10% stroke tint.
|
|
327
|
+
* Ignored by line, pencil, and path.
|
|
328
|
+
*/
|
|
329
|
+
fill?: VroomColor;
|
|
330
|
+
};
|
|
298
331
|
/**
|
|
299
332
|
* Storage adapter for **managed** drawing persistence. Provide it via the
|
|
300
333
|
* `drawingStore` prop and the chart owns the drawings array itself — loading and
|
|
@@ -720,16 +753,23 @@ type VroomChartCoreProps = {
|
|
|
720
753
|
chartType?: ChartType;
|
|
721
754
|
/**
|
|
722
755
|
* Duration (ms) of the animated transitions: the candle↔line switch when
|
|
723
|
-
* `chartType` changes, and the
|
|
756
|
+
* `chartType` changes, and the interval switch when the `candles` array is
|
|
724
757
|
* swapped for a different interval of the same asset. Default ~300. `0` snaps
|
|
725
|
-
* instantly. Ignored (snaps) when the OS requests reduced motion
|
|
726
|
-
* instead uses a plain cross-fade.
|
|
758
|
+
* instantly. Ignored (snaps) when the OS requests reduced motion.
|
|
727
759
|
*/
|
|
728
760
|
transitionMs?: number;
|
|
729
761
|
/**
|
|
730
762
|
* Easing curve applied to those transitions. Default `'ease-in-out'`.
|
|
731
763
|
*/
|
|
732
764
|
transitionEasing?: TransitionEasing;
|
|
765
|
+
/**
|
|
766
|
+
* How a same-asset interval switch animates. `'transform'` (default) lerps
|
|
767
|
+
* each visible column into its counterpart. `'fade'` fades the old scene out
|
|
768
|
+
* then the new one in — use when the two windows don’t share a 1:1 pairing
|
|
769
|
+
* (e.g. a fixed lookback). Same duration/easing as `transitionMs`. Reduced
|
|
770
|
+
* motion still snaps.
|
|
771
|
+
*/
|
|
772
|
+
intervalTransition?: IntervalTransition;
|
|
733
773
|
theme?: VroomTheme;
|
|
734
774
|
/** RSI indicator (pane below the candles). Omit/disable to hide it. */
|
|
735
775
|
rsi?: RSIConfig;
|
|
@@ -802,6 +842,12 @@ type VroomChartCoreProps = {
|
|
|
802
842
|
mode?: ChartMode;
|
|
803
843
|
/** Active drawing tool while in `draw` mode. Default `null` (draws nothing). */
|
|
804
844
|
tool?: DrawTool;
|
|
845
|
+
/**
|
|
846
|
+
* Default appearance for drawings the user creates (live draft + the object
|
|
847
|
+
* handed to `onDrawingComplete`). Paste copies the source drawing's style
|
|
848
|
+
* instead of this. Omitted fields keep the library defaults.
|
|
849
|
+
*/
|
|
850
|
+
drawingStyle?: DefaultDrawingStyle;
|
|
805
851
|
/**
|
|
806
852
|
* Committed drawings to render, anchored to data so they track the candles on
|
|
807
853
|
* pan/zoom. This is a controlled prop: append the value the chart hands you in
|
|
@@ -945,4 +991,4 @@ declare function classifyTransition(prev: Candle[] | null, next: Candle[], serie
|
|
|
945
991
|
*/
|
|
946
992
|
declare function timeframeWindow(oldWindow: VisibleRange, oldStepMs: number, oldLastMs: number, newStepMs: number, newLastMs: number): VisibleRange;
|
|
947
993
|
|
|
948
|
-
export { type BollingerBandsConfig, type Candle, type ChartType, type CrosshairEvent, type DataTransition, type MACDConfig, type MAKind, type MASource, type MovingAverageOverlay, type PriceLine, type PriceLinesStyle, type RSIConfig, type TransitionEasing, type VWAPConfig, type VisibleRange, type VolumeConfig, VroomChart, type VroomChartProps, type VroomColor, type VroomTheme, classifyTransition, inferStepMs, timeframeWindow };
|
|
994
|
+
export { type BollingerBandsConfig, type Candle, type ChartType, type CrosshairEvent, type DataTransition, type DefaultDrawingStyle, type IntervalTransition, type MACDConfig, type MAKind, type MASource, type MovingAverageOverlay, type PriceLine, type PriceLinesStyle, type RSIConfig, type TransitionEasing, type VWAPConfig, type VisibleRange, type VolumeConfig, VroomChart, type VroomChartProps, type VroomColor, type VroomTheme, classifyTransition, inferStepMs, timeframeWindow };
|
package/lib/index.js
CHANGED
|
@@ -384,11 +384,12 @@ function useChartCore(candles, size, visibleRange, defaultCandleWidth, chartType
|
|
|
384
384
|
ensureInstalled();
|
|
385
385
|
handleRef.current = globalThis.VroomChartJSI.create();
|
|
386
386
|
}
|
|
387
|
-
const animRef = (0, import_react.useRef)({ ms: 300, easing: void 0, reduceMotion: false });
|
|
387
|
+
const animRef = (0, import_react.useRef)({ ms: 300, easing: void 0, reduceMotion: false, interval: "transform" });
|
|
388
388
|
animRef.current = {
|
|
389
389
|
ms: Math.max(0, transition?.transitionMs ?? 300),
|
|
390
390
|
easing: transition?.transitionEasing,
|
|
391
|
-
reduceMotion: transition?.reduceMotion ?? false
|
|
391
|
+
reduceMotion: transition?.reduceMotion ?? false,
|
|
392
|
+
interval: transition?.intervalTransition === "fade" ? "fade" : "transform"
|
|
392
393
|
};
|
|
393
394
|
const onFrameRef = (0, import_react.useRef)(transition?.onFrame);
|
|
394
395
|
onFrameRef.current = transition?.onFrame;
|
|
@@ -461,7 +462,7 @@ function useChartCore(candles, size, visibleRange, defaultCandleWidth, chartType
|
|
|
461
462
|
morphing = animRef.current.ms > 0 && !animRef.current.reduceMotion && onFrameRef.current != null;
|
|
462
463
|
if (morphing) {
|
|
463
464
|
endIntervalMorph();
|
|
464
|
-
h.beginIntervalMorph();
|
|
465
|
+
h.beginIntervalMorph(animRef.current.interval);
|
|
465
466
|
}
|
|
466
467
|
} else if (transitionKind === "initial" || transitionKind === "reset") {
|
|
467
468
|
endIntervalMorph();
|
|
@@ -514,6 +515,9 @@ function useChartCore(candles, size, visibleRange, defaultCandleWidth, chartType
|
|
|
514
515
|
}
|
|
515
516
|
|
|
516
517
|
// src/VroomChart.tsx
|
|
518
|
+
function isSkImage(frame) {
|
|
519
|
+
return typeof frame.getImageInfo === "function";
|
|
520
|
+
}
|
|
517
521
|
function VroomChart(props) {
|
|
518
522
|
const {
|
|
519
523
|
candles,
|
|
@@ -526,6 +530,7 @@ function VroomChart(props) {
|
|
|
526
530
|
chartType,
|
|
527
531
|
transitionMs,
|
|
528
532
|
transitionEasing,
|
|
533
|
+
intervalTransition,
|
|
529
534
|
theme,
|
|
530
535
|
rsi,
|
|
531
536
|
macd,
|
|
@@ -565,17 +570,38 @@ function VroomChart(props) {
|
|
|
565
570
|
rec.beginRecording(import_react_native_skia.Skia.XYWHRect(0, 0, 1, 1));
|
|
566
571
|
return rec.finishRecordingAsPicture();
|
|
567
572
|
}, []);
|
|
573
|
+
const emptyImage = (0, import_react2.useMemo)(() => {
|
|
574
|
+
const data = import_react_native_skia.Skia.Data.fromBytes(new Uint8Array(4));
|
|
575
|
+
return import_react_native_skia.Skia.Image.MakeImage(
|
|
576
|
+
{
|
|
577
|
+
width: 1,
|
|
578
|
+
height: 1,
|
|
579
|
+
colorType: import_react_native_skia.ColorType.RGBA_8888,
|
|
580
|
+
alphaType: import_react_native_skia.AlphaType.Premul
|
|
581
|
+
},
|
|
582
|
+
data,
|
|
583
|
+
4
|
|
584
|
+
);
|
|
585
|
+
}, []);
|
|
568
586
|
const pictureSV = (0, import_react_native_reanimated.useSharedValue)(emptyPicture);
|
|
587
|
+
const imageSV = (0, import_react_native_reanimated.useSharedValue)(emptyImage);
|
|
588
|
+
const applyFrame = (0, import_react2.useCallback)(
|
|
589
|
+
(frame) => {
|
|
590
|
+
if (isSkImage(frame)) imageSV.value = frame;
|
|
591
|
+
else pictureSV.value = frame;
|
|
592
|
+
},
|
|
593
|
+
[imageSV, pictureSV]
|
|
594
|
+
);
|
|
569
595
|
const reduceMotion = (0, import_react_native_reanimated.useReducedMotion)();
|
|
570
596
|
const onFrame = (0, import_react2.useCallback)(
|
|
571
597
|
(p) => {
|
|
572
|
-
|
|
598
|
+
applyFrame(p);
|
|
573
599
|
},
|
|
574
|
-
[
|
|
600
|
+
[applyFrame]
|
|
575
601
|
);
|
|
576
602
|
const { handle, picture, volumeCollapseRef } = useChartCore(
|
|
577
603
|
candles,
|
|
578
|
-
{ width, height },
|
|
604
|
+
{ width, height, pxRatio: import_react_native2.PixelRatio.get() },
|
|
579
605
|
visibleRange,
|
|
580
606
|
defaultCandleWidth,
|
|
581
607
|
chartType,
|
|
@@ -587,7 +613,7 @@ function VroomChart(props) {
|
|
|
587
613
|
bollingerBands,
|
|
588
614
|
volume,
|
|
589
615
|
priceLinesProp,
|
|
590
|
-
{ seriesKey, transitionMs, transitionEasing, reduceMotion, onFrame }
|
|
616
|
+
{ seriesKey, transitionMs, transitionEasing, intervalTransition, reduceMotion, onFrame }
|
|
591
617
|
);
|
|
592
618
|
const crosshairActive = (0, import_react2.useRef)(false);
|
|
593
619
|
const lastCrosshairTime = (0, import_react2.useRef)(null);
|
|
@@ -604,11 +630,11 @@ function VroomChart(props) {
|
|
|
604
630
|
animRaf.current = null;
|
|
605
631
|
if (!handle) return;
|
|
606
632
|
const next = handle.render();
|
|
607
|
-
if (next)
|
|
633
|
+
if (next) applyFrame(next);
|
|
608
634
|
if (handle.isAnimating()) {
|
|
609
635
|
animRaf.current = requestAnimationFrame(animTick);
|
|
610
636
|
}
|
|
611
|
-
}, [handle,
|
|
637
|
+
}, [handle, applyFrame]);
|
|
612
638
|
const maybeStartAnim = (0, import_react2.useCallback)(() => {
|
|
613
639
|
if (animRaf.current != null) return;
|
|
614
640
|
if (!handle?.isAnimating()) return;
|
|
@@ -623,9 +649,9 @@ function VroomChart(props) {
|
|
|
623
649
|
};
|
|
624
650
|
}, []);
|
|
625
651
|
(0, import_react2.useEffect)(() => {
|
|
626
|
-
if (picture)
|
|
652
|
+
if (picture) applyFrame(picture);
|
|
627
653
|
maybeStartAnim();
|
|
628
|
-
}, [picture,
|
|
654
|
+
}, [picture, applyFrame, maybeStartAnim]);
|
|
629
655
|
const morphRaf = (0, import_react2.useRef)(null);
|
|
630
656
|
const morphFade = (0, import_react2.useRef)(null);
|
|
631
657
|
const morphHandle = (0, import_react2.useRef)(null);
|
|
@@ -639,7 +665,7 @@ function VroomChart(props) {
|
|
|
639
665
|
morphFade.current = target;
|
|
640
666
|
handle.setChartType(target);
|
|
641
667
|
const p = handle.render();
|
|
642
|
-
if (p)
|
|
668
|
+
if (p) applyFrame(p);
|
|
643
669
|
maybeStartAnim();
|
|
644
670
|
return void 0;
|
|
645
671
|
}
|
|
@@ -656,7 +682,7 @@ function VroomChart(props) {
|
|
|
656
682
|
morphFade.current = target;
|
|
657
683
|
handle.setChartType(target);
|
|
658
684
|
const p = handle.render();
|
|
659
|
-
if (p)
|
|
685
|
+
if (p) applyFrame(p);
|
|
660
686
|
maybeStartAnim();
|
|
661
687
|
return void 0;
|
|
662
688
|
}
|
|
@@ -669,7 +695,7 @@ function VroomChart(props) {
|
|
|
669
695
|
morphFade.current = fade;
|
|
670
696
|
handle.setMorph(reduceMotion ? 0 : fade, fade);
|
|
671
697
|
const p = handle.render();
|
|
672
|
-
if (p)
|
|
698
|
+
if (p) applyFrame(p);
|
|
673
699
|
if (prog < 1) {
|
|
674
700
|
morphRaf.current = requestAnimationFrame(step);
|
|
675
701
|
} else {
|
|
@@ -677,7 +703,7 @@ function VroomChart(props) {
|
|
|
677
703
|
morphFade.current = target;
|
|
678
704
|
handle.setChartType(target);
|
|
679
705
|
const q = handle.render();
|
|
680
|
-
if (q)
|
|
706
|
+
if (q) applyFrame(q);
|
|
681
707
|
maybeStartAnim();
|
|
682
708
|
}
|
|
683
709
|
};
|
|
@@ -688,7 +714,7 @@ function VroomChart(props) {
|
|
|
688
714
|
morphRaf.current = null;
|
|
689
715
|
}
|
|
690
716
|
};
|
|
691
|
-
}, [handle, chartType, transitionMs, reduceMotion,
|
|
717
|
+
}, [handle, chartType, transitionMs, reduceMotion, applyFrame, maybeStartAnim]);
|
|
692
718
|
const volumeRaf = (0, import_react2.useRef)(null);
|
|
693
719
|
const volumeHandle = (0, import_react2.useRef)(null);
|
|
694
720
|
(0, import_react2.useEffect)(() => {
|
|
@@ -714,7 +740,7 @@ function VroomChart(props) {
|
|
|
714
740
|
volumeCollapseRef.current = { t: target, easing };
|
|
715
741
|
handle.setVolumeCollapse(target, easing);
|
|
716
742
|
const p = handle.render();
|
|
717
|
-
if (p)
|
|
743
|
+
if (p) applyFrame(p);
|
|
718
744
|
maybeStartAnim();
|
|
719
745
|
return void 0;
|
|
720
746
|
}
|
|
@@ -728,7 +754,7 @@ function VroomChart(props) {
|
|
|
728
754
|
volumeCollapseRef.current = { t, easing: kind };
|
|
729
755
|
handle.setVolumeCollapse(t, kind);
|
|
730
756
|
const p = handle.render();
|
|
731
|
-
if (p)
|
|
757
|
+
if (p) applyFrame(p);
|
|
732
758
|
if (prog < 1) {
|
|
733
759
|
volumeRaf.current = requestAnimationFrame(step);
|
|
734
760
|
} else {
|
|
@@ -748,7 +774,7 @@ function VroomChart(props) {
|
|
|
748
774
|
volume?.enabled,
|
|
749
775
|
transitionMs,
|
|
750
776
|
reduceMotion,
|
|
751
|
-
|
|
777
|
+
applyFrame,
|
|
752
778
|
volumeCollapseRef,
|
|
753
779
|
maybeStartAnim
|
|
754
780
|
]);
|
|
@@ -766,7 +792,7 @@ function VroomChart(props) {
|
|
|
766
792
|
axisCollapse.current = { y: targetY, x: targetX };
|
|
767
793
|
handle.setAxisCollapse(targetY, targetX);
|
|
768
794
|
const p = handle.render();
|
|
769
|
-
if (p)
|
|
795
|
+
if (p) applyFrame(p);
|
|
770
796
|
maybeStartAnim();
|
|
771
797
|
return void 0;
|
|
772
798
|
}
|
|
@@ -785,7 +811,7 @@ function VroomChart(props) {
|
|
|
785
811
|
axisCollapse.current = { y: targetY, x: targetX };
|
|
786
812
|
handle.setAxisCollapse(targetY, targetX);
|
|
787
813
|
const p = handle.render();
|
|
788
|
-
if (p)
|
|
814
|
+
if (p) applyFrame(p);
|
|
789
815
|
maybeStartAnim();
|
|
790
816
|
return void 0;
|
|
791
817
|
}
|
|
@@ -799,7 +825,7 @@ function VroomChart(props) {
|
|
|
799
825
|
axisCollapse.current = { y, x };
|
|
800
826
|
handle.setAxisCollapse(y, x);
|
|
801
827
|
const p = handle.render();
|
|
802
|
-
if (p)
|
|
828
|
+
if (p) applyFrame(p);
|
|
803
829
|
if (prog < 1) {
|
|
804
830
|
axisRaf.current = requestAnimationFrame(step);
|
|
805
831
|
} else {
|
|
@@ -820,7 +846,7 @@ function VroomChart(props) {
|
|
|
820
846
|
showXAxis,
|
|
821
847
|
transitionMs,
|
|
822
848
|
reduceMotion,
|
|
823
|
-
|
|
849
|
+
applyFrame,
|
|
824
850
|
maybeStartAnim
|
|
825
851
|
]);
|
|
826
852
|
const hitAxis = (0, import_react2.useCallback)(
|
|
@@ -860,7 +886,7 @@ function VroomChart(props) {
|
|
|
860
886
|
priceDrag.current = { index: pl.index, id: pl.line.id, price: pl.line.price };
|
|
861
887
|
handle.setPriceLineDrag(pl.index, pl.line.price);
|
|
862
888
|
const p = handle.render();
|
|
863
|
-
if (p)
|
|
889
|
+
if (p) applyFrame(p);
|
|
864
890
|
}
|
|
865
891
|
}
|
|
866
892
|
}).onChange((e) => {
|
|
@@ -883,7 +909,7 @@ function VroomChart(props) {
|
|
|
883
909
|
next = handle.render();
|
|
884
910
|
} else if (crosshairActive.current) {
|
|
885
911
|
const ch = handle.setCrosshair(e.x, e.y - crosshairOffset);
|
|
886
|
-
if (ch)
|
|
912
|
+
if (ch) applyFrame(ch);
|
|
887
913
|
const info = handle.getCrosshairInfo();
|
|
888
914
|
const t = info?.timeMs ?? null;
|
|
889
915
|
if (t !== lastCrosshairTime.current) {
|
|
@@ -894,7 +920,7 @@ function VroomChart(props) {
|
|
|
894
920
|
} else {
|
|
895
921
|
next = handle.translate(e.changeX, e.changeY);
|
|
896
922
|
}
|
|
897
|
-
if (next)
|
|
923
|
+
if (next) applyFrame(next);
|
|
898
924
|
maybeStartAnim();
|
|
899
925
|
}).onEnd((e) => {
|
|
900
926
|
if (!handle) return;
|
|
@@ -903,7 +929,7 @@ function VroomChart(props) {
|
|
|
903
929
|
priceDrag.current = null;
|
|
904
930
|
handle.setPriceLineDrag(-1, 0);
|
|
905
931
|
const p = handle.render();
|
|
906
|
-
if (p)
|
|
932
|
+
if (p) applyFrame(p);
|
|
907
933
|
if (g) onPriceLineDragEnd?.(g.id, g.price);
|
|
908
934
|
return;
|
|
909
935
|
}
|
|
@@ -923,7 +949,7 @@ function VroomChart(props) {
|
|
|
923
949
|
velocity *= Math.pow(0.5, dt / HALF_LIFE_S);
|
|
924
950
|
const dx = velocity * dt;
|
|
925
951
|
const next = handle.pan(dx, 0);
|
|
926
|
-
if (next)
|
|
952
|
+
if (next) applyFrame(next);
|
|
927
953
|
maybeStartAnim();
|
|
928
954
|
if (Math.abs(velocity) > MIN_STOP) {
|
|
929
955
|
decayRaf.current = requestAnimationFrame(tick);
|
|
@@ -977,7 +1003,7 @@ function VroomChart(props) {
|
|
|
977
1003
|
}
|
|
978
1004
|
if (frameX === 1 && frameY === 1) return;
|
|
979
1005
|
const next = handle.zoom(frameX, frameY, focalX, focalY);
|
|
980
|
-
if (next)
|
|
1006
|
+
if (next) applyFrame(next);
|
|
981
1007
|
maybeStartAnim();
|
|
982
1008
|
});
|
|
983
1009
|
const longPress = import_react_native_gesture_handler.Gesture.LongPress().runOnJS(true).onStart((e) => {
|
|
@@ -987,7 +1013,7 @@ function VroomChart(props) {
|
|
|
987
1013
|
cancelDecay();
|
|
988
1014
|
crosshairActive.current = true;
|
|
989
1015
|
const ch = handle.setCrosshair(e.x, e.y - crosshairOffset);
|
|
990
|
-
if (ch)
|
|
1016
|
+
if (ch) applyFrame(ch);
|
|
991
1017
|
const info = handle.getCrosshairInfo();
|
|
992
1018
|
lastCrosshairTime.current = info?.timeMs ?? null;
|
|
993
1019
|
onCrosshair?.({
|
|
@@ -1010,7 +1036,7 @@ function VroomChart(props) {
|
|
|
1010
1036
|
if (hitAxis(e.x, e.y) !== "chart") return;
|
|
1011
1037
|
crosshairActive.current = false;
|
|
1012
1038
|
const ch = handle.clearCrosshair();
|
|
1013
|
-
if (ch)
|
|
1039
|
+
if (ch) applyFrame(ch);
|
|
1014
1040
|
lastCrosshairTime.current = null;
|
|
1015
1041
|
onCrosshair?.({ active: false, candle: null, timeMs: null, price: null, reason: "hide" });
|
|
1016
1042
|
});
|
|
@@ -1025,11 +1051,17 @@ function VroomChart(props) {
|
|
|
1025
1051
|
style
|
|
1026
1052
|
]
|
|
1027
1053
|
},
|
|
1028
|
-
/* @__PURE__ */ import_react2.default.createElement(import_react_native_gesture_handler.GestureDetector, { gesture }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: { flex: 1 } }, /* @__PURE__ */ import_react2.default.createElement(import_react_native_skia.Canvas, { style: { flex: 1 } }, width > 0 && height > 0 ? (
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1054
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native_gesture_handler.GestureDetector, { gesture }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: { flex: 1 } }, /* @__PURE__ */ import_react2.default.createElement(import_react_native_skia.Canvas, { style: { flex: 1 } }, width > 0 && height > 0 ? /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native_skia.Picture, { picture: pictureSV }), /* @__PURE__ */ import_react2.default.createElement(
|
|
1055
|
+
import_react_native_skia.Image,
|
|
1056
|
+
{
|
|
1057
|
+
image: imageSV,
|
|
1058
|
+
x: 0,
|
|
1059
|
+
y: 0,
|
|
1060
|
+
width,
|
|
1061
|
+
height,
|
|
1062
|
+
fit: "fill"
|
|
1063
|
+
}
|
|
1064
|
+
)) : null)))
|
|
1033
1065
|
);
|
|
1034
1066
|
}
|
|
1035
1067
|
// Annotate the CommonJS export names for ESM import in node:
|