Taro,React,Typescript for Roadcasting Map

Carousel Summary

Requirements: Roadcasting Map: Auto-Roadcasting, Leaking Part of Next Item, Moving Left, Seamless Connection Switching
The project technology stack is react.js, Taro, typescript
Difficulty: Because of the technology stack, using Taro's Swiper component to write a round-robin can be done with this component for normal round-robin, but because the requirements need to leak out a part of the next item, Taro's Swiper component does not have this property. Next-margin (used in Taro as nextMargin) of the applet can meet this requirement, butH5 is not supported, so the solution is either to use Swiper components, compatible with H5, or to use other container components.
Supplement: In applets or Taro s, swiper-item components of swiper components inherit the width and height of swiper by default, and the width and height of the swiper components are 100%, so it doesn't matter how you change the width, you can use ** to say high online!impotant** to change (ps: If you can change the width, it's easy to miss a part of the next item, unfortunately.)No)

Before I started trying other methods, I reviewed the documentation for all Taro container components, and if I could use Taro's offerings, it would be best to see that ScrollView could be implemented, except for the Swiper component of pass.

  • Try Method One: Implement with ScrollView

    ScrollView has been found to be able to slide pictures manually, but for automatic switching, you need to use onScroll to listen for the distance from the ScrollView container to the left, then use a timer to set the distance from the left after a few seconds, or use marginLeft to control the distance to the leftDistance, but!!!I forgot that this can be slid manually!!!If you slid it artificially while it's on the air, you'll have a problem, so Pass!

  • Try Method 2: Use the simplest css to implement
    Using animation implementation

    <!-- Note: The code is written in a WeChat applet with four test pictures-->
    <!-- wxml file -->
    <view class='carousel'>
      <view class='carousel-box'>
        <block wx:for="{{imgUrls}}">
          <view class='carousel-item'>
            <image class='carousel-img' src='{{item}}'></image>
          </view>
        </block>
      </view>
    </view>
    <!-- wxss file -->
    .carousel{
      width:750rpx;
      height:384rpx;
      overflow: hidden;
      margin-left:32rpx;
    }
    .carousel-box{
      width:2250rpx; //Calculated from the length of the picture array
      animation: imgMove 6s ease-out infinite
    }
    .carousel-item{
      float:left;
      width:624rpx;
      margin-right:12px;
    }
    .carousel-img{
      width:624rpx;
      height:384rpx;
      border-radius: 3px;
    }
    
    @keyframes imgMove{
      0%, 25% {
        margin-left:0;
      }
      35%,60%{
        margin-left:-324px
      }
      70%, 100%{
        margin-left:-648px;
      }
    }
    

Disadvantages: In this business scenario, the number of rotation pictures is not fixed, @keyfarames needs to determine the number of pictures to determine how many percent to slide, so this way of pass, in fact, can be achieved with a small number of pictures, but it is cumbersome!

  • Mode 3: Use native JS to implement: let alone say, there are many examples on the web. This project technical stack is react. If you use native js, you can certainly meet the project requirements, but JS operation Dom violates react's intent, every Dom change will re-render the page, performance will be much worse.Pass!

  • Mode 4: Use the most basic View component:

    • 1. Write the style first

      Use View to wrap all pictures, keep all pictures on one line, display the first one, and miss a part of the next item. This can be done by controlling the display of the pictures, or by controlling the width of the View that wraps the pictures, or by controlling the transparency, etc.

    • 2. Auto-rotation

      First you get the length of the picture array, then calculate the width of the outer View that wraps the picture, use marginLeft to move to the left, move to the left with a negative value (if you want to move to the right, with a positive value or with marginRight), mark the picture to which you moved with index, and calculate the value of marginLeft

      Note here that when assigning an initial value, some don't use 0 as the initial value, such as the width of the View that wraps the picture (one year after popularity: 0 multiplies any number by 0)

    • 3. Realize circular rotation

      When the picture is rotated to the last picture, you need to assign the index value to the first index so that you can rotate one round and then the next

      By this time it's actually working, but you'll find that because a part of the next item is missing from the rotation, when the last one is empty, it needs to be connected seamlessly

    • 3. Seamless connection

      Idea: Copy the first item of the array of pictures, make a judgment, hide the first copy behind the last one, so that when you rotate to the last picture of the array, you can show the picture we copied

      //This code does not make seamless connections, ideas have been followed
      //index.js
      import Taro,{ useState, useEffect } from '@tarojs/taro'
      import { View, Image } from '@tarojs/components'
      import { cropImage } from '../../utils/tools'
      import './index.scss'
      
      type Props = {
        imgList: string[]
      }
      
      export default function WebCarousel({
                                            imgList: []
                                          } : Props) {
        const { imgList } = this.props;
        const len = imgList.length;
        const ImgBoxWidth = Taro.pxTransform(750*len);
        const [index, setIndex] = useState<number>(1);
        const [translateLeft, setTranslateLeft] = useState<number>(1);
        const lastImg = imgList[len];
        imgList.push(lastImg)
        useEffect(() => {
          if(index === len ){
            setIndex(0);
            setTranslateLeft(1)
          }
          setInterval(() => {
            setIndex(index+1);
            setTranslateLeft(648 * index);
          },4000);
        }, [index]);
      
        return <View className='WCarousel'>
          <View className='WCarousel-list' style={{width:ImgBoxWidth, marginLeft:Taro.pxTransform(-translateLeft)}}>
            {
              imgList.map(item => (
                <View className='WCarousel-item' >
                  <Image className='WCarousel-img' src={cropImage(item)} />
                </View>
              ))
            }
          </View>
        </View>
      }
      //index.scss
      .WCarousel{
        width:750px;
        height:384px;
        overflow: hidden;
        margin-left:32px;
        &-list{
          height:384px;
          transition:all 0.3s
        }
        &-item{
          float:left;
          width:624px;
          margin-right:24px;
        }
        &-img{
          width:624px;
          height:384px;
          border-radius: 6px;
        }
      }
      

Keywords: React TypeScript

Added by coldfused on Thu, 08 Aug 2019 07:28:05 +0300