首页 > 解决方案 > 盒子顺序动画

问题描述

我有一组连续排列的盒子,每个盒子都有它的价值和背景颜色。最终,盒子改变了它的位置,我想为它制作动画。

这就是我能够在下面或(CodePen )下做的代码,它很好,但是当我再添加 5 个框(需要有 6 个)时,动画(过渡)有时只是跳过自身,框有点跳到那个地方,你可以在这里看到

function shuffle(a) {
    for (let i = a.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [a[i], a[j]] = [a[j], a[i]];
    }
    return a;
}

const BOX_COLOR = {
  1: "red",
  2: "blue",
  3: "green",
  4: "black",
  5: "orange",
  6: "yellow"
};


class App extends React.Component {
  state = {
    value: [1]
  }

  componentDidMount = () => {                 
    setInterval(() => {
      let newArr = shuffle(this.state.value)
      this.setState({ value: newArr})
    }, 2000);
  }
  
  render() {
     let order = this.state.value.map((BoxValue, BoxOrder) => { // BoxOrder is position of the box
      let classColor = BOX_COLOR[BoxValue]; // because each number has different color
      let classOrder = null; // and this should dictate on what position should that box be
      let randomPosition = Math.floor(Math.random() * 6) + 1 // generate random box position 
      switch (randomPosition) {
        case 1:
          classOrder = "first";
          break;
        case 2:
          classOrder = "second";
          break;
        case 3:
          classOrder = "third";
          break;
        case 4:
          classOrder = "fourth";
          break;
        case 5:
          classOrder = "fifth";
          break;
        case 6:
          classOrder = "sixth";
          break;
        default:
          break;
      }
      return (
        <div key={BoxValue} className={["box", classColor, classOrder].join(" ")}>
          {BoxValue}
        </div>
      );
    });
    return (
    <div className="container">
       {order} 
    </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'));
.container {
  border: 5px solid #666;
  height: 100px;
  width: 600px;
  display: flex;
  position: relative;
}

.box {
  border: 5px solid #999;
  background: red;
  width: 100px;
  height: 100%;
  padding: 20px;
  font-size: 50px;
  text-align: center;
  color: white;
  position: absolute;
  transition: transform 700ms ease-in-out;
  left: 0;
  top: 0;
  box-sizing: border-box;
}

.red {
  background: red;
}

.blue {
  background: blue;
}

.green {
  background: green;
}

.black {
  background: black;
}

.orange {
  background: orange;
}

.yellow {
  background: yellow;
}

.first {
  transform: translateX(0);
}

.second {
  transform: translateX(100px);
}

.third {
  transform: translateX(200px);
}

.fourth {
  transform: translateX(300px);
}

.fifth {
  transform: translateX(400px);
}

.sixth {
  transform: translateX(500px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app">
</div>

你怎么看,这里有什么问题,我只是想让动画像只有一个盒子一样流畅?

标签: javascriptcssreactjsanimationcss-animations

解决方案


我认为您正在使用BoxValueasBoxOrder和反之亦然。只需将它们切换到您在渲染方法中使用它的位置。替换BoxValueBoxOrder + 1并替换BoxOrder + 1BoxValue。(我认为在 3 个地方,我已经添加了评论)

请参阅下面的片段:

function shuffle(a) {
    for (let i = a.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [a[i], a[j]] = [a[j], a[i]];
    }
    return a;
}

const BOX_COLOR = {
  1: "red",
  2: "blue",
  3: "green",
  4: "black",
  5: "orange",
  6: "yellow"
};


class App extends React.Component {
  state = {
    value: [1, 2, 3, 4, 5, 6]
  }

  componentDidMount = () => {                 
    setInterval(() => {
      let newArr = shuffle(this.state.value)
      this.setState({ value: newArr})
    }, 2000);
  }
  
  render() {
     let order = this.state.value.map((BoxValue, BoxOrder) => { // BoxOrder is position of the box
      let classColor = BOX_COLOR[BoxOrder+1]; // because each number has different color
//CHANGED BoxValue TO BoxOrder+1
      let classOrder = null; // and this should dictate on what position should that box be
      let randomPosition = Math.floor(Math.random() * 6) + 1 // generate random box position 
      switch (BoxValue) {//CHANGED BoxOrder+1 TO BoxValue
        case 1:
          classOrder = "first";
          break;
        case 2:
          classOrder = "second";
          break;
        case 3:
          classOrder = "third";
          break;
        case 4:
          classOrder = "fourth";
          break;
        case 5:
          classOrder = "fifth";
          break;
        case 6:
          classOrder = "sixth";
          break;
        default:
          break;
      }
      return (
        <div key={BoxOrder +1} className={["box", classColor, classOrder].join(" ")}>
          {BoxOrder +1}
        </div>
      );
      //CHANGED BoxValue TO BoxOrder+1 
    });
    return (
    <div className="container">
       {order} 
    </div>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('app'));
.container {
  border: 5px solid #666;
  height: 100px;
  width: 600px;
  display: flex;
  position: relative;
}

.box {
  border: 5px solid #999;
  background: red;
  width: 100px;
  height: 100%;
  padding: 20px;
  font-size: 50px;
  text-align: center;
  color: white;
  position: absolute;
  transition: transform 700ms ease-in-out;
  left: 0;
  top: 0;
  box-sizing: border-box;
}

.red {
  background: red;
}

.blue {
  background: blue;
}

.green {
  background: green;
}

.black {
  background: black;
}

.orange {
  background: orange;
}

.yellow {
  background: yellow;
}

.first {
  transform: translateX(0);
}

.second {
  transform: translateX(100px);
}

.third {
  transform: translateX(200px);
}

.fourth {
  transform: translateX(300px);
}

.fifth {
  transform: translateX(400px);
}

.sixth {
  transform: translateX(500px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app">
</div>

你也可以在这里测试


推荐阅读