旋转老虎机在第一次旋转后是不可预测的

问题描述 投票:0回答:1

我有这个组件,应该模拟一台老虎机,使其旋转到编号的面,成为传递到props.slots的编号。

它第一次起作用,但是在初始旋转后似乎不起作用。我什至无法用手预测它将落在哪个数字上。我的数学怎么了?

我有5张脸,所以我在每张脸之间划分了360/5 = 72度。

然后有(current - next) * 72deg,但这不能给我正确的面孔!

const {
  useEffect,
  useRef,
  useState
} = React;

function rnd(min, max) {
  return Math.floor(Math.random() * (max - min)) + min
}

const SlotMachine = (props) => {
  const ringElements = useRef();
  const [state, setState] = useState({
    manual: true,
    rings: [],
    slots: []
  });
  const slotMap = {
    0: 0,
    1: 72,
    2: 144,
    3: 216,
    4: 288
  };

  useEffect(() => {
    const newState = { ...state,
      slots: props.slots,
      manual: false
    };
    setState(newState);
  }, [props.slots]);

  useEffect(() => {
    if (state.manual === false) {
      rotate();
    }
    setState({ ...state,
      manual: true
    });
  }, [state.manual]);

  const rotate = () => {
    let reRing = [];
    state.rings.forEach((el, i) => {
      console.log(`--- RING ${i} ----`);
      console.log(`----ROTATE FROM ${state.rings[i].curr} ROTATE TO ${state.slots[i]} Face ---`);
      console.log(state);
      let obj = el;
      let element = obj.ringElement;
      console.log(element);
      let turns = (obj.curr - state.slots[i]);
      let move = (obj.curr === null) ? slotMap[state.slots[i]] : (turns * 72);
      console.log(`TURN BY ${turns}`);
      //move += (360 * rnd(3,6));
      console.log(`rotateX(${move}deg) for ring${i}`);
      element.style.transform = `rotateX(${move}deg)`;
      console.log(`storing ${state.slots[i]} as the obj.curr replacing ${obj.curr}`);
      obj.curr = state.slots[i];
      reRing = [...reRing, obj];
    });
    console.log('update rings:');
    setState({ ...state,
      rings: reRing
    });
  }

  useEffect(() => {
    let mountRings = [];
    Array.from(ringElements.current.children).forEach((el, i) => {
      let obj = {};
      obj.ringElement = el;
      obj.curr = null;
      mountRings = [...mountRings, obj];
    });
    console.log(mountRings);
    setState({ ...state,
      rings: mountRings
    });
  }, []);

  return(
    <div>
      <div className="slots">
        <div className="rings" ref={ringElements}>
          <div className="ring">
            <div className="slot" id="0">0</div>
            <div className="slot" id="1">1</div>
            <div className="slot" id="2">2</div>
            <div className="slot" id="3">3</div>
            <div className="slot" id="4">4</div>
          </div>
          <div className="ring">
          <div className="slot" id="0">0</div>
          <div className="slot" id="1">1</div>
          <div className="slot" id="2">2</div>
          <div className="slot" id="3">3</div>
          <div className="slot" id="4">4</div>
          </div>
          <div className="ring">
          <div className="slot" id="0">0</div>
          <div className="slot" id="1">1</div>
          <div className="slot" id="2">2</div>
          <div className="slot" id="3">3</div>
          <div className="slot" id="4">4</div>
          </div>
        </div>
      </div>
      <button className="spin-button" onClick={() => { state.manual ? rotate() : setState({...state, manual:true })  }}>SPIN</button>
    </div>
  );
}

ReactDOM.render(
  <SlotMachine slots={3} />,
  document.getElementById('app')
);
:root {
  --pushZ: 27vmin;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Rozha One", serif;
  font-size: 4vmin;
  color: #d99748;
  user-select: none;
}

body,
.slots,
.rings,
.ring,
.slot,
.spin {
  display: flex;
  justify-content: center;
  align-items: center;
  transform-style: preserve-3d;
}

body {
  flex-direction: column;
}

body {
  justify-content: space-around;
  width: 100%;
  height: 100vh;
  background: #1F1F1F;
}

.slots {
  position: relative;
  width: 120vmin;
  height: 50vmin;
}

.slots>* {
  height: 100%;
}

.rings {
  width: 50%;
  perspective: 250vmin;
}

.ring {
  position: relative;
  width: calc(100% / 3);
  height: 100%;
  transition: 3s ease-in-out;
}

.slot {
  position: absolute;
  width: 100%;
  height: 45%;
  font-size: 15vmin;
  background: rgba(31, 31, 31, 0.935);
}


/* rotate goes from away */

.slot:nth-child(1) {
  color: red;
  transform: rotateX(360deg) translateZ(var(--pushZ));
}

.slot:nth-child(2) {
  color: green;
  transform: rotateX(288deg) translateZ(var(--pushZ));
}

.slot:nth-child(3) {
  color: blue;
  transform: rotateX(216deg) translateZ(var(--pushZ));
}

.slot:nth-child(4) {
  color: purple;
  transform: rotateX(144deg) translateZ(var(--pushZ));
}

.slot:nth-child(5) {
  color: orange;
  transform: rotateX(72deg) translateZ(var(--pushZ));
}

.spin-button {
  width: 14vmin;
  height: 14vmin;
  transform: rotateX(45deg);
  border: 0.3333333333vmin solid;
  border-radius: 50%;
  font-size: 4.5454545455vmin;
  color: #b57e3c;
  background: transparent;
  outline: none;
  cursor: pointer;
  transition: 0.3s;
}

.spin-button:hover {
  color: #d99748;
}

.spin-button:active {
  color: #ffca60;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script>

<div id="app"></div>
javascript reactjs transform css-transforms
1个回答
0
投票

解决了我的问题!旋转总是从“原点”开始。无需从上一轮旋转重新定向。

    element.style.transform = `rotateX(${move}deg)`;
© www.soinside.com 2019 - 2024. All rights reserved.