@@ -47,6 +47,11 @@ export type UseScrambleProps = {
47
47
* @default 1
48
48
*/
49
49
step ?: number ;
50
+
51
+ /**
52
+ * Chance of scrambling a character, range from 0 to 1, 0 being no chance, and 1 being 100% chance
53
+ */
54
+ chance ?: number ;
50
55
/**
51
56
* Randomize `seed` characters at random text positions
52
57
*
@@ -108,6 +113,7 @@ export const useScramble = (props: UseScrambleProps) => {
108
113
step = 1 ,
109
114
tick = 1 ,
110
115
scramble = 1 ,
116
+ chance = 0.5 ,
111
117
overflow = true ,
112
118
range = [ 65 , 125 ] ,
113
119
overdrive = true ,
@@ -116,20 +122,6 @@ export const useScramble = (props: UseScrambleProps) => {
116
122
onAnimationEnd,
117
123
} = props ;
118
124
119
- if ( speed === 0 ) {
120
- console . error ( 'speed 0 will stop the animation' ) ;
121
- }
122
-
123
- if ( step < 1 ) {
124
- step = 1 ;
125
- console . error ( 'step must be at least 1. ' ) ;
126
- }
127
-
128
- if ( tick < 1 ) {
129
- tick = 1 ;
130
- console . error ( 'tick must be at least 1' ) ;
131
- }
132
-
133
125
const prefersReducedMotion = window . matchMedia (
134
126
'(prefers-reduced-motion: reduce)'
135
127
) . matches ;
@@ -177,7 +169,11 @@ export const useScramble = (props: UseScrambleProps) => {
177
169
typeof controlRef . current [ index ] !== 'undefined'
178
170
) {
179
171
controlRef . current [ index ] =
180
- controlRef . current [ index ] === ' ' ? ' ' : scramble || seed ;
172
+ controlRef . current [ index ] === ' '
173
+ ? ' '
174
+ : getRandomInt ( 0 , 10 ) > ( 1 - chance ) * 10
175
+ ? scramble || seed
176
+ : 0 ;
181
177
}
182
178
}
183
179
} ;
@@ -188,14 +184,24 @@ export const useScramble = (props: UseScrambleProps) => {
188
184
if ( scrambleIndexRef . current < text . length ) {
189
185
const currentIndex = scrambleIndexRef . current ;
190
186
187
+ const shouldScramble = getRandomInt ( 0 , 10 ) > ( 1 - chance ) * 10 ;
188
+
191
189
controlRef . current [ currentIndex ] =
192
- text [ scrambleIndexRef . current ] === ' ' ? ' ' : scramble ;
193
- scrambleIndexRef . current += 1 ;
190
+ text [ scrambleIndexRef . current ] === ' '
191
+ ? ' '
192
+ : shouldScramble
193
+ ? scramble
194
+ : 0 ;
195
+ scrambleIndexRef . current ++ ;
194
196
}
195
197
}
196
198
} ;
197
199
198
- const increaseControl = ( ) => {
200
+ const resizeControl = ( ) => {
201
+ if ( text . length < controlRef . current . length ) {
202
+ controlRef . current . pop ( ) ;
203
+ controlRef . current . splice ( text . length , step ) ;
204
+ }
199
205
for ( var i = 0 ; i < step ; i ++ ) {
200
206
if ( controlRef . current . length < text . length ) {
201
207
controlRef . current . push (
@@ -205,13 +211,6 @@ export const useScramble = (props: UseScrambleProps) => {
205
211
}
206
212
} ;
207
213
208
- const decreaseControl = ( ) => {
209
- if ( text . length < controlRef . current . length ) {
210
- controlRef . current . pop ( ) ;
211
- controlRef . current . splice ( text . length , step ) ;
212
- }
213
- } ;
214
-
215
214
const onOverdrive = ( ) => {
216
215
if ( ! overdrive ) return ;
217
216
@@ -224,15 +223,14 @@ export const useScramble = (props: UseScrambleProps) => {
224
223
: String . fromCharCode (
225
224
typeof overdrive === 'boolean' ? 95 : overdrive
226
225
) ;
227
- overdriveRef . current += 1 ;
226
+ overdriveRef . current ++ ;
228
227
}
229
228
}
230
229
} ;
231
230
232
231
const onTick = ( ) => {
233
232
stepForward ( ) ;
234
- increaseControl ( ) ;
235
- decreaseControl ( ) ;
233
+ resizeControl ( ) ;
236
234
seedForward ( ) ;
237
235
} ;
238
236
@@ -244,14 +242,11 @@ export const useScramble = (props: UseScrambleProps) => {
244
242
const animate = ( time : number ) => {
245
243
if ( ! speed ) return ;
246
244
247
- const timeElapsed = time - elapsedRef . current ;
248
-
249
245
rafRef . current = requestAnimationFrame ( animate ) ;
250
246
251
- if ( overdrive ) {
252
- onOverdrive ( ) ;
253
- }
247
+ onOverdrive ( ) ;
254
248
249
+ const timeElapsed = time - elapsedRef . current ;
255
250
if ( timeElapsed > fpsInterval ) {
256
251
elapsedRef . current = time ;
257
252
@@ -336,7 +331,7 @@ export const useScramble = (props: UseScrambleProps) => {
336
331
cancelAnimationFrame ( rafRef . current ) ;
337
332
}
338
333
339
- stepRef . current += 1 ;
334
+ stepRef . current ++ ;
340
335
} ;
341
336
342
337
/**
@@ -387,7 +382,7 @@ export const useScramble = (props: UseScrambleProps) => {
387
382
useEffect ( ( ) => {
388
383
cancelAnimationFrame ( rafRef . current ) ;
389
384
390
- if ( speed > 0 ) rafRef . current = requestAnimationFrame ( animate ) ;
385
+ rafRef . current = requestAnimationFrame ( animate ) ;
391
386
392
387
// cancel raf on unmount
393
388
return ( ) => {
0 commit comments