欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

react?card?slider實現(xiàn)滑動卡片教程示例

 更新時間:2022年09月03日 10:50:07   作者:GuoguoDad  
這篇文章主要為大家介紹了react?card?slider實現(xiàn)滑動卡片教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

效果

實現(xiàn)

通過zIndex控制層級,opacity控制透明度,transform 控制卡片縮放程度,marginLeft控制位置,剩下的就是計算的事了

card-slider.tsx

import React from 'react'
export type CardProps = {
  opacity: number
  scale: number
  loop?: boolean
  width: number
  disablePrev?: boolean
  disableNext?: boolean
  boxWidth: number
  index?: number
  list: any[]
  renderItem(data: any): React.ReactNode
  onChange?: (index: number, data: any) => void
  style?: React.CSSProperties
}
type CardState = {
  activeIndex: number
  moving: boolean
}
export default class CardSlider extends React.Component<CardProps, CardState> {
  static defaultProps: Partial<CardProps> = {
    opacity: 0.9,
    scale: 0.9,
    loop: false,
    disablePrev: false,
    disableNext: false
  }
  constructor(props: CardProps) {
    super(props)
    this.state = {
      activeIndex: props.index || 0,
      moving: false
    }
  }
  componentWillReceiveProps(nextProps: any) {
    if (this.props.index !== nextProps.index) {
      this.setState({
        activeIndex: nextProps.index
      })
    }
  }
  // 卡片總數(shù)量
  get totalCount() {
    return this.props.list.length
  }
  // 間隔寬度
  get gridWidth() {
    const isEven = this.totalCount % 2 === 0
    const { width, boxWidth } = this.props
    return (boxWidth - width) / (isEven ? this.totalCount : this.totalCount - 1)
  }
  // 禁用prev
  get disablePrev() {
    const { loop, disablePrev } = this.props
    const { activeIndex } = this.state
    if (disablePrev) return true
    return !loop && activeIndex === 0
  }
  // 禁用prev
  get disableNext() {
    const { loop, disableNext } = this.props
    const { activeIndex } = this.state
    if (disableNext) return true
    return !loop && activeIndex === this.totalCount - 1
  }
  /**
   * offset: 是左或者右的第幾個
   * direction: 1:右側:-1:左側
   */
  getDirection(index: number) {
    const { activeIndex } = this.state
    let direction = 1
    if (
      index - activeIndex > this.totalCount / 2 ||
      (index - activeIndex < 0 && index - activeIndex > -this.totalCount / 2)
    ) {
      direction = -1
    }
    let offset = Math.abs(index - activeIndex)
    if (offset > this.totalCount / 2) {
      offset = activeIndex + this.totalCount - index
    }
    if (index - activeIndex < -this.totalCount / 2) {
      offset = this.totalCount + index - activeIndex
    }
    return {
      direction,
      offset
    }
  }
  render() {
    const { list, renderItem, opacity, scale, width, boxWidth, style = {} } = this.props
    return (
      <div style={{ ...styles.wrapper, ...style }}>
        <div style={{ ...styles.content, width: boxWidth }}>
          {list.map((data, index) => {
            const { direction, offset } = this.getDirection(index)
            const realScale = Math.pow(scale, offset)
            return renderItem({
              key: index,
              ...data,
              style: {
                position: 'absolute',
                left: '50%',
                marginLeft: this.gridWidth * direction * offset + direction * ((width / 2) * (1 - realScale)),
                zIndex: this.totalCount - offset,
                opacity: Math.pow(opacity, offset),
                transform: `translateX(-50%) translateZ(0) scale(${realScale})`,
                transition: 'all 300ms'
              }
            })
          })}
        </div>
        {!this.disablePrev && (
          <a href="javascript:;" rel="external nofollow"  rel="external nofollow"  style={{ ...styles.btn, left: 35 }} onClick={this.handlePrev}>
            {'<'}
          </a>
        )}
        {!this.disableNext && (
          <a href="javascript:;" rel="external nofollow"  rel="external nofollow"  style={{ ...styles.btn, right: 35 }} onClick={this.handleNext}>
            {'>'}
          </a>
        )}
      </div>
    )
  }
  handlePrev = () => {
    let { activeIndex } = this.state
    if (this.disablePrev) return
    activeIndex = --activeIndex < 0 ? this.totalCount - 1 : activeIndex
    this.setState({ activeIndex })
    this.handleChange(activeIndex)
  }
  handleNext = () => {
    let { activeIndex } = this.state
    if (this.disableNext) return
    activeIndex = ++activeIndex >= this.totalCount ? 0 : activeIndex
    this.setState({ activeIndex })
    this.handleChange(activeIndex)
  }
  handleChange = (index: number) => {
    const { list, onChange } = this.props
    onChange && onChange(index, list[index])
  }
}
const styles: { [name: string]: React.CSSProperties } = {
  wrapper: {
    position: 'relative',
    display: 'flex',
    justifyContent: 'center',
    width: '100%'
  },
  content: {
    height: 210,
    position: 'relative'
  },
  btn: {
    position: 'absolute',
    top: '50%',
    transform: 'translateY(-50%)',
    width: 36,
    height: 36,
    zIndex: 99,
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    fontSize: 24
  }
}

card-item.tsx

import React from 'react'
const CardItem = ({ style, url }) => {
  return (
    <div
      style={{
        width: 375,
        height: 208,
        background: '#000',
        color: '#fff',
        borderRadius: 5,
        textAlign: 'center',
        ...style
      }}
    >
      <img src={url} width="100%" height="100%" />
    </div>
  )
}
export default CardItem

App.tsx

import CardSlider from './card-slider'
import CardItem from './card-item'
import './App.scss'
const list = [
  {
    name: '1',
    url: 'https://m15.360buyimg.com/mobilecms/jfs/t1/218369/27/14203/132191/6226a702E5a0b9236/a11294e884bc7635.jpg!cr_1053x420_4_0!q70.jpg'
  },
  {
    name: '2',
    url: 'https://m15.360buyimg.com/mobilecms/jfs/t1/158791/25/27003/106834/620c4bc2Efb15fc57/7c89841a597ce41b.jpg!cr_1053x420_4_0!q70.jpg'
  },
  {
    name: '3',
    url: 'https://m15.360buyimg.com/mobilecms/jfs/t1/117358/2/22877/138901/6228342eE68ae2c88/f8a9adb2642c1313.jpg!cr_1053x420_4_0!q70.jpg'
  },
  {
    name: '4',
    url: 'https://m15.360buyimg.com/mobilecms/jfs/t1/121592/2/24818/138081/622ccc8fEdf840f95/cd229433d699c70c.jpg!cr_1053x420_4_0!q70.jpg'
  },
  {
    name: '5',
    url: 'https://imgcps.jd.com/ling-cubic/danpin/lab/amZzL3QxLzE2Mjc4Mi8zNi85MTM4LzQ0NjQ1MS82MDQwN2Q4MUVkMDlmMWM5OC9jZWVmOWU0OWVkNzlkNjZkLnBuZw/6Zi_6L-q6L6-5pav6LeR5q2l6Z6L/5qmh6IO25aSW5bqV/60586f6fa1b18f3314204f2d/cr_1125x449_0_166/s/q70.jpg'
  },
  {
    name: '6',
    url: 'https://imgcps.jd.com/img-cubic/creative_server_cid/v2/2000755/10041170380456/FocusActivity/CkNqZnMvdDEvMjExMDQ2LzIyLzExMTc3Lzc0NTA0LzYxYTU4MzAwRWU1YjQ0OTcxL2Q5YjE5NzlmOGJkMjAzNzIuanBnEgs4NDIteGNfMF81MjABOPOOekIWChLkuprnkZ_lo6vot5HmraXpnosQAEIQCgzpkpzmg6DnmbvlnLoQAUIQCgznq4vljbPmiqLotK0QAkIKCgbkvJjpgIkQBw/cr_1053x420_4_0/s/q70.jpg'
  },
  {
    name: '7',
    url: 'https://m15.360buyimg.com/mobilecms/jfs/t1/117358/2/22877/138901/6228342eE68ae2c88/f8a9adb2642c1313.jpg!cr_1053x420_4_0!q70.jpg'
  }
]
export default function App() {
  return (
    <div style={{ paddingTop: '20%'}}>
      <CardSlider
        list={list}
        renderItem={CardItem}
        width={375}
        boxWidth={500}
        opacity={0.75}
        scale={0.9}
        disableNext={false}
        disablePrev={false}
        onChange={(index: number, data: any) => {
          console.log(index, data)
        }}
      />
    </div>
  )
}

以上就是react card slider實現(xiàn)滑動卡片教程的詳細內(nèi)容,更多關于react card slider卡片滑動的資料請關注腳本之家其它相關文章!

相關文章

  • 詳解React項目如何修改打包地址(編譯輸出文件地址)

    詳解React項目如何修改打包地址(編譯輸出文件地址)

    這篇文章主要介紹了詳解React項目如何修改打包地址(編譯輸出文件地址),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-03-03
  • React配置子路由的實現(xiàn)

    React配置子路由的實現(xiàn)

    本文主要介紹了React配置子路由的實現(xiàn),我們來通過一個簡單的例子解釋一下如何配置子路由,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 如何強制刷新react hooks組件

    如何強制刷新react hooks組件

    這篇文章主要介紹了如何強制刷新react hooks組件問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • react源碼層探究setState作用

    react源碼層探究setState作用

    寫react的時候,踩了幾次坑發(fā)現(xiàn)setstate之后state不會立刻更新,于是判定setstate就是異步的方法,但是直到有一天,我想立刻拿到更新的state去傳參另一個方法的時候,才問自己,為什么setstate是異步的?準確地說,在React內(nèi)部機制能檢測到的地方,setState就是異步的
    2022-10-10
  • react 父子組件之間通訊props

    react 父子組件之間通訊props

    這篇文章主要介紹了react 父子組件之間通訊props,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • react表單受控的實現(xiàn)方案

    react表單受控的實現(xiàn)方案

    數(shù)據(jù)的受控控制一直是react里的一個痛點,當我想要實現(xiàn)一個輸入框的受控控制時,我需要定義一個onChange和value,手動去實現(xiàn)數(shù)據(jù)的綁定,本文小編給大家介紹了react表單受控的實現(xiàn)方案,需要的朋友可以參考下
    2023-12-12
  • React Hook useState useEffect componentDidMount componentDidUpdate componentWillUnmount問題

    React Hook useState useEffect componentD

    這篇文章主要介紹了React Hook useState useEffect componentDidMount componentDidUpdate componentWillUnmount問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • 淺談react路由傳參的幾種方式

    淺談react路由傳參的幾種方式

    這篇文章主要介紹了淺談react路由傳參的幾種方式,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • 在Create React App中使用CSS Modules的方法示例

    在Create React App中使用CSS Modules的方法示例

    本文介紹了如何在 Create React App 腳手架中使用 CSS Modules 的兩種方式。有一定的參考價值,有需要的朋友可以參考一下,希望對你有所幫助。
    2019-01-01
  • redux副作用處理之redux-thunk使用

    redux副作用處理之redux-thunk使用

    這篇文章主要介紹了redux副作用處理之redux-thunk使用方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評論