0

I built the following resize script - as you can see from the fiddle, it works for scaling up but not down:

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);
  }
}

I tried to fix the issue by using the determinant/cross-product for a positive/negative direction:

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;

As you can see from the fiddle, now it "sometimes" scales down, and it's always jumpy.

Any math majors with ideas? Am I getting the determinant incorrectly? Thanks in advance for any insight.

4

1 回答 1

1

When I first looked at it, I saw that there was no way a negative integer could be used, so I altered your function like this:

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 + ")";
  }

You can see it here: https://jsfiddle.net/gregborbonus/a37aeb08/5/

So after you comment, I made a further edit, to get rid of the initial position issue.

Everything you were scaling off of was determined based off the distance from the start point, so how far away or towards the resize dot did you move your mouse?

This means that even if you stopped moving Y direction, but you moved X a little, Y would still be greater than your move from X, making it scale based off Y, but you didn't move Y, you only moved X.

So, this function pulls from how far you moved your mouse from the last resize:

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/

于 2016-04-03T19:46:02.873 回答