zoukankan      html  css  js  c++  java
  • xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

    taro scroll tabs

    滚动标签 切换

    https://www.cnblogs.com/lml-lml/p/10954069.html

    https://developers.weixin.qq.com/community/develop/doc/000cc0b94ac5f8dcf4e7666475b804

    https://blog.csdn.net/weixin_42860683/article/details/83817925

    https://juejin.im/post/5d563b5e6fb9a06b317b5d20

    taro

    
    import Taro, {
      Component,
    } from '@tarojs/taro'
    import {
      View,
      Text,
      ScrollView,
    } from '@tarojs/components'
    
    import classnames from 'classnames'
    import './TabList.scss'
    
    export default class TabList extends Component {
      state = {
        active: 0,
      }
    
      componentWillMount() {
        this.setState({
          active: this.props.current || 0,
        })
      }
    
      componentDidMount() {
    
      }
    
      componentWillReceiveProps(nextProps) {
        const { current } = nextProps
        if (current !== this.props.current) {
          this.setState({
            active: current,
          })
        }
      }
    
      onSelectTab(index) {
        this.setState({
          active: index,
        })
        this.props.onSelected && this.props.onSelected(index)
      }
    
      render() {
        let { tabs, tabItemStyle, scrollWithAnimation } = this.props
        let { active } = this.state
        return (
          tabs.length && <ScrollView className="tab-list" scrollX scrollWithAnimation={scrollWithAnimation}
            scrollIntoView={`tab-${active >= 2 ? (active - 2) : 0}`}
          >
            <View className="tab-list__container">
              {
                tabs.map((item, index) => {
                  return (
                    <View style={tabItemStyle} className={classnames([
                      'tab-item',
                      {
                        active: active === index,
                      },
                    ])} onClick={this.onSelectTab.bind(this, index)} key={index} id={`tab-` + index}
                    >
                      <Text>{item.name}</Text>
                      <View className="tab-line"></View>
                    </View>
                  )
                })
              }
            </View>
    
          </ScrollView>
        )
      }
    }
    TabList.defaultProps = {
      tabs: [],
      current: 0,
      tabItemStyle: 'height:78rpx',
      scrollWithAnimation: process.env.TARO_ENV === 'weapp',
    }
    
    
    

    scroll tab 组件

    开发一个可以滚动的tab组件

    https://github.com/ScoutYin/ly-tab#readme

    https://github.com/ScoutYin/ly-tab/tree/master/src

    https://www.cnblogs.com/lml-lml/p/10954069.html

    window.requestAnimationFrame

    animation

    
    export function windowInit () {
      var lastTime = 0
      var vendors = ['webkit', 'moz']
      for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
        window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']
        window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || // name has changed in Webkit
                                      window[vendors[x] + 'CancelRequestAnimationFrame']
      }
    
      if (!window.requestAnimationFrame) {
        window.requestAnimationFrame = function (callback, element) {
          var currTime = new Date().getTime()
          var timeToCall = Math.max(0, 16.7 - (currTime - lastTime))
          var interval = currTime - lastTime
          var id = window.setTimeout(function () {
            callback(interval)
          }, timeToCall)
          lastTime = currTime + timeToCall
          return id
        }
      }
      if (!window.cancelAnimationFrame) {
        window.cancelAnimationFrame = function (id) {
          clearTimeout(id)
        }
      }
    }
    
    

    touch event

    
      methods: {
        // start
        handleTouchStart (event) {
          event.stopPropagation()
          cancelAnimationFrame(this.inertiaFrame)
          this.lastX = event.touches[0].clientX
        },
        // move
        handleTouchMove (event) {
          if (this.listWidth <= 0) return
          event.preventDefault()
          event.stopPropagation()
          this.touching = true
          this.startMoveTime = this.endMoveTime
          this.startX = this.lastX
          this.currentX = event.touches[0].clientX
          this.moveFollowTouch()
          this.endMoveTime = event.timeStamp // 每次触发touchmove事件的时间戳;
        },
        // end
        handleTouchEnd (event) {
          this.touching = false
          if (this.checkReboundX()) {
            cancelAnimationFrame(this.inertiaFrame)
          } else {
            let silenceTime = event.timeStamp - this.endMoveTime
            let timeStamp = this.endMoveTime - this.startMoveTime
            timeStamp = timeStamp > 0 ? timeStamp : 8
            if (silenceTime > 100) return  // 停顿时间超过100ms不产生惯性滑动;
            this.speed = (this.lastX - this.startX) / timeStamp
            this.acceleration = this.speed / this.sensitivity
            this.frameStartTime = new Date().getTime()
            this.inertiaFrame = requestAnimationFrame(this.moveByInertia)
          }
        },
        // 如果需要回弹则进行回弹操作并返回true;
        checkReboundX () {
          this.reBounding = false
          if (this.translateX > 0) {
            this.reBounding = true
            this.translateX = 0
          } else if (this.translateX < -this.listWidth) {
            this.reBounding = true
            this.translateX = -this.listWidth
          }
          return this.translateX === 0 || this.translateX === -this.listWidth
        },
        bindEvent () {
          this.$el.addEventListener('touchstart', this.handleTouchStart, false)
          this.$el.addEventListener('touchmove', this.handleTouchMove, false)
          this.$el.addEventListener('touchend', this.handleTouchEnd, false)
        },
        removeEvent () {
          this.$el.removeEventListener('touchstart', this.handleTouchStart)
          this.$el.removeEventListener('touchmove', this.handleTouchMove)
          this.$el.removeEventListener('touchend', this.handleTouchEnd)
        },
        // touch拖动
        moveFollowTouch () {
          if (this.isMoveLeft) { // 向左拖动
            if (this.translateX <= 0 && this.translateX + this.listWidth > 0 || this.translateX > 0) {
              this.translateX += this.currentX - this.lastX
            } else if (this.translateX + this.listWidth <= 0) {
              this.translateX += this.additionalX * (this.currentX - this.lastX)
                                 / (this.viewAreaWidth + Math.abs(this.translateX + this.listWidth))
            }
          } else { // 向右拖动
            if (this.translateX >= 0) {
              this.translateX += this.additionalX * (this.currentX - this.lastX)
                                 / (this.viewAreaWidth + this.translateX)
            } else if ((this.translateX <= 0 && this.translateX + this.listWidth >= 0) ||
              this.translateX + this.listWidth <= 0) {
                this.translateX += this.currentX - this.lastX
            }
          }
          this.lastX = this.currentX
        },
        // 惯性滑动
        moveByInertia () {
          this.frameEndTime = new Date().getTime()
          this.frameTime = this.frameEndTime - this.frameStartTime
          if (this.isMoveLeft) { // 向左惯性滑动;
            if (this.translateX <= -this.listWidth) { // 超出边界的过程;
              // 加速度指数变化;
              this.acceleration *= (this.reBoundExponent +
                                   Math.abs(this.translateX + this.listWidth)) /
                                   this.reBoundExponent
              this.speed = Math.min(this.speed - this.acceleration, 0) // 为避免减速过程过短,此处加速度没有乘上frameTime;
            } else {
              this.speed = Math.min(this.speed - this.acceleration * this.frameTime, 0)
            }
          } else if (this.isMoveRight) { // 向右惯性滑动;
            if (this.translateX >= 0) {
              this.acceleration *= (this.reBoundExponent + this.translateX) / this.reBoundExponent
              this.speed = Math.max(this.speed - this.acceleration, 0)
            } else {
              this.speed = Math.max(this.speed - this.acceleration * this.frameTime, 0)
            }
          }
          this.translateX += this.speed * this.frameTime / 2
          if (Math.abs(this.speed) <= this.zeroSpeed) {
            this.checkReboundX()
            return
          }
          this.frameStartTime = this.frameEndTime
          this.inertiaFrame = requestAnimationFrame(this.moveByInertia)
        },
        // 计算activeBar的translateX
        calcBarPosX () {
          if (this.fixBottom || !this.$children.length) return
          if (this.$children.length <= this.value) return
          const item = this.$children[this.value].$el
          const itemWidth = item.offsetWidth
          const itemLeft = item.offsetLeft
          this.activeBarWidth = Math.max(itemWidth * 0.6, 14)
          this.activeBarX = itemLeft + (itemWidth - this.activeBarWidth) / 2
        },
        // 点击切换item时,调整位置使当前item尽可能往中间显示
        checkPosition () {
          if (this.fixBottom || !this.$children.length) return
          if (this.$children.length <= this.value) return
          const activeItem = this.$children[this.value].$el
          const offsetLeft = activeItem.offsetLeft
          const half = (this.viewAreaWidth - activeItem.offsetWidth) / 2
          let changeX = 0
          const absTransX = Math.abs(this.translateX)
          if (offsetLeft <= absTransX + half) { // item偏左,需要往右移
            let pageX = offsetLeft + this.translateX
            changeX = half - pageX
          } else { // item偏右,需要往左移
            changeX = -(offsetLeft - absTransX - half)
          }
          let lastX = changeX + this.translateX
          // 两种边界情况
          lastX > 0 && (lastX = 0)
          lastX < -this.listWidth && (lastX = -this.listWidth)
          this.reBounding = true
          this.translateX = lastX
        }
      }
    
    

    ©xgqfrms 2012-2020

    www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!


  • 相关阅读:
    iOS
    iOS
    iOS
    OpenGLES入门笔记四
    OpenGLES入门笔记三
    AVPlayer无法播放
    阿里云TTS重播报pointer being freed was not allocated错误
    [AVAssetWriter startWriting] Cannot call method when status is 1
    HTTP load failed (error code: -1009) / NSURLConnection finished with error
    在iPhone5上起始页卡着不动
  • 原文地址:https://www.cnblogs.com/xgqfrms/p/12582327.html
Copyright © 2011-2022 走看看