最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

效果

實(shí)現(xiàn)

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

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:右側(cè):-1:左側(cè)
   */
  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實(shí)現(xiàn)滑動卡片教程的詳細(xì)內(nèi)容,更多關(guān)于react card slider卡片滑動的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 一文詳解React如何處理表單的復(fù)雜驗(yàn)證邏輯

    一文詳解React如何處理表單的復(fù)雜驗(yàn)證邏輯

    這篇文章主要為大家詳細(xì)介紹了React中如何處理表單的復(fù)雜驗(yàn)證邏輯,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • React類組件和函數(shù)組件對比-Hooks的簡介

    React類組件和函數(shù)組件對比-Hooks的簡介

    Hook?是?React?16.8?的新增特性,它可以讓我們在不編寫class的情況下,?使用state以及其他的React特性(比如生命周期,這篇文章主要介紹了React類組件和函數(shù)組件對比-Hooks的介紹及初體驗(yàn),需要的朋友可以參考下
    2022-11-11
  • React配置Redux并結(jié)合本地存儲設(shè)置token方式

    React配置Redux并結(jié)合本地存儲設(shè)置token方式

    這篇文章主要介紹了React配置Redux并結(jié)合本地存儲設(shè)置token方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • React實(shí)現(xiàn)卡片拖拽效果流程詳解

    React實(shí)現(xiàn)卡片拖拽效果流程詳解

    這篇文章主要介紹了React Web開發(fā)實(shí)戰(zhàn)示例,實(shí)現(xiàn)卡片拖拽效果,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-11-11
  • 淺談react-native熱更新react-native-pushy集成遇到的問題

    淺談react-native熱更新react-native-pushy集成遇到的問題

    下面小編就為大家?guī)硪黄獪\談react-native熱更新react-native-pushy集成遇到的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • react中form.setFieldvalue數(shù)據(jù)回填時 value和text不對應(yīng)的問題及解決方法

    react中form.setFieldvalue數(shù)據(jù)回填時 value和text不對應(yīng)的問題及解決方法

    這篇文章主要介紹了react中form.setFieldvalue數(shù)據(jù)回填時 value和text不對應(yīng)的問題及解決方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07
  • 詳解如何在項(xiàng)目中使用jest測試react native組件

    詳解如何在項(xiàng)目中使用jest測試react native組件

    本篇文章主要介紹了詳解如何在項(xiàng)目中使用jest測試react native組件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • 詳解React項(xiàng)目中碰到的IE問題

    詳解React項(xiàng)目中碰到的IE問題

    這篇文章主要介紹了React項(xiàng)目中碰到的IE問題,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • Input標(biāo)簽自動校驗(yàn)功能去除實(shí)現(xiàn)

    Input標(biāo)簽自動校驗(yàn)功能去除實(shí)現(xiàn)

    這篇文章主要為大家介紹了Input標(biāo)簽的自動拼寫檢查功能去除實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • react簡單實(shí)現(xiàn)防抖和節(jié)流

    react簡單實(shí)現(xiàn)防抖和節(jié)流

    在日常開發(fā)中,我們經(jīng)常會有防抖和節(jié)流的需要,可以減小服務(wù)器端壓力,提升用戶體驗(yàn),本文就詳細(xì)的介紹了react簡單實(shí)現(xiàn)防抖和節(jié)流,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05

最新評論

棋牌| 玉门市| 罗源县| 康定县| 顺昌县| 望都县| 麦盖提县| 扬中市| 北流市| 临江市| 茂名市| 大理市| 东安县| 黎川县| 禹城市| 萨嘎县| 滦南县| 黔南| 古浪县| 通辽市| 噶尔县| 饶平县| 敦煌市| 德钦县| 隆回县| 桦南县| 彩票| 友谊县| 马尔康县| 尚义县| 兴业县| 汽车| 丰顺县| 高尔夫| 奉化市| 精河县| 鹤山市| 娱乐| 五常市| 沂南县| 灵寿县|