调整脚本大小可以放大,而不是缩小。使用行列式使其变得有弹性

时间:2016-04-03 19:30:01

标签: javascript resize geometry determinants pythagorean

我构建了以下调整大小脚本 - 正如您从小提琴中看到的那样,它适用于扩展但不会缩小:

https://jsfiddle.net/calipoop/a37aeb08/

var item = document.getElementById('item'), 
btn = document.getElementById('resizeBtn'),
s = 1;

btn.addEventListener('mousedown', initResize);

function initResize(e) {
  var startS = s, startX = e.clientX, startY = e.clientY, dx, dy, d;
  window.addEventListener('mousemove', resize);
  window.addEventListener('mouseup', killResize);

  function resize(e) {
    dx = startX - e.clientX;
    dy = startY - e.clientY;
    d = Math.round(Math.sqrt(dx * dx + dy * dy));
    s = startS + (d * .001);
    item.style.transform = "scale(" + s + ")";
  }

  function killResize() {
    window.removeEventListener('mousemove', resize);
    window.removeEventListener('mouseup', killResize);
  }
}

我试图通过使用行列式/交叉积来确定正/负方向来解决问题:

https://jsfiddle.net/calipoop/zbx3us36/

det = (startX*e.clientY) - (e.clientX*startY);
dir = (det >= 0) ? 1 : -1; //get direction from sign of determinant
d = Math.round(Math.sqrt(dx * dx + dy * dy)) * dir;

正如你从小提琴中看到的那样,现在它有时会"缩小,它总是跳跃。

任何数学专业都有想法?我错误地得到了决定因素吗?提前感谢任何见解。

1 个答案:

答案 0 :(得分:1)

当我第一次看到它时,我发现没有办法可以使用负整数,所以我改变了你的函数:

function initResize(e) {
  var startS = s,
    startX = e.clientX,
    startY = e.clientY,
    dx, dy, d;
  window.addEventListener('mousemove', resize);
  window.addEventListener('mouseup', killResize);

  function resize(e) {
    dx = startX - e.clientX;
    dy = startY - e.clientY;
    negative = false;
    if (dx < 0 || dy < 0) negative = true;
    d = Math.abs(Math.round(Math.sqrt(dx * dx + dy * dy))); //Always postive, need a way to determine if should be negative.
    if (!negative) d = (d * -1);
    s = startS + (d * .001);

    item.style.transform = "scale(" + s + ")";
  }

你可以在这里看到它: https://jsfiddle.net/gregborbonus/a37aeb08/5/

因此,在您发表评论后,我进行了进一步的编辑,以摆脱初始职位问题。

你缩小的所有东西都是根据距离起点的距离来确定的,那么你移动鼠标的距离或调整大小点的距离是多远?

这意味着即使你停止向Y方向移动,但是你移动了一点X,Y仍然会比从X移动更大,使得它基于Y进行缩放,但是你没有移动Y,你只是移动了X

因此,此函数可以从您最后一次调整大小的位置移动鼠标:

function initResize(e) {
  var startS = s,
    startX = e.clientX,
    startY = e.clientY,
    dx, dy, d;
  window.addEventListener('mousemove', resize);
  window.addEventListener('mouseup', killResize);

  function resize(e) {
    //The problem with this logic is that while resizing, you calculate based on distance FROM your start, this is not always the best approach, so what you need is the difference from your last recorded position.

    dx = startX - e.clientX;
    dy = startY - e.clientY;
    startX=e.clientX; //for the next run
    startY=e.clientY; //for the next run
    negative = false;
    if (dx < 0 || dy < 0) negative = true;
    //d = Math.abs(Math.round(Math.sqrt(dx * dx + dy * dy))); //Always postive, need a way to determine if should be negative.
    d=Math.max(Math.abs(dx),Math.abs(dy))*3; //Lets figure out which is the max and do the math off that.
    if (!negative) d = (d * -1);
    s = startS + (d * .001);
    startS=s; //Set the scale for the next run.

    item.style.transform = "scale(" + s + ")";
  }

  function killResize() {

    window.removeEventListener('mousemove', resize);
    window.removeEventListener('mouseup', killResize);
  }
}

https://jsfiddle.net/gregborbonus/a37aeb08/6/