首页 > 解决方案 > 如何旋转点并放置在中心?

问题描述

我试图旋转点以防父容器旋转:

https://stackblitz.com/edit/js-qzfdbb?file=index.js

代码是:

var elParent = document.getElementById('parent');
var elCircle = document.getElementById('circle');

elCircle.addEventListener('click', function(e) {
  const circleSvg = document.getElementById('circle');
  const circleSvgRect = circleSvg.getBoundingClientRect();
  const parentRect = document.getElementById('parent').getBoundingClientRect();

  let leftTopX = circleSvgRect.left - parentRect.left;
  let leftTopY = circleSvgRect.top - parentRect.top;

  leftTopX = leftTopX + 15 - 5;
  leftTopY = leftTopY + 15 - 5;

  var degree = (20 * Math.PI) / 180;
  var xc = 250;
  var yc = 250;

  leftTopX =
    (leftTopX - xc) * Math.cos(degree) -
    (leftTopY - yc) * Math.sin(degree) +
    xc;
  leftTopY =
    (leftTopX - xc) * Math.sin(degree) +
    (leftTopY - yc) * Math.cos(degree) +
    yc;

  let c = document.getElementById('c');
  if (c) c.remove();

  c = document.createElement('div');
  c.setAttribute('id', 'c');
  c.style.setProperty('left', leftTopX + 'px');
  c.style.setProperty('top', leftTopY + 'px');
  elParent.appendChild(c);
});

要查看结果,请单击红色圆圈内。在没有旋转的情况下,一个绿色圆圈被放置在红色圆圈的中心。否则有偏移。

标签: javascript

解决方案


数学应该是这样的,但解决方案需要一些额外的计算来计算红色圆圈本身在外部矩形内的旋转。

注 1:为简单起见,正文的边距已删除...
注 2:滚动对脚本的影响很大。因此,如果不考虑它,该解决方案也可能不是很有用......

var elParent = document.getElementById('parent');
var elCircle = document.getElementById('circle');

elCircle.addEventListener('click', function(e) {
  const circleSvg = document.getElementById('circle');
  const circleSvgRect = circleSvg.getBoundingClientRect();
  const parentRect = document.getElementById('parent').getBoundingClientRect();

  const degree = getCurrentRotation(document.getElementById('parent'));

  const xcenter = parentRect.width / 2 + parentRect.left;
  const ycenter = parentRect.height / 2 + parentRect.top;

  const dx = (circleSvgRect.left + 10) - xcenter;
  const dy = ycenter - (circleSvgRect.top + 10); 

  console.log(dx + ' - ' + dy + '-' + Math.atan(dy / dx));

  const r = Math.sqrt(dx * dx + dy * dy);
  const curDegree = Math.atan(dy / dx) + degree;

  xnew = xcenter + Math.sign(-dx) * Math.sin(curDegree) * r;
  ynew = ycenter - Math.sign(-dx) * Math.cos(curDegree) * r;

  let c = document.getElementById('c');
  if (c) c.remove();

  c = document.createElement('div');
  c.setAttribute('id', 'c');
  c.style.setProperty('left', xnew + 'px');
  c.style.setProperty('top', ynew + 'px');
  elParent.appendChild(c);
});

//https://stackoverflow.com/questions/19574171/how-to-get-css-transform-rotation-value-in-degrees-with-javascript
function getCurrentRotation(el) {
  var st = window.getComputedStyle(el, null);
  var tm =
    st.getPropertyValue('-webkit-transform') ||
    st.getPropertyValue('-moz-transform') ||
    st.getPropertyValue('-ms-transform') ||
    st.getPropertyValue('-o-transform') ||
    st.getPropertyValue('transform') ||
    'none';
  if (tm != 'none') {
    var values = tm
      .split('(')[1]
      .split(')')[0]
      .split(',');
    return (angle = Math.atan2(values[1], values[0]));
  }
  return 0;
}
<div id="parent">
  <div id="circle" style="left: 100px; top: 100px"></div>
</div>

<style>
  body {
    margin:0px;
    padding:0px;
  }
  #circle {
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: red;
    position: relative;
    
  }

  #c {
    position: absolute;
    width: 10px;
    height: 10px;
    background: green;
    border-radius: 50%;
  }

  #parent {
    width: 500px;
    position: relative;
    height: 500px;
    border: 1px solid #ccc;
    transform: rotate(180deg);
  }
</style>


推荐阅读