rn-marquee-text 2.1.2-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 +96 -5
- package/dist/MarqueeText.js +147 -163
- 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,34 +1,125 @@
|
|
|
1
|
-
import * as React from
|
|
2
|
-
import { ViewStyle, TextStyle } from
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { ViewStyle, TextStyle } from 'react-native';
|
|
3
|
+
/**
|
|
4
|
+
* Animation modes for the marquee text
|
|
5
|
+
*/
|
|
3
6
|
declare enum AnimationMode {
|
|
4
7
|
LOOP = "loop",
|
|
5
8
|
BOUNCE = "bounce"
|
|
6
9
|
}
|
|
7
|
-
|
|
10
|
+
/**
|
|
11
|
+
* Direction of the marquee animation
|
|
12
|
+
*/
|
|
13
|
+
type MarqueeDirection = 'horizontal' | 'vertical';
|
|
14
|
+
/**
|
|
15
|
+
* Props for the MarqueeText component
|
|
16
|
+
*/
|
|
8
17
|
interface MarqueeTextProps {
|
|
18
|
+
/**
|
|
19
|
+
* Content to be scrolled (string or React nodes)
|
|
20
|
+
*/
|
|
9
21
|
children: React.ReactNode;
|
|
22
|
+
/**
|
|
23
|
+
* The animation mode: 'loop' for continuous scrolling or 'bounce' for back-and-forth
|
|
24
|
+
* @default AnimationMode.LOOP
|
|
25
|
+
*/
|
|
10
26
|
mode?: AnimationMode;
|
|
27
|
+
/**
|
|
28
|
+
* Speed of the scrolling animation in pixels per second
|
|
29
|
+
* @default 30
|
|
30
|
+
*/
|
|
11
31
|
speed?: number;
|
|
32
|
+
/**
|
|
33
|
+
* Delay in milliseconds before starting the animation
|
|
34
|
+
* @default 1500
|
|
35
|
+
*/
|
|
12
36
|
delay?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Duration in milliseconds to pause at the end of the content (only for bounce mode)
|
|
39
|
+
* @default 1000
|
|
40
|
+
*/
|
|
13
41
|
endPauseDuration?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Container style
|
|
44
|
+
*/
|
|
14
45
|
style?: ViewStyle;
|
|
46
|
+
/**
|
|
47
|
+
* Text style (when children is a string)
|
|
48
|
+
*/
|
|
15
49
|
textStyle?: TextStyle;
|
|
50
|
+
/**
|
|
51
|
+
* Whether to enable the animation
|
|
52
|
+
* @default true
|
|
53
|
+
*/
|
|
16
54
|
enabled?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Direction of scrolling ('horizontal' or 'vertical')
|
|
57
|
+
* @default 'horizontal'
|
|
58
|
+
*/
|
|
17
59
|
direction?: MarqueeDirection;
|
|
60
|
+
/**
|
|
61
|
+
* Spacing between cloned elements
|
|
62
|
+
* @default 20
|
|
63
|
+
* @deprecated Use `gap` instead
|
|
64
|
+
*/
|
|
18
65
|
spacing?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Gap between repeating text loops
|
|
68
|
+
* @default 20
|
|
69
|
+
*/
|
|
70
|
+
gap?: number;
|
|
71
|
+
/**
|
|
72
|
+
* Allow user interaction with gesture handling
|
|
73
|
+
* @default true
|
|
74
|
+
*/
|
|
19
75
|
withGesture?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Custom frame rate for animation
|
|
78
|
+
*/
|
|
20
79
|
frameRate?: number;
|
|
80
|
+
/**
|
|
81
|
+
* Reverse the animation direction
|
|
82
|
+
* @default false
|
|
83
|
+
*/
|
|
21
84
|
reverse?: boolean;
|
|
85
|
+
/**
|
|
86
|
+
* Background color for the container
|
|
87
|
+
* @default 'transparent'
|
|
88
|
+
*/
|
|
22
89
|
backgroundColor?: string;
|
|
90
|
+
/**
|
|
91
|
+
* Callback when animation starts
|
|
92
|
+
*/
|
|
23
93
|
onAnimationStart?: () => void;
|
|
94
|
+
/**
|
|
95
|
+
* Callback when animation stops
|
|
96
|
+
*/
|
|
24
97
|
onAnimationStop?: () => void;
|
|
25
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Reference handle for the MarqueeText component
|
|
101
|
+
*/
|
|
26
102
|
export interface MarqueeTextRef {
|
|
103
|
+
/**
|
|
104
|
+
* Start the marquee animation
|
|
105
|
+
*/
|
|
27
106
|
start: () => void;
|
|
107
|
+
/**
|
|
108
|
+
* Stop the marquee animation
|
|
109
|
+
*/
|
|
28
110
|
stop: () => void;
|
|
111
|
+
/**
|
|
112
|
+
* Whether the animation is currently active
|
|
113
|
+
*/
|
|
29
114
|
isActive: boolean;
|
|
30
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* MarqueeText component for scrolling text or content
|
|
118
|
+
*
|
|
119
|
+
* This component creates a scrolling effect for text or other content.
|
|
120
|
+
* It supports both horizontal and vertical scrolling, different animation
|
|
121
|
+
* modes, and user interaction via gestures.
|
|
122
|
+
*/
|
|
31
123
|
declare const MarqueeText: React.ForwardRefExoticComponent<MarqueeTextProps & React.RefAttributes<MarqueeTextRef>>;
|
|
32
|
-
export { AnimationMode };
|
|
124
|
+
export { MarqueeText, AnimationMode };
|
|
33
125
|
export type { MarqueeDirection, MarqueeTextProps };
|
|
34
|
-
export default MarqueeText;
|
package/dist/MarqueeText.js
CHANGED
|
@@ -1,202 +1,186 @@
|
|
|
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
|
+
/**
|
|
6
|
+
* Animation modes for the marquee text
|
|
7
|
+
*/
|
|
5
8
|
var AnimationMode;
|
|
6
9
|
(function (AnimationMode) {
|
|
7
10
|
AnimationMode["LOOP"] = "loop";
|
|
8
11
|
AnimationMode["BOUNCE"] = "bounce";
|
|
9
12
|
})(AnimationMode || (AnimationMode = {}));
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (dimension <= 0)
|
|
19
|
-
return {};
|
|
20
|
-
var position = (index - 1) * (dimension + spacing);
|
|
21
|
-
var translation = -(anim.value % (dimension + spacing));
|
|
22
|
-
return _a = {
|
|
23
|
-
position: "absolute"
|
|
24
|
-
},
|
|
25
|
-
_a[isVertical ? "top" : "left"] = position,
|
|
26
|
-
_a.transform = isVertical
|
|
27
|
-
? [{ translateY: translation }]
|
|
28
|
-
: [{ translateX: translation }],
|
|
29
|
-
_a;
|
|
30
|
-
}, [index, spacing, contentMeasurement, direction]);
|
|
31
|
-
return <Animated.View style={style}>{children}</Animated.View>;
|
|
32
|
-
});
|
|
13
|
+
// AnimatedChild removed in favor of simplified Flexbox layout
|
|
14
|
+
/**
|
|
15
|
+
* MarqueeText component for scrolling text or content
|
|
16
|
+
*
|
|
17
|
+
* This component creates a scrolling effect for text or other content.
|
|
18
|
+
* It supports both horizontal and vertical scrolling, different animation
|
|
19
|
+
* modes, and user interaction via gestures.
|
|
20
|
+
*/
|
|
33
21
|
var MarqueeText = React.forwardRef(function (_a, ref) {
|
|
34
|
-
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 ?
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
var
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
});
|
|
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';
|
|
26
|
+
var isBounceMode = mode === AnimationMode.BOUNCE;
|
|
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
|
|
48
35
|
var _m = React.useState(0), cloneTimes = _m[0], setCloneTimes = _m[1];
|
|
49
|
-
|
|
50
|
-
var isMounted = React.useRef(true);
|
|
51
|
-
var isActive = useSharedValue(false);
|
|
52
|
-
var frameRateMs = frameRate ? 1000 / frameRate : 1000 / 60;
|
|
53
|
-
var pixelsPerMs = speed / 10;
|
|
54
|
-
var frameCallback = useFrameCallback(function (frameInfo) {
|
|
55
|
-
if (!enabled || frameInfo.timeSincePreviousFrame === null)
|
|
56
|
-
return;
|
|
57
|
-
var deltaTime = frameRateMs
|
|
58
|
-
? frameInfo.timeSincePreviousFrame / frameRateMs
|
|
59
|
-
: frameInfo.timeSincePreviousFrame;
|
|
60
|
-
anim.value += (reverse ? -1 : 1) * pixelsPerMs * deltaTime;
|
|
61
|
-
}, false);
|
|
36
|
+
// Calculate how many clones we need
|
|
62
37
|
useAnimatedReaction(function () {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
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) {
|
|
70
44
|
return 0;
|
|
71
|
-
return Math.ceil(containerDim / contentDim) + 2;
|
|
72
|
-
}, function (times) {
|
|
73
|
-
if (times > 0 && isMounted.current) {
|
|
74
|
-
runOnJS(setCloneTimes)(times);
|
|
75
45
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (
|
|
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)
|
|
56
|
+
return;
|
|
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;
|
|
79
62
|
return;
|
|
80
|
-
|
|
81
|
-
|
|
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)();
|
|
82
94
|
onAnimationStart === null || onAnimationStart === void 0 ? void 0 : onAnimationStart();
|
|
83
|
-
}, [
|
|
95
|
+
}, [startAnimation, onAnimationStart]);
|
|
84
96
|
var stop = React.useCallback(function () {
|
|
85
|
-
|
|
86
|
-
|
|
97
|
+
cancelAnimation(offset);
|
|
98
|
+
isAnimating.value = false;
|
|
87
99
|
onAnimationStop === null || onAnimationStop === void 0 ? void 0 : onAnimationStop();
|
|
88
|
-
}, [
|
|
100
|
+
}, [offset, onAnimationStop]);
|
|
89
101
|
React.useImperativeHandle(ref, function () { return ({
|
|
90
102
|
start: start,
|
|
91
103
|
stop: stop,
|
|
92
|
-
get isActive() {
|
|
93
|
-
return isActive.value;
|
|
94
|
-
},
|
|
104
|
+
get isActive() { return isAnimating.value; }
|
|
95
105
|
}); });
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
.onChange(function (e) {
|
|
101
|
-
anim.value += -(isVertical ? e.changeY : e.changeX);
|
|
102
|
-
})
|
|
103
|
-
.onFinalize(function (e) {
|
|
104
|
-
anim.value = withDecay({
|
|
105
|
-
velocity: -(isVertical ? e.velocityY : e.velocityX),
|
|
106
|
-
}, function (finished) {
|
|
107
|
-
if (finished)
|
|
108
|
-
runOnJS(start)();
|
|
109
|
-
});
|
|
110
|
-
});
|
|
111
|
-
}, [withGesture, isVertical, anim, start, stop, enabled]);
|
|
112
|
-
React.useEffect(function () {
|
|
113
|
-
return function () {
|
|
114
|
-
isMounted.current = false;
|
|
115
|
-
stop();
|
|
116
|
-
};
|
|
117
|
-
}, [stop]);
|
|
118
|
-
React.useEffect(function () {
|
|
119
|
-
if (enabled) {
|
|
120
|
-
var timer_1 = setTimeout(function () { return start(); }, delay);
|
|
121
|
-
return function () { return clearTimeout(timer_1); };
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
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)();
|
|
125
110
|
}
|
|
126
|
-
}, [enabled, start
|
|
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
|
+
});
|
|
127
138
|
var renderContent = function () {
|
|
128
|
-
if (typeof children ===
|
|
129
|
-
return
|
|
130
|
-
{children}
|
|
131
|
-
</Text>);
|
|
139
|
+
if (typeof children === 'string') {
|
|
140
|
+
return <Text style={textStyle}>{children}</Text>;
|
|
132
141
|
}
|
|
133
|
-
return
|
|
134
|
-
{children}
|
|
135
|
-
</View>);
|
|
142
|
+
return children;
|
|
136
143
|
};
|
|
137
|
-
return (<
|
|
138
|
-
|
|
139
|
-
{ backgroundColor: backgroundColor },
|
|
140
|
-
style,
|
|
141
|
-
{
|
|
142
|
-
minHeight: isVertical ? 20 : undefined,
|
|
143
|
-
minWidth: !isVertical ? 20 : undefined,
|
|
144
|
-
height: isVertical ? 'auto' : undefined,
|
|
145
|
-
width: !isVertical ? 'auto' : undefined,
|
|
146
|
-
},
|
|
147
|
-
]} onLayout={function (ev) {
|
|
148
|
-
containerMeasurement.value = ev.nativeEvent.layout;
|
|
149
|
-
}} pointerEvents="box-none">
|
|
150
|
-
<GestureDetector gesture={pan}>
|
|
151
|
-
<Animated.View style={[
|
|
152
|
-
isVertical ? styles.column : styles.row,
|
|
153
|
-
styles.contentWrapper,
|
|
154
|
-
]} pointerEvents="box-none">
|
|
155
|
-
<View style={styles.hidden} onLayout={function (ev) {
|
|
156
|
-
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;
|
|
157
146
|
}}>
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
{
|
|
162
|
-
Array.from({ length: cloneTimes }).map(function (_, index) {
|
|
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}>
|
|
163
161
|
{renderContent()}
|
|
164
|
-
</
|
|
162
|
+
</View>);
|
|
163
|
+
})}
|
|
165
164
|
</Animated.View>
|
|
166
165
|
</GestureDetector>
|
|
167
|
-
</
|
|
166
|
+
</View>);
|
|
168
167
|
});
|
|
169
168
|
var styles = StyleSheet.create({
|
|
170
169
|
container: {
|
|
171
|
-
overflow:
|
|
170
|
+
overflow: 'hidden',
|
|
172
171
|
},
|
|
173
172
|
hidden: {
|
|
174
173
|
opacity: 0,
|
|
175
|
-
position:
|
|
174
|
+
position: 'absolute',
|
|
176
175
|
zIndex: -1,
|
|
177
176
|
},
|
|
178
177
|
row: {
|
|
179
|
-
flexDirection:
|
|
180
|
-
position:
|
|
181
|
-
alignItems: 'center',
|
|
178
|
+
flexDirection: 'row',
|
|
179
|
+
position: 'relative',
|
|
182
180
|
},
|
|
183
181
|
column: {
|
|
184
|
-
flexDirection:
|
|
185
|
-
position:
|
|
186
|
-
justifyContent: 'center',
|
|
187
|
-
},
|
|
188
|
-
contentWrapper: {
|
|
189
|
-
flexShrink: 1,
|
|
190
|
-
},
|
|
191
|
-
defaultText: {
|
|
192
|
-
fontSize: 16,
|
|
193
|
-
color: 'black',
|
|
194
|
-
includeFontPadding: false,
|
|
195
|
-
textAlignVertical: 'center',
|
|
196
|
-
},
|
|
197
|
-
childContainer: {
|
|
198
|
-
flexShrink: 1,
|
|
182
|
+
flexDirection: 'column',
|
|
183
|
+
position: 'relative',
|
|
199
184
|
},
|
|
200
185
|
});
|
|
201
|
-
export { AnimationMode };
|
|
202
|
-
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
|
+
}
|