Hoang
Hoang

Reputation: 1

How can I create an auto-scroll timeline?

I'm trying to create an automatically scrolling timeline to represent time passing each second. I've done the automatic scrolling of the timeline, but I'm having performance issues.

This is my code. When I set the maxDuration to be large (about > 1000), it will be very laggy. I hope everyone can give me a solution or a better mechanism to code

import React, {useRef} from 'react';
import {
  Animated,
  Easing,
  FlatList,
  LayoutChangeEvent,
  View,
} from 'react-native';
import styles, {width} from './TimeRecordScrollStyle';
import {TimeInLine} from './TimeInLine';

const maxDuration = 150;
const padW = 80;
export const TimeRecordScroll = () => {
  const offsetX = useRef<any>(new Animated.Value(0));
  const contentRef = useRef<any>(null);

  const measureContainerView = React.useCallback(
    ({nativeEvent: {}}: LayoutChangeEvent) => {
      if (!contentRef.current) return;
      contentRef.current.measure(
        (_fx: number, _fy: number, width: number, height: number) => {
          offsetX.current?.setValue(0);
          console.log(width);
          startAnimated();
        },
      );
    },
    [],
  );

  const startAnimated = () => {
    Animated.timing(offsetX.current, {
      toValue: -(padW * maxDuration),
      duration: (maxDuration + 1) * 1000,
      delay: 0,
      easing: Easing.linear,
      useNativeDriver: true,
    }).start();
  };

  return (
    <View style={styles.viewScroll}>
      <View style={styles.markCandle} />
      <View
        ref={contentRef}
        onLayout={measureContainerView}
        style={styles.viewTimeLine}>
        <Animated.View
          style={[
            {
              width: width * maxDuration,
              transform: [{translateX: offsetX.current}],
            },
            styles.timeLine,
          ]}>
          <FlatList
            data={Array.from({length: maxDuration + 1}, (_, i) => i)}
            renderItem={item => <TimeInLine idx={item.index} />}
            keyExtractor={item => item.toString()}
            showsHorizontalScrollIndicator={false}
            horizontal
            scrollEnabled={false}
            getItemLayout={(data, index) => ({
              length: padW,
              offset: padW * index,
              index,
            })}
            initialNumToRender={Math.ceil(width / padW)}
          />
        </Animated.View>
      </View>
    </View>
  );
};

This is the result:

Upvotes: 0

Views: 63

Answers (0)

Related Questions