rn-marquee-text 2.1.1-beta.1 → 3.0.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/README.md +160 -163
- package/dist/AutoScroll.d.ts +2 -4
- package/dist/AutoScroll.js +3 -4
- package/dist/MarqueeText.d.ts +10 -5
- package/dist/MarqueeText.js +135 -169
- package/dist/constants.d.ts +4 -109
- package/dist/constants.js +4 -12
- package/dist/index.d.ts +6 -18
- package/dist/index.js +8 -10
- package/package.json +57 -59
package/README.md
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
|
-
|
|
1
|
+
```markdown
|
|
2
|
+
# React Native Marquee Text 🚀
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
[](https://github.com/yourusername/rn-marquee-text/blob/main/LICENSE)
|
|
5
|
-
[](https://www.npmjs.com/package/rn-marquee-text)
|
|
6
|
-
[](https://github.com/yourusername/rn-marquee-text/actions)
|
|
7
|
-
|
|
8
|
-
A high-performance, customizable marquee component for React Native with smooth animations and gesture support.
|
|
9
|
-
|
|
10
|
-

|
|
4
|
+

|
|
11
5
|
|
|
12
6
|
## Features ✨
|
|
13
7
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
8
|
+
- **Multi-directional scrolling**: Horizontal and vertical marquee effects
|
|
9
|
+
- **Animation modes**: Loop and bounce animations
|
|
10
|
+
- **Performance optimized**: Built with React Native Reanimated 2
|
|
11
|
+
- **Customizable**: Control speed, delay, spacing, and more
|
|
12
|
+
- **Interactive**: Gesture support for pausing/resuming
|
|
13
|
+
- **Flexible content**: Supports both text and custom components
|
|
14
|
+
- **TypeScript ready**: Complete type definitions included
|
|
21
15
|
|
|
22
|
-
## Installation
|
|
16
|
+
## Installation 📦
|
|
23
17
|
|
|
24
18
|
```bash
|
|
25
19
|
# Using npm
|
|
@@ -29,188 +23,191 @@ npm install rn-marquee-text react-native-reanimated react-native-gesture-handler
|
|
|
29
23
|
yarn add rn-marquee-text react-native-reanimated react-native-gesture-handler
|
|
30
24
|
```
|
|
31
25
|
|
|
32
|
-
### Peer Dependencies
|
|
33
|
-
|
|
34
|
-
-
|
|
26
|
+
### Peer Dependencies
|
|
27
|
+
Ensure you've properly installed and configured:
|
|
28
|
+
- [React Native Reanimated](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation)
|
|
29
|
+
- [React Native Gesture Handler](https://docs.swmansion.com/react-native-gesture-handler/docs/)
|
|
35
30
|
|
|
36
|
-
##
|
|
31
|
+
## Usage 🚀
|
|
37
32
|
|
|
33
|
+
### Basic Implementation
|
|
38
34
|
```jsx
|
|
39
|
-
import
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
import React from 'react';
|
|
36
|
+
import { StyleSheet, View } from 'react-native';
|
|
37
|
+
import MarqueeText from 'rn-marquee-text';
|
|
38
|
+
|
|
39
|
+
const App = () => (
|
|
40
|
+
<View style={styles.container}>
|
|
41
|
+
<MarqueeText
|
|
42
|
+
style={styles.marquee}
|
|
43
|
+
speed={40}
|
|
44
|
+
textStyle={styles.text}
|
|
47
45
|
>
|
|
48
|
-
|
|
49
|
-
</
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Advanced Usage 🧠
|
|
46
|
+
Your scrolling text goes here
|
|
47
|
+
</MarqueeText>
|
|
48
|
+
</View>
|
|
49
|
+
);
|
|
55
50
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
speed={30}
|
|
62
|
-
delay={2000}
|
|
63
|
-
endPauseDuration={1500}
|
|
64
|
-
spacing={30}
|
|
65
|
-
>
|
|
66
|
-
{yourCustomComponent}
|
|
67
|
-
</Marquee.MarqueeText>
|
|
68
|
-
```
|
|
51
|
+
const styles = StyleSheet.create({
|
|
52
|
+
container: { flex: 1, justifyContent: 'center', padding: 20 },
|
|
53
|
+
marquee: { height: 50, backgroundColor: '#f5f5f5', borderRadius: 8 },
|
|
54
|
+
text: { fontSize: 16, color: '#333' }
|
|
55
|
+
});
|
|
69
56
|
|
|
70
|
-
|
|
71
|
-
```jsx
|
|
72
|
-
const marqueeRef = useRef(null);
|
|
73
|
-
|
|
74
|
-
// Start/pause programmatically
|
|
75
|
-
<>
|
|
76
|
-
<Marquee.MarqueeText ref={marqueeRef} />
|
|
77
|
-
<Button
|
|
78
|
-
title="Toggle"
|
|
79
|
-
onPress={() => marqueeRef.current?.isActive
|
|
80
|
-
? marqueeRef.current.stop()
|
|
81
|
-
: marqueeRef.current.start()
|
|
82
|
-
}
|
|
83
|
-
/>
|
|
84
|
-
</>
|
|
57
|
+
export default App;
|
|
85
58
|
```
|
|
86
59
|
|
|
87
60
|
## API Reference 📚
|
|
88
61
|
|
|
89
62
|
### Props
|
|
90
|
-
|
|
91
63
|
| Prop | Type | Default | Description |
|
|
92
64
|
|------|------|---------|-------------|
|
|
93
|
-
| `
|
|
94
|
-
| `
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
102
|
-
| `
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `onAnimationStart` |
|
|
107
|
-
| `onAnimationStop` |
|
|
65
|
+
| `children` | React.ReactNode | Required | Content to scroll (string or components) |
|
|
66
|
+
| `mode` | 'loop' \| 'bounce' | 'loop' | Animation behavior |
|
|
67
|
+
| `speed` | number | 30 | Pixels per second |
|
|
68
|
+
| `direction` | 'horizontal' \| 'vertical' | 'horizontal' | Scroll direction |
|
|
69
|
+
| `enabled` | boolean | true | Animation active state |
|
|
70
|
+
| `delay` | number | 1500 | Initial delay (ms) before starting |
|
|
71
|
+
| `endPauseDuration` | number | 1000 | Pause at end (bounce mode only) |
|
|
72
|
+
| `gap` | number | 20 | Gap between repeating text loops |
|
|
73
|
+
| `spacing` | number | 20 | **Deprecated**: Use `gap` instead |
|
|
74
|
+
| `reverse` | boolean | false | Reverse the animation direction |
|
|
75
|
+
| `backgroundColor` | string | 'transparent' | Background color for the container |
|
|
76
|
+
| `withGesture` | boolean | true | Allow user interaction with gesture handling |
|
|
77
|
+
| `frameRate` | number | - | Custom frame rate for animation |
|
|
78
|
+
| `onAnimationStart` | function | - | Callback when animation starts |
|
|
79
|
+
| `onAnimationStop` | function | - | Callback when animation stops |
|
|
80
|
+
| `style` | ViewStyle | - | Container style |
|
|
81
|
+
| `textStyle` | TextStyle | - | Text style (when children is a string) |
|
|
108
82
|
|
|
109
83
|
### Methods (via ref)
|
|
84
|
+
```jsx
|
|
85
|
+
const marqueeRef = useRef();
|
|
110
86
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
start: () => void;
|
|
114
|
-
stop: () => void;
|
|
115
|
-
isActive: boolean;
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
## Examples 🎨
|
|
87
|
+
// Start animation
|
|
88
|
+
marqueeRef.current?.start();
|
|
120
89
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
<Marquee.MarqueeText
|
|
124
|
-
style={styles.ticker}
|
|
125
|
-
textStyle={styles.tickerText}
|
|
126
|
-
speed={40}
|
|
127
|
-
>
|
|
128
|
-
BREAKING: React Native Marquee Text released! • New version available • Check out the docs
|
|
129
|
-
</Marquee.MarqueeText>
|
|
90
|
+
// Stop animation
|
|
91
|
+
marqueeRef.current?.stop();
|
|
130
92
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
backgroundColor: '#ff0000',
|
|
134
|
-
height: 30,
|
|
135
|
-
},
|
|
136
|
-
tickerText: {
|
|
137
|
-
color: 'white',
|
|
138
|
-
fontSize: 14,
|
|
139
|
-
fontWeight: 'bold',
|
|
140
|
-
},
|
|
141
|
-
});
|
|
93
|
+
// Check if active
|
|
94
|
+
const isActive = marqueeRef.current?.isActive;
|
|
142
95
|
```
|
|
143
96
|
|
|
144
|
-
|
|
145
|
-
```jsx
|
|
146
|
-
<Marquee.MarqueeText
|
|
147
|
-
direction="vertical"
|
|
148
|
-
mode="bounce"
|
|
149
|
-
speed={20}
|
|
150
|
-
style={styles.carousel}
|
|
151
|
-
>
|
|
152
|
-
<ProductCard {...item1} />
|
|
153
|
-
<ProductCard {...item2} />
|
|
154
|
-
<ProductCard {...item3} />
|
|
155
|
-
</Marquee.MarqueeText>
|
|
156
|
-
```
|
|
97
|
+
## Examples 🎨
|
|
157
98
|
|
|
158
|
-
###
|
|
99
|
+
### Comprehensive Demo Example
|
|
159
100
|
```jsx
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
101
|
+
import React from 'react';
|
|
102
|
+
import { SafeAreaView, View, Text, StyleSheet } from 'react-native';
|
|
103
|
+
import { AutoScroll, Marquee } from 'rn-marquee-text';
|
|
104
|
+
|
|
105
|
+
export default function App() {
|
|
106
|
+
return (
|
|
107
|
+
<SafeAreaView style={{ flex: 1, padding: 16, gap: 24 }}>
|
|
108
|
+
<Text style={{ fontSize: 20, fontWeight: 'bold' }}>Marquee Text Demo</Text>
|
|
109
|
+
|
|
110
|
+
<View style={{ borderRadius: 8, overflow: 'hidden' }}>
|
|
111
|
+
<Marquee speed={80}>
|
|
112
|
+
This is a long scrolling text that demonstrates the marquee functionality
|
|
113
|
+
</Marquee>
|
|
114
|
+
</View>
|
|
115
|
+
|
|
116
|
+
<View style={{ borderRadius: 8, overflow: 'hidden' }}>
|
|
117
|
+
<Marquee
|
|
118
|
+
speed={120}
|
|
119
|
+
backgroundColor="#1a365d"
|
|
120
|
+
textStyle={{ color: '#f0f4f8', fontSize: 14 }}
|
|
121
|
+
>
|
|
122
|
+
Faster scrolling example with different colors
|
|
123
|
+
</Marquee>
|
|
124
|
+
</View>
|
|
125
|
+
|
|
126
|
+
<View style={{ width: '100%', borderRadius: 8, overflow: 'hidden' }}>
|
|
127
|
+
<Marquee
|
|
128
|
+
speed={100}
|
|
129
|
+
backgroundColor="#7b341e"
|
|
130
|
+
textStyle={{ color: '#fffaf0', fontSize: 18 }}
|
|
131
|
+
>
|
|
132
|
+
Breaking News: This is a full-width marquee text component that scrolls horizontally
|
|
133
|
+
</Marquee>
|
|
134
|
+
</View>
|
|
135
|
+
|
|
136
|
+
<View style={{ marginVertical: 10, borderRadius: 8, overflow: 'hidden' }}>
|
|
137
|
+
<Marquee
|
|
138
|
+
speed={50}
|
|
139
|
+
backgroundColor="#fff"
|
|
140
|
+
textStyle={{ color: '#0000ff', fontSize: 16 }}
|
|
141
|
+
>
|
|
142
|
+
This text will scroll horizontally with bounce effect. It will pause for 2 seconds at each end.
|
|
143
|
+
</Marquee>
|
|
144
|
+
</View>
|
|
145
|
+
|
|
146
|
+
<AutoScroll endPauseDuration={2000} style={styles.cardScroller} direction="horizontal">
|
|
147
|
+
<div style={styles.contentContainer}>
|
|
148
|
+
{[1, 2, 3, 4, 5].map((item) => (
|
|
149
|
+
<div key={item} style={styles.card}>
|
|
150
|
+
<Text style={styles.cardText}>Card {item}</Text>
|
|
151
|
+
</div>
|
|
152
|
+
))}
|
|
153
|
+
</div>
|
|
154
|
+
</AutoScroll>
|
|
155
|
+
<AutoScroll endPauseDuration={2000} style={styles.cardScroller} direction="horizontal">
|
|
156
|
+
<Text style={styles.cardText}>This text will scroll horizontally with bounce effect and pause for 2 seconds at each end 🎉</Text>
|
|
157
|
+
</AutoScroll>
|
|
158
|
+
</SafeAreaView>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
167
161
|
|
|
168
162
|
const styles = StyleSheet.create({
|
|
169
|
-
|
|
163
|
+
cardScroller: {
|
|
164
|
+
height: 120,
|
|
170
165
|
width: '100%',
|
|
171
|
-
|
|
166
|
+
marginTop: 10,
|
|
167
|
+
},
|
|
168
|
+
contentContainer: {
|
|
169
|
+
flexDirection: 'row',
|
|
170
|
+
padding: 10,
|
|
171
|
+
},
|
|
172
|
+
card: {
|
|
173
|
+
width: 100,
|
|
174
|
+
height: 100,
|
|
175
|
+
backgroundColor: '#f0f0f0',
|
|
176
|
+
borderRadius: 8,
|
|
177
|
+
marginRight: 10,
|
|
178
|
+
justifyContent: 'center',
|
|
179
|
+
alignItems: 'center',
|
|
180
|
+
},
|
|
181
|
+
cardText: {
|
|
182
|
+
fontSize: 16,
|
|
183
|
+
fontWeight: 'bold',
|
|
172
184
|
},
|
|
173
|
-
text: {
|
|
174
|
-
fontSize: 16,
|
|
175
|
-
color: '#333'
|
|
176
|
-
}
|
|
177
185
|
});
|
|
178
186
|
```
|
|
179
187
|
|
|
180
|
-
## Troubleshooting
|
|
181
|
-
|
|
182
|
-
### Animation not smooth?
|
|
183
|
-
- Ensure you're using Reanimated 2+
|
|
184
|
-
- Check for heavy renders in parent components
|
|
185
|
-
- Try reducing the `frameRate` prop
|
|
188
|
+
## Troubleshooting 🛠️
|
|
186
189
|
|
|
187
|
-
|
|
188
|
-
- Verify
|
|
189
|
-
- Check
|
|
190
|
-
- Ensure `textStyle` is properly applied
|
|
190
|
+
**Animation not working?**
|
|
191
|
+
- Verify Reanimated installation
|
|
192
|
+
- Check babel.config.js for Reanimated plugin
|
|
191
193
|
|
|
192
|
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
- Set `withGesture={true}` (default)
|
|
194
|
+
**Text not visible?**
|
|
195
|
+
- Ensure container has proper dimensions
|
|
196
|
+
- Verify text color contrasts with background
|
|
196
197
|
|
|
197
|
-
|
|
198
|
-
- Reduce
|
|
199
|
-
-
|
|
200
|
-
- Use `
|
|
198
|
+
**Performance issues?**
|
|
199
|
+
- Reduce animation speed
|
|
200
|
+
- Simplify marquee content
|
|
201
|
+
- Use `frameRate` prop to limit FPS
|
|
201
202
|
|
|
202
203
|
## Contributing 🤝
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
2. Create a feature branch
|
|
208
|
-
3. Submit a pull request
|
|
204
|
+
Contributions are welcome! Please:
|
|
205
|
+
1. Open an issue to discuss changes
|
|
206
|
+
2. Ensure tests are updated
|
|
207
|
+
3. Maintain consistent code style
|
|
209
208
|
|
|
210
209
|
## License 📄
|
|
210
|
+
MIT © PareshChavda(https://github.com/pareshchavda)
|
|
211
211
|
|
|
212
|
-
MIT © PARESH CHAVDA
|
|
213
212
|
|
|
214
|
-
---
|
|
215
213
|
|
|
216
|
-
Made with ❤️ for the React Native community
|
package/dist/AutoScroll.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { TextStyle, ViewStyle } from 'react-native';
|
|
3
|
-
import { AnimationMode } from './constants';
|
|
4
3
|
/**
|
|
5
4
|
* AutoScroll component that measures its content and container
|
|
6
5
|
* dimensions and automatically sets up a scrolling animation if
|
|
@@ -16,9 +15,9 @@ import { AnimationMode } from './constants';
|
|
|
16
15
|
* @prop {boolean} enabled - Whether the scrolling animation is enabled
|
|
17
16
|
* @prop {'horizontal'|'vertical'} direction - The direction of the scrolling animation
|
|
18
17
|
*/
|
|
19
|
-
declare const AutoScroll: ({ children, mode, speed, delay, endPauseDuration, style, textStyle, enabled, direction, }: {
|
|
18
|
+
export declare const AutoScroll: ({ children, mode, speed, delay, endPauseDuration, style, textStyle, enabled, direction, }: {
|
|
20
19
|
children: React.ReactNode;
|
|
21
|
-
mode?:
|
|
20
|
+
mode?: "loop" | "bounce";
|
|
22
21
|
speed?: number;
|
|
23
22
|
delay?: number;
|
|
24
23
|
endPauseDuration?: number;
|
|
@@ -27,4 +26,3 @@ declare const AutoScroll: ({ children, mode, speed, delay, endPauseDuration, sty
|
|
|
27
26
|
enabled?: boolean;
|
|
28
27
|
direction?: "horizontal" | "vertical";
|
|
29
28
|
}) => React.JSX.Element;
|
|
30
|
-
export default AutoScroll;
|
package/dist/AutoScroll.js
CHANGED
|
@@ -17,8 +17,8 @@ import { AnimationMode } from './constants';
|
|
|
17
17
|
* @prop {boolean} enabled - Whether the scrolling animation is enabled
|
|
18
18
|
* @prop {'horizontal'|'vertical'} direction - The direction of the scrolling animation
|
|
19
19
|
*/
|
|
20
|
-
var AutoScroll = function (_a) {
|
|
21
|
-
var children = _a.children, _b = _a.mode, mode = _b === void 0 ?
|
|
20
|
+
export var AutoScroll = function (_a) {
|
|
21
|
+
var children = _a.children, _b = _a.mode, mode = _b === void 0 ? 'loop' : _b, _c = _a.speed, speed = _c === void 0 ? 30 : _c, _d = _a.delay, delay = _d === void 0 ? 1500 : _d, _e = _a.endPauseDuration, endPauseDuration = _e === void 0 ? 1000 : _e, _f = _a.style, style = _f === void 0 ? {} : _f, _g = _a.textStyle, textStyle = _g === void 0 ? {} : _g, _h = _a.enabled, enabled = _h === void 0 ? true : _h, _j = _a.direction, direction = _j === void 0 ? 'vertical' : _j;
|
|
22
22
|
// References for measurement
|
|
23
23
|
var containerRef = useRef(null);
|
|
24
24
|
var contentRef = useRef(null);
|
|
@@ -88,7 +88,7 @@ var AutoScroll = function (_a) {
|
|
|
88
88
|
console.log('Animation setup:', { distance: distance, duration: duration });
|
|
89
89
|
// Reset position
|
|
90
90
|
scrollPosition.value = 0;
|
|
91
|
-
if (mode === AnimationMode.LOOP) {
|
|
91
|
+
if (mode === AnimationMode.LOOP || mode === 'loop') {
|
|
92
92
|
// Continuous loop animation
|
|
93
93
|
scrollPosition.value = withDelay(delay, withRepeat(withTiming(-distance, { duration: duration, easing: Easing.linear }), -1, false));
|
|
94
94
|
}
|
|
@@ -143,4 +143,3 @@ var styles = StyleSheet.create({
|
|
|
143
143
|
flexShrink: 0,
|
|
144
144
|
},
|
|
145
145
|
});
|
|
146
|
-
export default AutoScroll;
|
package/dist/MarqueeText.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import { ViewStyle, TextStyle } from
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ViewStyle, TextStyle } from 'react-native';
|
|
3
3
|
/**
|
|
4
4
|
* Animation modes for the marquee text
|
|
5
5
|
*/
|
|
@@ -10,7 +10,7 @@ declare enum AnimationMode {
|
|
|
10
10
|
/**
|
|
11
11
|
* Direction of the marquee animation
|
|
12
12
|
*/
|
|
13
|
-
type MarqueeDirection =
|
|
13
|
+
type MarqueeDirection = 'horizontal' | 'vertical';
|
|
14
14
|
/**
|
|
15
15
|
* Props for the MarqueeText component
|
|
16
16
|
*/
|
|
@@ -60,8 +60,14 @@ interface MarqueeTextProps {
|
|
|
60
60
|
/**
|
|
61
61
|
* Spacing between cloned elements
|
|
62
62
|
* @default 20
|
|
63
|
+
* @deprecated Use `gap` instead
|
|
63
64
|
*/
|
|
64
65
|
spacing?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Gap between repeating text loops
|
|
68
|
+
* @default 20
|
|
69
|
+
*/
|
|
70
|
+
gap?: number;
|
|
65
71
|
/**
|
|
66
72
|
* Allow user interaction with gesture handling
|
|
67
73
|
* @default true
|
|
@@ -115,6 +121,5 @@ export interface MarqueeTextRef {
|
|
|
115
121
|
* modes, and user interaction via gestures.
|
|
116
122
|
*/
|
|
117
123
|
declare const MarqueeText: React.ForwardRefExoticComponent<MarqueeTextProps & React.RefAttributes<MarqueeTextRef>>;
|
|
118
|
-
export { AnimationMode };
|
|
124
|
+
export { MarqueeText, AnimationMode };
|
|
119
125
|
export type { MarqueeDirection, MarqueeTextProps };
|
|
120
|
-
export default MarqueeText;
|
package/dist/MarqueeText.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import { StyleSheet, View, Text
|
|
3
|
-
import { Gesture, GestureDetector } from
|
|
4
|
-
import Animated, { runOnJS, useAnimatedReaction, useAnimatedStyle, useSharedValue,
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { StyleSheet, View, Text } from 'react-native';
|
|
3
|
+
import { Gesture, GestureDetector } from 'react-native-gesture-handler';
|
|
4
|
+
import Animated, { runOnJS, useAnimatedReaction, useAnimatedStyle, useSharedValue, withDelay, withRepeat, withSequence, withTiming, Easing, cancelAnimation, runOnUI, } from 'react-native-reanimated';
|
|
5
5
|
/**
|
|
6
6
|
* Animation modes for the marquee text
|
|
7
7
|
*/
|
|
@@ -10,32 +10,7 @@ var AnimationMode;
|
|
|
10
10
|
AnimationMode["LOOP"] = "loop";
|
|
11
11
|
AnimationMode["BOUNCE"] = "bounce";
|
|
12
12
|
})(AnimationMode || (AnimationMode = {}));
|
|
13
|
-
|
|
14
|
-
* Component to render a child item in the marquee
|
|
15
|
-
*/
|
|
16
|
-
var AnimatedChild = React.memo(function (_a) {
|
|
17
|
-
var index = _a.index, children = _a.children, anim = _a.anim, contentMeasurement = _a.contentMeasurement, spacing = _a.spacing, direction = _a.direction;
|
|
18
|
-
var style = useAnimatedStyle(function () {
|
|
19
|
-
var _a;
|
|
20
|
-
var isVertical = direction === "vertical";
|
|
21
|
-
var dimension = isVertical
|
|
22
|
-
? contentMeasurement.value.height
|
|
23
|
-
: contentMeasurement.value.width;
|
|
24
|
-
if (dimension <= 0)
|
|
25
|
-
return {};
|
|
26
|
-
var position = (index - 1) * (dimension + spacing);
|
|
27
|
-
var translation = -(anim.value % (dimension + spacing));
|
|
28
|
-
return _a = {
|
|
29
|
-
position: "absolute"
|
|
30
|
-
},
|
|
31
|
-
_a[isVertical ? "top" : "left"] = position,
|
|
32
|
-
_a.transform = isVertical
|
|
33
|
-
? [{ translateY: translation }]
|
|
34
|
-
: [{ translateX: translation }],
|
|
35
|
-
_a;
|
|
36
|
-
}, [index, spacing, contentMeasurement, direction]);
|
|
37
|
-
return <Animated.View style={style}>{children}</Animated.View>;
|
|
38
|
-
});
|
|
13
|
+
// AnimatedChild removed in favor of simplified Flexbox layout
|
|
39
14
|
/**
|
|
40
15
|
* MarqueeText component for scrolling text or content
|
|
41
16
|
*
|
|
@@ -44,177 +19,168 @@ var AnimatedChild = React.memo(function (_a) {
|
|
|
44
19
|
* modes, and user interaction via gestures.
|
|
45
20
|
*/
|
|
46
21
|
var MarqueeText = React.forwardRef(function (_a, ref) {
|
|
47
|
-
var children = _a.children, _b = _a.mode, mode = _b === void 0 ? AnimationMode.LOOP : _b, _c = _a.speed, speed = _c === void 0 ? 30 : _c, _d = _a.delay, delay = _d === void 0 ? 1500 : _d, _e = _a.endPauseDuration, endPauseDuration = _e === void 0 ? 1000 : _e, style = _a.style, textStyle = _a.textStyle, _f = _a.enabled, enabled = _f === void 0 ? true : _f, _g = _a.direction, direction = _g === void 0 ?
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}), contentSize = _m[0], setContentSize = _m[1];
|
|
52
|
-
var isVertical = direction === "vertical";
|
|
22
|
+
var children = _a.children, _b = _a.mode, mode = _b === void 0 ? AnimationMode.LOOP : _b, _c = _a.speed, speed = _c === void 0 ? 30 : _c, _d = _a.delay, delay = _d === void 0 ? 1500 : _d, _e = _a.endPauseDuration, endPauseDuration = _e === void 0 ? 1000 : _e, style = _a.style, textStyle = _a.textStyle, _f = _a.enabled, enabled = _f === void 0 ? true : _f, _g = _a.direction, direction = _g === void 0 ? 'horizontal' : _g, _h = _a.spacing, spacing = _h === void 0 ? 20 : _h, gap = _a.gap, // New prop
|
|
23
|
+
_j = _a.withGesture, // New prop
|
|
24
|
+
withGesture = _j === void 0 ? true : _j, frameRate = _a.frameRate, _k = _a.reverse, reverse = _k === void 0 ? false : _k, _l = _a.backgroundColor, backgroundColor = _l === void 0 ? 'transparent' : _l, onAnimationStart = _a.onAnimationStart, onAnimationStop = _a.onAnimationStop;
|
|
25
|
+
var isVertical = direction === 'vertical';
|
|
53
26
|
var isBounceMode = mode === AnimationMode.BOUNCE;
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
var
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
y: 0,
|
|
65
|
-
});
|
|
66
|
-
var _o = React.useState(0), cloneTimes = _o[0], setCloneTimes = _o[1];
|
|
67
|
-
var anim = useSharedValue(0);
|
|
68
|
-
var isMounted = React.useRef(true);
|
|
69
|
-
var isActive = useSharedValue(false);
|
|
70
|
-
var frameRateMs = frameRate ? 1000 / frameRate : 1000 / 60; // Default to 60fps
|
|
71
|
-
var pixelsPerMs = speed / 1000;
|
|
72
|
-
// Animation frame callback
|
|
73
|
-
var frameCallback = useFrameCallback(function (frameInfo) {
|
|
74
|
-
if (!enabled || frameInfo.timeSincePreviousFrame === null)
|
|
75
|
-
return;
|
|
76
|
-
var deltaTime = frameRateMs
|
|
77
|
-
? frameInfo.timeSincePreviousFrame / frameRateMs
|
|
78
|
-
: frameInfo.timeSincePreviousFrame;
|
|
79
|
-
anim.value += (reverse ? -1 : 1) * pixelsPerMs * deltaTime;
|
|
80
|
-
}, false);
|
|
81
|
-
// Calculate how many clones we need to fill the screen
|
|
27
|
+
// Resolve gap/spacing (prefer gap)
|
|
28
|
+
var effectiveSpacing = gap !== undefined ? gap : spacing;
|
|
29
|
+
// Shared values
|
|
30
|
+
var containerSize = useSharedValue(0);
|
|
31
|
+
var contentSize = useSharedValue(0);
|
|
32
|
+
var offset = useSharedValue(0);
|
|
33
|
+
var isAnimating = useSharedValue(false);
|
|
34
|
+
// State for cloning
|
|
35
|
+
var _m = React.useState(0), cloneTimes = _m[0], setCloneTimes = _m[1];
|
|
36
|
+
// Calculate how many clones we need
|
|
82
37
|
useAnimatedReaction(function () {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (contentDim <= 0 || containerDim <= 0)
|
|
38
|
+
if (contentSize.value === 0 || containerSize.value === 0)
|
|
39
|
+
return 0;
|
|
40
|
+
// Conditional Animation Check:
|
|
41
|
+
// Only loop if content exceeds container?
|
|
42
|
+
// If contentSize <= containerSize, we need 0 clones (just original).
|
|
43
|
+
if (contentSize.value <= containerSize.value) {
|
|
90
44
|
return 0;
|
|
91
|
-
// Need enough clones to fill the container plus buffer for continuous scrolling
|
|
92
|
-
return Math.ceil(containerDim / contentDim) + 2;
|
|
93
|
-
}, function (times) {
|
|
94
|
-
if (times > 0 && isMounted.current) {
|
|
95
|
-
runOnJS(setCloneTimes)(times);
|
|
96
45
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
46
|
+
return Math.ceil(containerSize.value / contentSize.value) + 2;
|
|
47
|
+
}, function (result) {
|
|
48
|
+
if (result !== cloneTimes) {
|
|
49
|
+
runOnJS(setCloneTimes)(result);
|
|
50
|
+
}
|
|
51
|
+
}, [contentSize, containerSize]);
|
|
52
|
+
// Animation Logic
|
|
53
|
+
var startAnimation = React.useCallback(function () {
|
|
54
|
+
'worklet';
|
|
55
|
+
if (!enabled || contentSize.value === 0 || containerSize.value === 0)
|
|
101
56
|
return;
|
|
102
|
-
|
|
103
|
-
|
|
57
|
+
// If no clones needed (fits in screen), don't animate
|
|
58
|
+
if (contentSize.value <= containerSize.value) {
|
|
59
|
+
cancelAnimation(offset);
|
|
60
|
+
offset.value = 0; // Reset position
|
|
61
|
+
isAnimating.value = false;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
cancelAnimation(offset);
|
|
65
|
+
isAnimating.value = true;
|
|
66
|
+
var size = contentSize.value + effectiveSpacing;
|
|
67
|
+
if (mode === AnimationMode.LOOP) {
|
|
68
|
+
// Continuous Loop
|
|
69
|
+
var duration = (size / speed) * 1000;
|
|
70
|
+
// Initial delay handled by a separate sequence wrapper
|
|
71
|
+
// The repeating part must be seamless: 0 -> -size, then instant reset to 0
|
|
72
|
+
offset.value = withDelay(delay, withRepeat(withSequence(withTiming(-size, {
|
|
73
|
+
duration: duration,
|
|
74
|
+
easing: Easing.linear,
|
|
75
|
+
}), withTiming(0, { duration: 0 })), -1, // Infinite repeat
|
|
76
|
+
false // No reverse
|
|
77
|
+
));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// Bounce Mode
|
|
81
|
+
var distance = Math.abs(contentSize.value - containerSize.value);
|
|
82
|
+
if (distance <= 0)
|
|
83
|
+
return;
|
|
84
|
+
var target = contentSize.value > containerSize.value
|
|
85
|
+
? -(contentSize.value - containerSize.value)
|
|
86
|
+
: (containerSize.value - contentSize.value);
|
|
87
|
+
var duration = (Math.abs(target) / speed) * 1000;
|
|
88
|
+
offset.value = withRepeat(withSequence(withDelay(delay, withTiming(target, { duration: duration, easing: Easing.linear })), withDelay(endPauseDuration, withTiming(0, { duration: duration, easing: Easing.linear }))), -1, false);
|
|
89
|
+
}
|
|
90
|
+
}, [enabled, mode, speed, delay, endPauseDuration, effectiveSpacing, containerSize, contentSize]);
|
|
91
|
+
// Start/Stop Controls
|
|
92
|
+
var start = React.useCallback(function () {
|
|
93
|
+
runOnUI(startAnimation)();
|
|
104
94
|
onAnimationStart === null || onAnimationStart === void 0 ? void 0 : onAnimationStart();
|
|
105
|
-
}, [
|
|
95
|
+
}, [startAnimation, onAnimationStart]);
|
|
106
96
|
var stop = React.useCallback(function () {
|
|
107
|
-
|
|
108
|
-
|
|
97
|
+
cancelAnimation(offset);
|
|
98
|
+
isAnimating.value = false;
|
|
109
99
|
onAnimationStop === null || onAnimationStop === void 0 ? void 0 : onAnimationStop();
|
|
110
|
-
}, [
|
|
111
|
-
// Expose controls via ref
|
|
100
|
+
}, [offset, onAnimationStop]);
|
|
112
101
|
React.useImperativeHandle(ref, function () { return ({
|
|
113
102
|
start: start,
|
|
114
103
|
stop: stop,
|
|
115
|
-
get isActive() {
|
|
116
|
-
return isActive.value;
|
|
117
|
-
},
|
|
104
|
+
get isActive() { return isAnimating.value; }
|
|
118
105
|
}); });
|
|
119
|
-
//
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
.onBegin(function () {
|
|
124
|
-
// Stop auto-animation when user interacts
|
|
125
|
-
runOnJS(stop)();
|
|
126
|
-
})
|
|
127
|
-
.onChange(function (e) {
|
|
128
|
-
// Move according to user's gesture
|
|
129
|
-
anim.value += -(isVertical ? e.changeY : e.changeX);
|
|
130
|
-
})
|
|
131
|
-
.onFinalize(function (e) {
|
|
132
|
-
// Apply momentum scrolling when user releases
|
|
133
|
-
anim.value = withDecay({
|
|
134
|
-
velocity: -(isVertical ? e.velocityY : e.velocityX),
|
|
135
|
-
}, function (finished) {
|
|
136
|
-
// Restart auto-animation when decay finishes
|
|
137
|
-
if (finished)
|
|
138
|
-
runOnJS(start)();
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
}, [withGesture, isVertical, anim, start, stop, enabled]);
|
|
142
|
-
// Cleanup on unmount
|
|
143
|
-
React.useEffect(function () {
|
|
144
|
-
return function () {
|
|
145
|
-
isMounted.current = false;
|
|
146
|
-
stop();
|
|
147
|
-
};
|
|
148
|
-
}, [stop]);
|
|
149
|
-
// Start/stop based on enabled prop changes
|
|
150
|
-
React.useEffect(function () {
|
|
151
|
-
if (enabled) {
|
|
152
|
-
var timer_1 = setTimeout(function () {
|
|
153
|
-
start();
|
|
154
|
-
}, delay);
|
|
155
|
-
return function () { return clearTimeout(timer_1); };
|
|
156
|
-
}
|
|
157
|
-
else {
|
|
158
|
-
stop();
|
|
106
|
+
// Effect to auto-start when layout is ready
|
|
107
|
+
useAnimatedReaction(function () { return contentSize.value > 0 && containerSize.value > 0 && cloneTimes > 0; }, function (isReady) {
|
|
108
|
+
if (isReady && enabled) {
|
|
109
|
+
runOnJS(start)();
|
|
159
110
|
}
|
|
160
|
-
}, [enabled, start
|
|
161
|
-
//
|
|
111
|
+
}, [cloneTimes, enabled, start]);
|
|
112
|
+
// Gesture Handler
|
|
113
|
+
var pan = Gesture.Pan()
|
|
114
|
+
.enabled(withGesture && enabled)
|
|
115
|
+
.onBegin(function () {
|
|
116
|
+
cancelAnimation(offset);
|
|
117
|
+
isAnimating.value = false;
|
|
118
|
+
})
|
|
119
|
+
.onChange(function (e) {
|
|
120
|
+
offset.value += isVertical ? e.changeY : e.changeX;
|
|
121
|
+
})
|
|
122
|
+
.onFinalize(function () {
|
|
123
|
+
// Logic to resume?
|
|
124
|
+
// For simplicity in declaring "clean reset", we might just restart the loop
|
|
125
|
+
// OR we can calculate where we are and finish the current cycle.
|
|
126
|
+
// Restarting is safest to prevent being "out of phase".
|
|
127
|
+
runOnJS(start)();
|
|
128
|
+
});
|
|
129
|
+
var animatedStyle = useAnimatedStyle(function () {
|
|
130
|
+
return {
|
|
131
|
+
transform: [
|
|
132
|
+
isVertical
|
|
133
|
+
? { translateY: offset.value }
|
|
134
|
+
: { translateX: offset.value }
|
|
135
|
+
],
|
|
136
|
+
};
|
|
137
|
+
});
|
|
162
138
|
var renderContent = function () {
|
|
163
|
-
if (typeof children ===
|
|
139
|
+
if (typeof children === 'string') {
|
|
164
140
|
return <Text style={textStyle}>{children}</Text>;
|
|
165
141
|
}
|
|
166
142
|
return children;
|
|
167
143
|
};
|
|
168
|
-
return (<
|
|
169
|
-
|
|
170
|
-
{ backgroundColor: backgroundColor },
|
|
171
|
-
style,
|
|
172
|
-
{
|
|
173
|
-
height: isVertical && contentMeasurement.value.height > 0
|
|
174
|
-
? contentMeasurement.value.height
|
|
175
|
-
: undefined,
|
|
176
|
-
width: !isVertical && contentMeasurement.value.width > 0
|
|
177
|
-
? contentMeasurement.value.width
|
|
178
|
-
: undefined,
|
|
179
|
-
},
|
|
180
|
-
]} onLayout={function (ev) {
|
|
181
|
-
containerMeasurement.value = ev.nativeEvent.layout;
|
|
182
|
-
}} pointerEvents="box-none">
|
|
183
|
-
<GestureDetector gesture={pan}>
|
|
184
|
-
<Animated.View style={isVertical ? styles.column : styles.row} pointerEvents="box-none">
|
|
185
|
-
{/* Hidden element for measuring original content size */}
|
|
186
|
-
<View style={styles.hidden} onLayout={function (ev) {
|
|
187
|
-
contentMeasurement.value = ev.nativeEvent.layout;
|
|
144
|
+
return (<View style={[styles.container, { backgroundColor: backgroundColor }, style]} onLayout={function (ev) {
|
|
145
|
+
containerSize.value = isVertical ? ev.nativeEvent.layout.height : ev.nativeEvent.layout.width;
|
|
188
146
|
}}>
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
{/*
|
|
193
|
-
{cloneTimes
|
|
194
|
-
|
|
147
|
+
<GestureDetector gesture={pan}>
|
|
148
|
+
<Animated.View style={[isVertical ? styles.column : styles.row, animatedStyle]}>
|
|
149
|
+
{/* Original Items + Clones */}
|
|
150
|
+
{/* We render a list of items based on cloneTimes */}
|
|
151
|
+
{Array.from({ length: Math.max(1, cloneTimes) }).map(function (_, index) {
|
|
152
|
+
var _a;
|
|
153
|
+
// We need to space them out.
|
|
154
|
+
// In this simplified declarative model, we just render them in a flex row/col with gaps/margins.
|
|
155
|
+
// We don't need absolute positioning if we use Flexbox layout properly!
|
|
156
|
+
return (<View key={index} style={_a = {},
|
|
157
|
+
_a[isVertical ? 'marginBottom' : 'marginRight'] = effectiveSpacing,
|
|
158
|
+
_a} onLayout={index === 0 ? function (ev) {
|
|
159
|
+
contentSize.value = isVertical ? ev.nativeEvent.layout.height : ev.nativeEvent.layout.width;
|
|
160
|
+
} : undefined}>
|
|
195
161
|
{renderContent()}
|
|
196
|
-
</
|
|
162
|
+
</View>);
|
|
163
|
+
})}
|
|
197
164
|
</Animated.View>
|
|
198
165
|
</GestureDetector>
|
|
199
|
-
</
|
|
166
|
+
</View>);
|
|
200
167
|
});
|
|
201
168
|
var styles = StyleSheet.create({
|
|
202
169
|
container: {
|
|
203
|
-
overflow:
|
|
170
|
+
overflow: 'hidden',
|
|
204
171
|
},
|
|
205
172
|
hidden: {
|
|
206
173
|
opacity: 0,
|
|
207
|
-
position:
|
|
174
|
+
position: 'absolute',
|
|
208
175
|
zIndex: -1,
|
|
209
176
|
},
|
|
210
177
|
row: {
|
|
211
|
-
flexDirection:
|
|
212
|
-
position:
|
|
178
|
+
flexDirection: 'row',
|
|
179
|
+
position: 'relative',
|
|
213
180
|
},
|
|
214
181
|
column: {
|
|
215
|
-
flexDirection:
|
|
216
|
-
position:
|
|
182
|
+
flexDirection: 'column',
|
|
183
|
+
position: 'relative',
|
|
217
184
|
},
|
|
218
185
|
});
|
|
219
|
-
export { AnimationMode };
|
|
220
|
-
export default MarqueeText;
|
|
186
|
+
export { MarqueeText, AnimationMode };
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,109 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export declare enum AnimationMode {
|
|
6
|
-
LOOP = "loop",
|
|
7
|
-
BOUNCE = "bounce"
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Direction of the marquee animation
|
|
11
|
-
*/
|
|
12
|
-
type MarqueeDirection = 'horizontal' | 'vertical';
|
|
13
|
-
/**
|
|
14
|
-
* Props for the MarqueeText component
|
|
15
|
-
*/
|
|
16
|
-
export interface MarqueeTextProps {
|
|
17
|
-
/**
|
|
18
|
-
* Content to be scrolled (string or React nodes)
|
|
19
|
-
*/
|
|
20
|
-
children: React.ReactNode;
|
|
21
|
-
/**
|
|
22
|
-
* The animation mode: 'loop' for continuous scrolling or 'bounce' for back-and-forth
|
|
23
|
-
* @default AnimationMode.LOOP
|
|
24
|
-
*/
|
|
25
|
-
mode?: AnimationMode;
|
|
26
|
-
/**
|
|
27
|
-
* Speed of the scrolling animation in pixels per second
|
|
28
|
-
* @default 30
|
|
29
|
-
*/
|
|
30
|
-
speed?: number;
|
|
31
|
-
/**
|
|
32
|
-
* Delay in milliseconds before starting the animation
|
|
33
|
-
* @default 1500
|
|
34
|
-
*/
|
|
35
|
-
delay?: number;
|
|
36
|
-
/**
|
|
37
|
-
* Duration in milliseconds to pause at the end of the content (only for bounce mode)
|
|
38
|
-
* @default 1000
|
|
39
|
-
*/
|
|
40
|
-
endPauseDuration?: number;
|
|
41
|
-
/**
|
|
42
|
-
* Container style
|
|
43
|
-
*/
|
|
44
|
-
style?: ViewStyle;
|
|
45
|
-
/**
|
|
46
|
-
* Text style (when children is a string)
|
|
47
|
-
*/
|
|
48
|
-
textStyle?: TextStyle;
|
|
49
|
-
/**
|
|
50
|
-
* Whether to enable the animation
|
|
51
|
-
* @default true
|
|
52
|
-
*/
|
|
53
|
-
enabled?: boolean;
|
|
54
|
-
/**
|
|
55
|
-
* Direction of scrolling ('horizontal' or 'vertical')
|
|
56
|
-
* @default 'horizontal'
|
|
57
|
-
*/
|
|
58
|
-
direction?: MarqueeDirection;
|
|
59
|
-
/**
|
|
60
|
-
* Spacing between cloned elements
|
|
61
|
-
* @default 20
|
|
62
|
-
*/
|
|
63
|
-
spacing?: number;
|
|
64
|
-
/**
|
|
65
|
-
* Allow user interaction with gesture handling
|
|
66
|
-
* @default true
|
|
67
|
-
*/
|
|
68
|
-
withGesture?: boolean;
|
|
69
|
-
/**
|
|
70
|
-
* Custom frame rate for animation
|
|
71
|
-
*/
|
|
72
|
-
frameRate?: number;
|
|
73
|
-
/**
|
|
74
|
-
* Reverse the animation direction
|
|
75
|
-
* @default false
|
|
76
|
-
*/
|
|
77
|
-
reverse?: boolean;
|
|
78
|
-
/**
|
|
79
|
-
* Background color for the container
|
|
80
|
-
* @default 'transparent'
|
|
81
|
-
*/
|
|
82
|
-
backgroundColor?: string;
|
|
83
|
-
/**
|
|
84
|
-
* Callback when animation starts
|
|
85
|
-
*/
|
|
86
|
-
onAnimationStart?: () => void;
|
|
87
|
-
/**
|
|
88
|
-
* Callback when animation stops
|
|
89
|
-
*/
|
|
90
|
-
onAnimationStop?: () => void;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Reference handle for the MarqueeText component
|
|
94
|
-
*/
|
|
95
|
-
export interface MarqueeTextRef {
|
|
96
|
-
/**
|
|
97
|
-
* Start the marquee animation
|
|
98
|
-
*/
|
|
99
|
-
start: () => void;
|
|
100
|
-
/**
|
|
101
|
-
* Stop the marquee animation
|
|
102
|
-
*/
|
|
103
|
-
stop: () => void;
|
|
104
|
-
/**
|
|
105
|
-
* Whether the animation is currently active
|
|
106
|
-
*/
|
|
107
|
-
isActive: boolean;
|
|
108
|
-
}
|
|
109
|
-
export {};
|
|
1
|
+
export declare const AnimationMode: {
|
|
2
|
+
LOOP: string;
|
|
3
|
+
BOUNCE: string;
|
|
4
|
+
};
|
package/dist/constants.js
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Animation modes for the marquee text
|
|
7
|
-
*/
|
|
8
|
-
export var AnimationMode;
|
|
9
|
-
(function (AnimationMode) {
|
|
10
|
-
AnimationMode["LOOP"] = "loop";
|
|
11
|
-
AnimationMode["BOUNCE"] = "bounce";
|
|
12
|
-
})(AnimationMode || (AnimationMode = {}));
|
|
1
|
+
export var AnimationMode = {
|
|
2
|
+
LOOP: 'loop',
|
|
3
|
+
BOUNCE: 'bounce',
|
|
4
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,18 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
declare const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
speed?: number;
|
|
8
|
-
delay?: number;
|
|
9
|
-
endPauseDuration?: number;
|
|
10
|
-
style?: import("react-native").ViewStyle;
|
|
11
|
-
textStyle?: import("react-native").TextStyle;
|
|
12
|
-
enabled?: boolean;
|
|
13
|
-
direction?: "horizontal" | "vertical";
|
|
14
|
-
}) => import("react").JSX.Element;
|
|
15
|
-
MarqueeText: import("react").ForwardRefExoticComponent<import("./MarqueeText").MarqueeTextProps & import("react").RefAttributes<import("./MarqueeText").MarqueeTextRef>>;
|
|
16
|
-
AnimationMode: typeof AnimationMode;
|
|
17
|
-
};
|
|
18
|
-
export default Marquee;
|
|
1
|
+
import { AutoScroll } from './AutoScroll';
|
|
2
|
+
import { AnimationMode } from './constants';
|
|
3
|
+
declare const MarqueeTextShim: any;
|
|
4
|
+
declare const MarqueeShim: any;
|
|
5
|
+
export { AutoScroll, AnimationMode, MarqueeTextShim as MarqueeText, MarqueeShim as Marquee };
|
|
6
|
+
export default AutoScroll;
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import AutoScroll from './AutoScroll';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
//
|
|
5
|
-
var
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
export default Marquee;
|
|
1
|
+
import { AutoScroll } from './AutoScroll';
|
|
2
|
+
import { MarqueeText } from './MarqueeText';
|
|
3
|
+
import { AnimationMode } from './constants';
|
|
4
|
+
// @ts-ignore - Shim for React 18/19 compatibility
|
|
5
|
+
var MarqueeTextShim = MarqueeText;
|
|
6
|
+
var MarqueeShim = MarqueeText;
|
|
7
|
+
export { AutoScroll, AnimationMode, MarqueeTextShim as MarqueeText, MarqueeShim as Marquee };
|
|
8
|
+
export default AutoScroll;
|
package/package.json
CHANGED
|
@@ -1,60 +1,58 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
}
|
|
2
|
+
"name": "rn-marquee-text",
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "A customizable marquee (scrolling) text component for React Native",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"prepare": "npm run build"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"index.js",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"react-native",
|
|
19
|
+
"marquee",
|
|
20
|
+
"scrolling-text",
|
|
21
|
+
"text",
|
|
22
|
+
"animation",
|
|
23
|
+
"react-native-component",
|
|
24
|
+
"react",
|
|
25
|
+
"native",
|
|
26
|
+
"expo",
|
|
27
|
+
"Marquee"
|
|
28
|
+
],
|
|
29
|
+
"author": "Paresh Chavda",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/pareshchavda/rn-marquee-text-public.git"
|
|
34
|
+
},
|
|
35
|
+
"bugs": {
|
|
36
|
+
"url": "https://github.com/pareshchavda/rn-marquee-text-public/issues"
|
|
37
|
+
},
|
|
38
|
+
"homepage": "https://github.com/pareshchavda/rn-marquee-text-public#readme",
|
|
39
|
+
"peerDependencies": {
|
|
40
|
+
"prop-types": ">=15.0.0",
|
|
41
|
+
"react": "*",
|
|
42
|
+
"react-native": "*",
|
|
43
|
+
"react-native-reanimated": ">=2.0.0",
|
|
44
|
+
"@react-navigation/native": ">=6.0.0"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@react-navigation/native": "^7.1.9",
|
|
48
|
+
"@types/react": "^19.1.2",
|
|
49
|
+
"prop-types": "^15.8.1",
|
|
50
|
+
"react": "^18.2.0",
|
|
51
|
+
"react-native": "^0.72.17",
|
|
52
|
+
"react-native-reanimated": "^3.17.5",
|
|
53
|
+
"typescript": "^5.0.0"
|
|
54
|
+
},
|
|
55
|
+
"dependencies": {
|
|
56
|
+
"react-native-gesture-handler": "^2.25.0"
|
|
57
|
+
}
|
|
58
|
+
}
|