【问题标题】:Basic rotate and translate an element on keydown基本旋转和平移 keydown 上的元素
【发布时间】:2017-09-27 17:05:09
【问题描述】:

我正在尝试了解如何为特定元素添加基本交互性。在这里,我希望用户能够按任意箭头键并看到元素相应地旋转和平移。我不确定为此使用 DOM 与 Canvas 之间的区别,但由于我知道如何使用 DOM,所以我在这里选择了该方法。我的问题是元素的运动不一致,我认为这是因为我不小心用我的函数覆盖了变换值。

这是下面的sn-p。除了down 键之外的所有箭头键。

function rotate( e, n ) {  //get current rotation and add n to it
  var curTranslation = getTrans( e );
  
  e.style.transform = 
  'rotate( ' + n + 'deg ) translateY(' + curTranslation + 'px )';
}
function translate( e, n ) { //get current translation and add n to it
  var curRotation = getRot( e );  
  
  e.style.transform = 
  'rotate( ' + curRotation + 'deg ) translateY(' + n + 'px )';
}     
function checkKey( e ) { //fire when a key on the keyboard is pressed. 
  var d = document,
      triBx = d.getElementById( 'tri-bx' );
  
  if ( e.keyCode == '38' ) { //up
    countTrans = Math.abs( countTrans ) * -1.1;  
    translate( triBx, countTrans );
  }
  else if ( e.keyCode == '40' ) { //down
    body.innerHTML = 'down';
  }
  else if ( e.keyCode == '37' ) { //left
    countRot = Math.abs( countRot ) * -1.1;
    rotate( triBx, countRot );
  }
  else if ( e.keyCode == '39' ) { //right
    countRot = Math.abs( countRot ) * 1.1;
    rotate( triBx, countRot );
  }
}

function start() { //call first function
  var d = document,
      triBx = d.getElementById( 'tri-bx' );
  
  window.addEventListener( 'keydown', checkKey );
}

//prevent entire window from scrolling
window.addEventListener("keydown", function(e) { 
    // space and arrow keys
    if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
        e.preventDefault();
    }
}, false);
start();
html, 
body {
  height: 100%;
  margin: 0;
  padding: 0;
}
body {
  display: flex;
  justify-content: center;
  align-items: center;
}
.tri-bx {
  transform: rotate( 0 );
  transition: transform 1s;
}
.tri {
  width: 0; 
  height: 0; 
  border-left: 1rem solid transparent;
  border-right: 1rem solid transparent;
  border-bottom: 1rem solid black;
  transform: scaleX( 0.5 );
}
<div id="tri-bx" class="tri-bx">

  <div id="tri" class="tri"></div>

</div>

<p style="position:absolute; bottom: 0;">use arrow keys</p>

<script>
  var countRot = 1,   //keep track of how many times the keys are pressed for rotation
  countTrans = 1;     //Same for translation

  function getRot( e ) {  //get rotation angle of element
    var st = window.getComputedStyle( e, null ),
        tr = st.getPropertyValue( 'transform' ) || 'FAIL',
        values = tr.split( '(' )[ 1 ].split( ')' )[ 0 ].split( ',' ),
        a = values[ 0 ],
        b = values[ 1 ],
        c = values[ 2 ],
        d = values[ 3 ],
        scale = Math.sqrt( a * a + b * b ),
        sin = b / scale,
        angle = Math.round( Math.atan2( b, a ) * ( 180 / Math.PI ) );

    return angle;
  }
  
  function getTrans( e ) { //get translation value of element
  var st = window.getComputedStyle( e, null ),
      tr = st.getPropertyValue( 'transform' ) || 'FAIL',
      values = tr.split( '(' )[ 1 ].split( ')' )[ 0 ].split( ',' ),
      f = values[ 5 ];

  return f;
}
</script>

我的问题是为什么对象会在屏幕上跳过以及如何避免覆盖转换以使其正常工作。想法?

【问题讨论】:

    标签: javascript css css-animations css-transforms keydown


    【解决方案1】:

    您正在将转换用于不打算做的事情。 元素总是从它的原始位置转换。这就是为什么在你翻译它然后改变它的旋转之后,它会旋转一堆(这可能不是你所期望的)。如果您考虑一下,它会以度数旋转,因此您将三角形从“中间”或开始的位置移得越远,它移动的距离就越远。

    我建议您为此使用画布(有很多很棒的游戏库,它比您想象的更容易)。请记住,CSS 是为样式而不是交互而创建的。

    【讨论】:

    • 是的,所以在我的代码中,我试图只使用调用getRot()getTrans()curTranslationcurRotation 变量添加到以前的转换值,以避免覆盖它们。我的代码有问题,因为它似乎仍然覆盖了一些值。感谢您的建议,这主要是在我开始使用画布之前了解转换及其工作原理的练习。
    • 您的代码似乎很好,但试图实现一些不可能的事情。如果你想一想,当它实际上是在原始位置的轴上旋转时,你不能在它的轴上旋转三角形!
    • 并非不可能。我在这里做了:stackoverflow.com/questions/43723656/…,但有一个更大的问题。
    猜你喜欢
    • 1970-01-01
    • 2021-04-19
    • 2016-05-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多