2016-04-03 12 views
0

ich folgenden Resize-Skript gebaut - wie man sich von der Geige sehen, es funktioniert für Scaling-up, aber nicht nach unten:Skalieren skalieren skalieren, nicht nach unten. die Determinante macht es nervös

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

Ich habe versucht, das Problem zu beheben durch die Determinante/Kreuzprodukt für eine positive/negative Richtung unter Verwendung von:

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; 

Wie Sie von der Geige sehen können, "skaliert" es jetzt manchmal und es ist immer nervös.

Irgendwelche Mathe Majors mit Ideen? Bekomme ich die Determinante falsch? Vielen Dank im Voraus für jede Einsicht.

Antwort

1

Als ich es sah, sah ich, dass es keine Möglichkeit gab eine negative ganze Zahl verwendet werden könnte, so dass ich verändert Ihre Funktion wie folgt aus:

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

Sie können es hier sehen: https://jsfiddle.net/gregborbonus/a37aeb08/5/

Also, nachdem Sie kommentieren, machte ich eine weitere Bearbeitung, um das Problem der ursprünglichen Position loszuwerden.

Alles, von dem Sie skaliert haben, wurde basierend auf der Entfernung vom Startpunkt bestimmt. Wie weit oder in Richtung des Größenpunktes haben Sie die Maus bewegt?

Dies bedeutet, dass selbst wenn Sie die Y-Richtung nicht mehr bewegen würden, aber Sie X ein wenig bewegt haben, Y immer noch größer als Ihre X-Bewegung ist, so dass Sie auf Y skalieren, aber Y nicht, nur Sie bewegt X.

Also, zieht diese Funktion aus, wie weit man mit der Maus aus dem letzten resize bewegt:

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/

+0

Dank für das Update Greg! Es ist jetzt viel glatter, aber nur, wenn Sie sich in eine vollkommen diagonale Richtung bewegen. Wenn Sie mehr in Richtung X oder Y-Achse drehen, springt es ... können Sie replizieren? Wie können wir den Sprung vermeiden? – calipoop

+0

RE negative ganze Zahl, ich habe versucht, das über die Determinante zu erreichen (det = (startX x e.clientY) - (e.clientX x startY)). Ich dachte, das könnte die Skalierung glatter machen. – calipoop

+0

Ich sah, es funktionierte nicht gut mit der Logik, da es davon abhing, wie Sie sich bewegten. –