antdパッケージ時間軸に基づいて(antdがあなたを満たすことができないとき);


**
antdパッケージ時間軸に基づいて(antdがあなたを満たすことができないとき);
**何事も初めは难しくて、ずっとブログを书きたいと思って、自分のものを分かち合って、科室は仕方なく仕事が比较的に忙しくて、何を书くのがいいか分からないで、浅すぎるでしょう、面白くないと思って、深すぎるでしょう、私もできません、ちょうど会社は最近私达にいくつかのコンポーネントを包装して、花を借りて仏を捧げて分かち合いましょう!前にも书いたことがないでしょうハハ..
まず、このコンポーネントの様子を見てみましょう.
主な機能は次のとおりです.
  • コンポーネントの内部展示内容は任意に編集され、コンポーネントのより良い多重化(timeLineHTML)を実現する.
  • 左右の矢印をクリックすると、時間軸を左右にスライドさせることができ、毎回の移動量はセル数を基準とし、クリックできない場合はマウスポインタに相応のヒントを与え、マウスは時間軸の真ん中の任意の位置をドラッグして同じ効果を実現することができる(mouseSliding).
  • コンポーネントは、親要素の幅が高く、画面幅が変化したときに応答するように自動的に適応することができる.

  • 次にコードと考え方を見てみましょう.まず、コンポーネントのスタイルの左右の2つのボタンを観察し、幅が固定され、応答式の変化は主に中間部分の幅であり、antdグループ価格はLayoutレイアウトを使用して書かれ、コードは以下の通りである.
    レイアウトが決まったので、残りは書かないと思います.注意しなければならないのは、componentDidMountのライフサイクルでページの最初の更新を記録したとき、各セルの位置を初期位置として、マウスがトリガーしたスクロールがどのように実現されているかです.くだらないことを言わないで直接コードをつけます.
    //        
      timeLineClick = (direction) => {
        const {moveCount} = this.props;
        let self = this;
    
        //          
        if (!this.allowClick) return;
    
        //    scrollLeft        scrollLeft           
        let lastPositionLeft = $('.diagnosis_box').eq(this.timeLineHTMLArr.length - 1).position().left;
        let lastWidth = $('.diagnosis_box').eq(this.timeLineHTMLArr.length - 1).width();
        let timeLinBoxWidth = $('#time_line_box').width() + _padding;
    
        if (direction === 'left' && $('.diagnosis_box').eq(0).position().left >= _padding) {
          return;
        }
        else if (direction === 'right') {
          if (Math.floor(lastPositionLeft + lastWidth) <= timeLinBoxWidth) {
            return
          }
        }
    
        this.allowClick = false;
        //         scrollLeft               this.timeLineCounter
        let currentPosition = $('#time_line_box').scrollLeft() + _padding;
        if (this.isResize || (direction === 'left' && Math.floor(lastPositionLeft + lastWidth) <= timeLinBoxWidth)) {
          this.timeLineHTMLArr.some((item, index) => {
            if (index < this.timeLineHTMLArr.length - 1
              && item <= currentPosition
              && currentPosition <= this.timeLineHTMLArr[index + 1]
            ) {
              this.timeLineCounter = this.isResize ? index + 1 : index
            }
          });
        }
    
        let count = 0;
        //       timeline
        if (direction === 'left') {
          if (this.timeLineCounter >= 0) {
    
            this.timeLineCounter = this.timeLineCounter - moveCount >= 0
              ? this.timeLineCounter - moveCount
              : 0;
            let leftCount = Math.floor((currentPosition - self.timeLineHTMLArr[self.timeLineCounter]) / 5);
            let displacementTime = 200 / leftCount;
    
            function moveLeft(count) {
              setTimeout(() => {
                self.isResize = false;
                let counts = count + 1;
                let _left = currentPosition - _padding - counts * 5;
                $('#time_line_box').scrollLeft(_left);
                if (leftCount > count) {
                  moveLeft(counts);
                }
                else {
                  self.allowClick = true;
    
                  let newLastPositionLeft = $('.diagnosis_box').eq(self.timeLineHTMLArr.length - 1).position().left;
                  self.setState({
                    left: self.timeLineCounter === 0 ? false : true,
                    right: Math.floor(newLastPositionLeft + lastWidth) <= timeLinBoxWidth ? false : true
                  });
                }
              }, displacementTime)
            }
    
            moveLeft(count);
          }
        }
        else if (direction === 'right') {
          if (this.timeLineCounter <= this.timeLineHTMLArr.length - 1) {
    
            this.timeLineCounter = this.timeLineCounter + moveCount < this.timeLineHTMLArr.length - 1
              ? this.timeLineCounter + moveCount
              : this.timeLineHTMLArr.length - 1;
    
            let leftCount = Math.floor((self.timeLineHTMLArr[self.timeLineCounter] - currentPosition) / 5);
            let displacementTime = 200 / leftCount;
    
            function moveRight(count) {
              setTimeout(() => {
                self.isResize = false;
                let counts = count + 1;
                let _left = currentPosition - _padding + counts * 5;
                $('#time_line_box').scrollLeft(_left);
    
                if (leftCount > count) {
                  moveRight(counts);
                }
                else {
                  self.allowClick = true;
    
                  let newLastPositionLeft = $('.diagnosis_box').eq(self.timeLineHTMLArr.length - 1).position().left;
                  self.setState({
                    left: self.timeLineCounter === 0 ? false : true,
                    right: Math.floor(newLastPositionLeft + lastWidth) <= timeLinBoxWidth ? false : true
                  });
                }
              }, displacementTime)
            }
    
            moveRight(count);
          }
        }
      };

    ここでのロジックは主にマウスクリックでトリガーされるプロセスであり、注意すべき点はいくつかあります.
  • 第1変位には時間がかかるので、私たちは唯一の過程で、変位が終わる前にクリックイベントを受け入れないスロットルを作る必要があります.
  • それぞれのシフト単位の距離が異なるため、セルの長いシフト時間も長すぎて、視覚効果もあまりよくないので、中では毎回のシフト時間を200に固定し、settimeoutで再帰的に呼び出します.
  • コンポーネントをカプセル化するときに気まずい問題が発生し、最初のセルが左端にないときにマウスドラッグブラウザが揺れてサイズを変えると、ページが変化し、計算された位置にずれが生じる(マウスドラッグで変位する場合もこのような処理が必要)ため、コードには
  • という処理があります.
    オフセット量を修正することを目的とする.残りはあまり言わないでコードを直接見ましょう.
    import React, {PureComponent} from 'react';
    import styles from './TimeLine.less';
    import {Icon, Layout} from 'antd';
    import $ from "jquery";
    import PropTypes from 'prop-types';
    /*
    *                             TimeLineHTML  
    *         className = diagnosis_box;       diagnosis_box     
    *                  
    * _padding  time_line_box   padding               
    * */
    const _padding = 24;
    const {Sider, Content} = Layout;
    
    let eleDrag = false;
    
    class TimeLine extends PureComponent {
      static propTypes = {
        timeLineHTML: PropTypes.array.isRequired, //     
        moveCount: PropTypes.number, //         
        height: PropTypes.number,
        mouseSliding: PropTypes.bool //           
      };
    
      static defaultProps = {
        moveCount: 3,
        height: 65,
        mouseSliding: true
      };
    
      constructor(props) {
        super(props);
        this.state = {
          left: false,
          right: true
        };
        this.timeLineHTMLArr = [];
        this.timeLineCounter = 0;
        this.allowClick = true;
        this.isResize = false;
        this.initClientX = null;
      }
    
      componentDidMount() {
        let self = this;
        //            positionleft         
        if (!this.timeLineHTMLArr.length) {
          $('.diagnosis_box').each(function () {
            self.timeLineHTMLArr.push($(this).position().left);
          });
        }
        window.onresize = () => {
          let target = this;
          if (target.resizeFlag) {
            clearTimeout(target.resizeFlag);
          }
          target.resizeFlag = setTimeout(function () {
            self.isResize = true;
            target.resizeFlag = null;
          }, 100);
        };
      }
    
      //        
      timeLineClick = (direction) => {
        const {moveCount} = this.props;
        let self = this;
    
        //          
        if (!this.allowClick) return;
    
        //    scrollLeft        scrollLeft           
        let lastPositionLeft = $('.diagnosis_box').eq(this.timeLineHTMLArr.length - 1).position().left;
        let lastWidth = $('.diagnosis_box').eq(this.timeLineHTMLArr.length - 1).width();
        let timeLinBoxWidth = $('#time_line_box').width() + _padding;
    
        if (direction === 'left' && $('.diagnosis_box').eq(0).position().left >= _padding) {
          return;
        }
        else if (direction === 'right') {
          if (Math.floor(lastPositionLeft + lastWidth) <= timeLinBoxWidth) {
            return
          }
        }
    
        this.allowClick = false;
        //         scrollLeft               this.timeLineCounter
        let currentPosition = $('#time_line_box').scrollLeft() + _padding;
        if (this.isResize || (direction === 'left'
            && Math.floor(lastPositionLeft + lastWidth) <= timeLinBoxWidth)) {
          this.timeLineHTMLArr.some((item, index) => {
            if (index < this.timeLineHTMLArr.length - 1
              && item <= currentPosition
              && currentPosition <= this.timeLineHTMLArr[index + 1]
            ) {
              this.timeLineCounter = this.isResize ? index + 1 : index
            }
          });
        }
    
        let count = 0;
        //       timeline
        if (direction === 'left') {
          if (this.timeLineCounter >= 0) {
    
            this.timeLineCounter = this.timeLineCounter - moveCount >= 0
              ? this.timeLineCounter - moveCount
              : 0;
            let leftCount = Math.floor((currentPosition - self.timeLineHTMLArr[self.timeLineCounter]) / 5);
            let displacementTime = 200 / leftCount;
    
            function moveLeft(count) {
              setTimeout(() => {
                self.isResize = false;
                let counts = count + 1;
                let _left = currentPosition - _padding - counts * 5;
                $('#time_line_box').scrollLeft(_left);
                if (leftCount > count) {
                  moveLeft(counts);
                }
                else {
                  self.allowClick = true;
    
                  let newLastPositionLeft = $('.diagnosis_box').eq(self.timeLineHTMLArr.length - 1).position().left;
                  self.setState({
                    left: self.timeLineCounter === 0 ? false : true,
                    right: Math.floor(newLastPositionLeft + lastWidth) <= timeLinBoxWidth ? false : true
                  });
                }
              }, displacementTime)
            }
    
            moveLeft(count);
          }
        }
        else if (direction === 'right') {
          if (this.timeLineCounter <= this.timeLineHTMLArr.length - 1) {
    
            this.timeLineCounter = this.timeLineCounter + moveCount < this.timeLineHTMLArr.length - 1
              ? this.timeLineCounter + moveCount
              : this.timeLineHTMLArr.length - 1;
    
            let leftCount = Math.floor((self.timeLineHTMLArr[self.timeLineCounter] - currentPosition) / 5);
            let displacementTime = 200 / leftCount;
    
            function moveRight(count) {
              setTimeout(() => {
                self.isResize = false;
                let counts = count + 1;
                let _left = currentPosition - _padding + counts * 5;
                $('#time_line_box').scrollLeft(_left);
    
                if (leftCount > count) {
                  moveRight(counts);
                }
                else {
                  self.allowClick = true;
    
                  let newLastPositionLeft = $('.diagnosis_box').eq(self.timeLineHTMLArr.length - 1).position().left;
                  self.setState({
                    left: self.timeLineCounter === 0 ? false : true,
                    right: Math.floor(newLastPositionLeft + lastWidth) <= timeLinBoxWidth ? false : true
                  });
                }
              }, displacementTime)
            }
    
            moveRight(count);
          }
        }
      };
    
      //            
      onMouseDown = (e) => {
        e.stopPropagation();
        e.preventDefault();
        eleDrag = true;
        this.initClientX = e.clientX;
      };
    
      onMouseMoveCapture = (e) => {
        e.stopPropagation();
        e.preventDefault();
        if (!this.allowClick) return;
        if (eleDrag) {
          let currentPosition = $('#time_line_box').scrollLeft();
    
          if (this.initClientX > e.clientX) { //       
            let lastPositionLeft = $('.diagnosis_box').eq(this.timeLineHTMLArr.length - 1).position().left;
            let lastWidth = $('.diagnosis_box').eq(this.timeLineHTMLArr.length - 1).width();
            let timeLinBoxWidth = $('#time_line_box').width() + _padding;
            if (Math.floor(lastPositionLeft + lastWidth) <= timeLinBoxWidth) {
              return
            }
            let displacement = this.initClientX - e.clientX;
            $('#time_line_box').scrollLeft(currentPosition + displacement);
          }
          else if (this.initClientX < e.clientX) {//       
            if ($('.diagnosis_box').eq(0).position().left >= _padding) {
              return;
            }
            let displacement = currentPosition - (e.clientX - this.initClientX);
            $('#time_line_box').scrollLeft(displacement);
          }
          this.initClientX = e.clientX;
        }
      };
    
      noDragging = (e) => {
        e.stopPropagation();
        e.preventDefault();
        eleDrag = false;
        this.initClientX = null;
      };
    
      render() {
        const {
          props: {
            timeLineHTML,
            height,
            mouseSliding
          },
          state: {
            left,
            right,
          }
        } = this;
        return (
          
    { if ($('.diagnosis_box').eq(0).position().left >= _padding - 0.01) { this.setState({left: false}); } else { this.setState({left: true}); } }} onClick={() => { this.timeLineClick('left') }} /> {mouseSliding ?
    {timeLineHTML}
    :
    {timeLineHTML}
    }
    { let lastPositionLeft = $('.diagnosis_box').eq(this.timeLineHTMLArr.length - 1).position().left; let lastWidth = $('.diagnosis_box').eq(this.timeLineHTMLArr.length - 1).width(); let timeLinBoxWidth = $('#time_line_box').width() + _padding; if (Math.floor(lastPositionLeft + lastWidth) <= timeLinBoxWidth) { this.setState({right: false}); } else { this.setState({right: true}); } }} onClick={() => { this.timeLineClick('right') }} />
    ) } } export default TimeLine;

    次は対応するlessです.
    .TimeLine{
      height: 100%;
      :global{
        .ant-layout.ant-layout-has-sider{
          height: 100%;
        }
      }
    
      .time_line_box{
        position: relative;
        padding: 0 24px;
        height: 100%;
        overflow: hidden;
        white-space: nowrap;
      }
    }

    次は技術のまとめです.主にこのコンポーネントに注意しなければならない点を説明します.
  • マウスクリックイベントは判断する必要があり、唯一の過程で次のクリックイベントを禁止しなければならない.
  • 次にマウスをドラッグした後、再びクリックして移動したり、画面幅が変化した後、クリックした場合、オフセット位置を補正する必要があります.
  • マウスがクリックできない場合の臨界判断に注意する.