尝试将 GSAP 滚动骰子动画更新为 React 并产生奇怪的效果

Trying to update a GSAP rolling dice animation to React and Having weird effects

我在 GitHub 上发现了一个非常棒的 Gsap 动画:https://github.com/mthomps4/Dice-Roll

看起来很棒,但我想在 React 中使用。我已经让它在表面上工作得更少了,但是当我掷骰子时,骰子上显示的内容和存储的记录不匹配。他们总是很奇怪,但不合逻辑。

IE:

Shown    Console Log
 1           0
 2           2
 5           3
 6           1

这些也是我可以开始工作的仅有的 4 个值。我尝试调整生成随机数的代码:

const startRoll = function () {
        console.log('RUN!');
        let randomNum = Math.floor(Math.random() * 3); //between 0 and 5

const faceRoll = function () {
        let randomNum = Math.floor(Math.random() * 6); //between 0 and 5

(评论来自原始仓库)

请告诉我如何完善这个小骰子,掷骰子,因为它看起来很棒而且快完成了。真的希望我能让它工作,提前致谢。

JSX

export default function Dice() {
    //////////// Copy Pasta ////////

    const cubeRef = useRef();
    const sceneRef = useRef();

    let i = 90;
    let j = 0;

    //Main DOM Variables and Selectors

    //Selects Cube Face X via CSS Degree Rotatation
    const cubeFace = [
        'translateX(200px)',
        'rotateX(90deg)',
        'rotateX(180deg)',
        'rotateX(270deg)',
    ];

    TweenMax.set(sceneRef.current, { perspective: 0 });

    //Rotates through cubeFace array on each click.
    //If i>cubeFace reset to 0 and preform 1st step.

    const RotateY = function () {
        TweenMax.to(cubeRef.current, 0.5, {
            transform: cubeFace[i],
            ease: Linear.easeNone,
        });

        if (i < cubeFace.length) {
            i++;
            console.log(i);
        } else {
            i = 1;
            TweenMax.to(cubeRef.current, 0.5, {
                transform: cubeFace[0],
                ease: Linear.easeNone,
            });
            console.log(i);
        }
    }; //RotateY Function

    const RotateX = function () {
        TweenMax.to(cubeRef.current, 0.5, { transform: 'rotateY(' + i + 'deg)' });
        i += 90;
    };

    //Random Experimental Scene
    const tl = new TimelineMax({ paused: true, repeat: 3 });
    tl.yoyo(true);
    tl.to(cubeRef.current, 1, { rotation: 360 })

        .to(cubeRef.current, 1, { rotationY: 360, rotationX: 360 }, '-=1')
        .to(sceneRef.current, 1, { scale: 0.2 }, '-=1')
        .to(cubeRef.current, 1, { x: 500 }, '-=1');

    tl.timeScale(1);

    const start = function () {
        tl.restart();
    };

    //TweenMax would not take Array String used if statement
    // const cubeRef.currentFace2 = [
    //   "rotationY:0, rotationX:0",
    //   "rotationX:90",
    //   "rotationX:180",
    //   "rotationX:270",
    //   "rotationY:90",
    //   "rotationY:180"];
    // const rl = new TimelineMax({onComplete:faceRoll});

    //Roll Die Timeline
    const startRoll = function () {
        console.log('RUN!');
        let randomNum = Math.floor(Math.random() * 3); //between 0 and 5
        let rl = new TimelineMax({ onComplete: faceRoll });
        rl.to(cubeRef.current, 0.01, { rotationY: 0, rotationX: 0 });
        rl.to(cubeRef.current, 3, { rotationY: 1800, rotationX: 1800 });
        rl.to(sceneRef.current, 3, { scale: 0.2 }, '-.1');
        rl.timeScale(4);
        rl.restart();
    };

    const faceRoll = function () {
        let randomNum = Math.floor(Math.random() * 6); //between 0 and 5
        if (randomNum === 0) {
            TweenMax.to(cubeRef.current, 0.2, { rotationY: 0, rotationX: 0 }, '-1');
            TweenMax.to(sceneRef.current, 0.2, { scale: 1 }, '-1');
        }
        if (randomNum === 1) {
            TweenMax.to(cubeRef.current, 0.2, { rotationX: 90, scale: 1 }, '-1');
            TweenMax.to(sceneRef.current, 0.2, { scale: 1 }, '-1');
        }
        if (randomNum === 2) {
            TweenMax.to(cubeRef.current, 0.2, { rotationX: 180, scale: 1 }, '-1');
            TweenMax.to(sceneRef.current, 0.2, { scale: 1 }, '-1');
        }
        if (randomNum === 3) {
            TweenMax.to(cubeRef.current, 0.2, { rotationX: 270, scale: 1 }, '-1');
            TweenMax.to(sceneRef.current, 0.2, { scale: 1 }, '-1');
        }
        if (randomNum === 4) {
            TweenMax.to(cubeRef.current, 0.2, { rotationY: 90, scale: 1 }, '-1');
            TweenMax.to(sceneRef.current, 0.2, { scale: 1 }, '-1');
        }
        if (randomNum === 5) {
            TweenMax.to(cubeRef.current, 0.2, { rotationY: 270, scale: 1 }, '-1');
            TweenMax.to(sceneRef.current, 0.2, { scale: 1 }, '-1');
        }
        console.log(randomNum);
    }; //FaceRoll If Statement

    /////////////////////

    return (
        <DiceWrap>
            <header>
                <h1> Random Die Throw </h1>
                <h3> Cube Rotation and Animation </h3>
            </header>

            <div id="box1">
                <div className="scene" ref={sceneRef}>
                    <div className="cube" ref={cubeRef}>
                        <div className="cube-face front-face rfront"></div>
                        <div className="cube-face back-face rback"></div>
                        <div className="cube-face left-face rleft"></div>
                        <div className="cube-face right-face rright"></div>
                        <div className="cube-face top-face rtop"></div>
                        <div className="cube-face bottom-face rbottom"></div>
                    </div>
                </div>
            </div>

            <div id="Roll">
                <button id="RollDie" onClick={startRoll}>
                    Roll Die
                </button>
            </div>

            <div id="animations">
                <button id="StartB" onClick={RotateX}>
                    Rotate X
                </button>
                <button id="StartA" onClick={start}>
                    Start Scale Animation
                </button>
                <button id="StartC" onClick={RotateY}>
                    Rotate Y
                </button>
            </div>
        </DiceWrap>
    );
}

Styled-Components(不确定这是不是原因?)

.cube{
  margin-top:80px;
  margin:auto;
  width:150px;
  height:150px;
  /*position:relative;*/
  transform-style: preserve-3d;
}

.cube-face {
  width: 150px;
  height: 150px;
  position: absolute;
}

.front-face{
  background:red;
  transform:translate3d(0,0,75px);
  /*border-radius:20px;*/
  box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.5);
  background: url(${DiceOne});
  background-size: contain;
}

.back-face{
  background:yellow;
  transform:rotateY(180deg) translate3d(0,0,75px);
    /*border-radius:20px;*/
    box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.5);
    background: url(${DiceTwo});
    background-size: contain;
}

.left-face{
  background: orange;
  transform: rotateY(-90deg) translate3d(0, 0, 75px);
    /*border-radius:20px;*/
    box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.5);
    background: url(${DiceThree});
    background-size: contain;
}

.right-face{
  background:lime;
  transform: rotateY(90deg) translate3d(0, 0, 75px);
    /*border-radius:20px;*/
    box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.5);
    background: url(${DiceFour});
    background-size: contain;
}

.top-face {
  background:blue;
  transform: rotateX(90deg) translate3d(0, 0, 75px);
    /*border-radius:20px;*/
    box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.5);
    background: url(${DiceFive});
    background-size: contain;
}

.bottom-face {
  background:magenta;
  transform: rotateX(-90deg) translate3d(0, 0, 75px);
    /*border-radius:20px;*/
    box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.5);
    background: url(${DiceSix});
    background-size: contain;
}

只需打乱faceRoll个函数号,点击Roll Die按钮,控制台输出相同

//Main DOM Variables and Selectors

//Selects Cube Face X via CSS Degree Rotatation
var cubeFace = [
  "translateX(200px)",
  "rotateX(90deg)",
  "rotateX(180deg)",
  "rotateX(270deg)"];

var startAnimation = document.getElementById("StartA"); //Start Animation Button
var buttonY = document.getElementById("StartB"); //Rotate Y Button (Still Rotates around X?)
var buttonX = document.getElementById("StartC"); // Rotate X Button
var Cube = document.querySelectorAll(".cube");
var Scene = document.querySelectorAll(".scene");
var i = 90;
var j = 0;

window.addEventListener('DOMContentLoaded', (event) => {

TweenMax.set(Scene, {perspective:0});

//Rotates through cubeFace array on each click.
//If i>cubeFace reset to 0 and preform 1st step.

var RotateY = function(){
  TweenMax.to (Cube,.5, {transform: cubeFace[i], ease:Linear.easeNone});

  if (i<cubeFace.length)
  {i++; console.log(i);}

  else{i=1;
    TweenMax.to (Cube,.5, {transform: cubeFace[0], ease:Linear.easeNone});
    console.log(i);}
  }//RotateY Function


var RotateX = function (){
  TweenMax.to(Cube, .5, {transform: "rotateY("+i+"deg)"});
  i+=90;}

//Random Experimental Scene
var tl = new TimelineMax({paused:true, repeat:3});
    tl.yoyo(true);
    tl.to(Cube, 1, {rotation:360})

    .to(Cube, 1, {rotationY:360, rotationX:360}, "-=1")
    .to(Scene,1, {scale:.2},"-=1")
    .to(Cube, 1, {x:500}, "-=1")

    tl.timeScale(1);

var start = function(){tl.restart();};

startAnimation.onclick = start;
buttonX.onclick = RotateY;
buttonY.onclick = RotateX;


//TweenMax would not take Array String used if statement
// var cubeFace2 = [
//   "rotationY:0, rotationX:0",
//   "rotationX:90",
//   "rotationX:180",
//   "rotationX:270",
//   "rotationY:90",
//   "rotationY:180"];
// var rl = new TimelineMax({onComplete:faceRoll});

var rollDie = document.getElementById("RollDie");
 //Roll Die Timeline
var startRoll = function(){
  var randomNum = Math.floor(Math.random() * 3); //between 0 and 5
  var rl = new TimelineMax({onComplete:faceRoll});
  rl.to(Cube,.01, {rotationY:0, rotationX:0});
  rl.to(Cube,3, {rotationY:1800, rotationX:1800});
  rl.to(Scene,3, {scale:.2},"-.1");
  rl.timeScale(4);
  rl.restart();
};

var faceRoll = function(){
var randomNum = Math.floor(Math.random() * 6); //between 0 and 5
  if(randomNum === 0){
    TweenMax.to(Cube,.2, {rotationY:0, rotationX:0},"-1");
    TweenMax.to(Scene, .2, {scale:1}, "-1");
  }
  if(randomNum === 5){
    TweenMax.to(Cube,.2,{rotationX:90, scale:1},"-1");
    TweenMax.to(Scene, .2, {scale:1}, "-1");
  }
  if(randomNum === 1){
    TweenMax.to(Cube,.2,{rotationX:180, scale:1},"-1");
    TweenMax.to(Scene, .2, {scale:1}, "-1");
  }
  if(randomNum === 4){
    TweenMax.to(Cube,.2,{rotationX:270, scale:1},"-1");
    TweenMax.to(Scene, .2, {scale:1}, "-1");
  }
  if(randomNum === 2){
    TweenMax.to(Cube,.2,{rotationY:90, scale:1},"-1");
    TweenMax.to(Scene, .2, {scale:1}, "-1");
  }
  if(randomNum === 3){
    TweenMax.to(Cube,.2,{rotationY:270, scale:1},"-1");
    TweenMax.to(Scene, .2, {scale:1}, "-1");
  }
  console.log(randomNum+1);
}//FaceRoll If Statement

rollDie.onclick = startRoll;

});
@import url(https://fonts.googleapis.com/css?family=Roboto:400,300,500,700);

/***Main CSS ***/

body {
  margin: 0;
  padding: 0;
  font-family: 'Roboto', sans-serif;
}

header {
  margin: 0;
  padding: 0;
  height: 150px;
  background-color: #673AB7;
  color: white;
  text-align: center;
}

header h1 {
  margin: 0;
  padding: 10px;
  padding-top: 1.5em;
  font-weight: 500;
}

header h3 {
  margin: 0;
  font-weight: 300;
}

button {
  margin: 20px;
  padding: 10px;
  font-size: 1em;
  background-color: #3F51B5;
  color: white;
  font-weight: 500;
}

#Roll {
  margin-top: 20px;
  display: flex;
  justify-content: center;
}

#animationWrap {
  text-align: center;
}

#animations {
  display: flex;
  justify-content: center;
}


/*********The Cube CSS***********/

#box1 {
  margin-top: 100px;
}

#box1 input,
#box1 label {
  display: none;
}

.scene
.cube {
  margin-top: 80px;
  margin: auto;
  width: 150px;
  height: 150px;
  transform-style: preserve-3d;
}

.cube-face {
  width: 150px;
  height: 150px;
  position: absolute;
}

.front-face {
  background: red;
  transform: translate3d(0, 0, 75px);
  box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.5);
  background: url("https://raw.githubusercontent.com/mthomps4/Dice-Roll/master/images/D_DieFace1.jpg");
  background-size: contain;
}

.back-face {
  background: yellow;
  transform: rotateY(180deg) translate3d(0, 0, 75px);
  /*border-radius:20px;*/
  box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.5);
  background: url("https://raw.githubusercontent.com/mthomps4/Dice-Roll/master/images/D_DieFace2.jpg");
  background-size: contain;
}

.left-face {
  background: orange;
  transform: rotateY(-90deg) translate3d(0, 0, 75px);
  /*border-radius:20px;*/
  box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.5);
  background: url("https://raw.githubusercontent.com/mthomps4/Dice-Roll/master/images/D_DieFace3.jpg");
  background-size: contain;
}

.right-face {
  background: lime;
  transform: rotateY(90deg) translate3d(0, 0, 75px);
  /*border-radius:20px;*/
  box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.5);
  background: url("https://raw.githubusercontent.com/mthomps4/Dice-Roll/master/images/D_DieFace4.jpg");
  background-size: contain;
}

.top-face {
  background: blue;
  transform: rotateX(90deg) translate3d(0, 0, 75px);
  /*border-radius:20px;*/
  box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.5);
  background: url("https://raw.githubusercontent.com/mthomps4/Dice-Roll/master/images/D_DieFace5.jpg");
  background-size: contain;
}

.bottom-face {
  background: magenta;
  transform: rotateX(-90deg) translate3d(0, 0, 75px);
  /*border-radius:20px;*/
  box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.5);
  background: url("https://raw.githubusercontent.com/mthomps4/Dice-Roll/master/images/D_DieFace6.jpg");
  background-size: contain;
}


/***** NOT IN USE REFER TO diceA.js*****/


/**** Radio Button Interactions ****/

#radio-front:checked~.scene .cube {
  transform: rotateX(0deg) rotateY(0deg);
  transition: 2s;
}

#radio-back:checked~.scene .cube {
  transform: rotateY(180deg);
  transition: 2s;
}

#radio-left:checked~.scene .cube {
  transform: rotateY(90deg);
  transition: 2s;
}

#radio-right:checked~.scene .cube {
  transform: rotateY(-90deg);
  transition: 2s;
}

#radio-top:checked~.scene .cube {
  transform: rotateX(-90deg);
  transition: 2s;
}

#radio-bottom:checked~.scene .cube {
  transform: rotateX(90deg);
  transition: 2s;
}


/*CSS CUBE ROTATIONS*/


/*.rfront{
  transform:rotateX(0deg) rotateY(0deg);
  transition:2s;
}
.rback{
  transform: rotateY(180deg);
  transition:2s;
}
.rleft{
  transform: rotateY(90deg);
  transition:2s;
}
.rright{
  transform: rotateY(-90deg);
  transition:2s;
}
.rtop{
  transform: rotateX(-90deg);
  transition:2s;
}
.rbottom{
  transform: rotateX(90deg);
  transition:2s;
}*/

.sceneCSS {
  transform-style: preserve-3d;
  animation-name: boxRoll;
  animation-duration: 2s;
}

.reset {
  transform-style: ;
  animation-name: ;
  animation-duration: ;
}

@keyframes boxRoll {
  from {}
  10% {
    transform: translateX(75px) rotateY(180deg);
  }
  20% {
    transform: translateX(-75px) rotateY(90deg);
  }
  30% {
    transform: rotateY(-90deg);
  }
  40% {
    transform: translateY(75px) rotateX(-90deg);
  }
  50% {
    transform: translateY(-75px) rotateX(90deg);
  }
  to {
    transform: rotateX(0deg) rotateY(0deg);
  }
}


/*.scene2 .cube2{
  transform-style:preserve-3d;
  animation-name: rotateBox2;
  animation-duration:10s;
  animation-iteration-count: infinite;
}*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.18.4/TweenMax.min.js"></script>
<header>
  <h1> Random Die Throw </h1>
  <h3> Cube Rotation and Animation </h3>
</header>

<div id="box1">
  <div class="scene">
    <div class="cube">
      <div class="cube-face front-face rfront"></div>
      <div class="cube-face back-face rback"></div>
      <div class="cube-face left-face rleft"></div>
      <div class="cube-face right-face rright"></div>
      <div class="cube-face top-face rtop"></div>
      <div class="cube-face bottom-face rbottom"></div>
    </div>
  </div>
</div>


<div id="Roll">
  <button id="RollDie">Roll Die</button>
</div>


<div id="animations">
  <button id="StartB">Rotate X</button>
  <button id="StartA">Start Scale Animation</button>
  <button id="StartC">Rotate Y</button>
</div>

看起来像: