2012-09-11 11 views
8

Ich habe einige Probleme mit der Skalierung eines Containers auf einen festen Punkt.
In meinem Fall versuche ich eine Stufe auf den Mauszeiger zu skalieren (zoomen).Skalierung auf einen festen Punkt in KineticJS

Hier ist ein Weg, um mit reiner Leinwand zu tun: http://phrogz.net/tmp/canvas_zoom_to_cursor.html

Ich kann einfach nicht herausfinden (wie bei Zoom Canvas to Mouse Cursor diskutiert wird), wie die gleiche Logik anwenden, während der API KineticJS verwenden.

Beispielcode:

var position = this.stage.getUserPosition(); 
var scale = Math.max(this.stage.getScale().x + (0.05 * (scaleUp ? 1 : -1)), 0); 
this.stage.setScale(scale); 
// Adjust scale to position...? 
this.stage.draw(); 

Antwort

16

Nach viel kämpfen und sucht und versuchen, die Spitze von @Eric Rowell und den in dem entsandte Code versehen mit Zoom in on a point (using scale and translate) SO Frage bekam ich endlich den Zoom in und aus einem festen Punkt arbeiten mit KineticJS.

Hier ist eine funktionierende DEMO.

Und hier ist der Code:

var ui = { 
    stage: null, 
    scale: 1, 
    zoomFactor: 1.1, 
    origin: { 
     x: 0, 
     y: 0 
    }, 
    zoom: function(event) { 
     event.preventDefault(); 
     var evt = event.originalEvent, 
      mx = evt.clientX /* - canvas.offsetLeft */, 
      my = evt.clientY /* - canvas.offsetTop */, 
      wheel = evt.wheelDelta/120; 
     var zoom = (ui.zoomFactor - (evt.wheelDelta < 0 ? 0.2 : 0)); 
     var newscale = ui.scale * zoom; 
     ui.origin.x = mx/ui.scale + ui.origin.x - mx/newscale; 
     ui.origin.y = my/ui.scale + ui.origin.y - my/newscale; 

     ui.stage.setOffset(ui.origin.x, ui.origin.y); 
     ui.stage.setScale(newscale); 
     ui.stage.draw(); 

     ui.scale *= zoom; 
    } 
}; 

$(function() { 
    var width = $(document).width() - 2, 
     height = $(document).height() - 5; 
    var stage = ui.stage = new Kinetic.Stage({ 
     container: 'container', 
     width: width, 
     height: height 
    }); 
    var layer = new Kinetic.Layer({ 
     draggable: true 
    }); 
    var rectX = stage.getWidth()/2 - 50; 
    var rectY = stage.getHeight()/2 - 25; 

    var box = new Kinetic.Circle({ 
     x: 100, 
     y: 100, 
     radius: 50, 
     fill: '#00D200', 
     stroke: 'black', 
     strokeWidth: 2, 
    }); 

    // add cursor styling 
    box.on('mouseover', function() { 
     document.body.style.cursor = 'pointer'; 
    }); 
    box.on('mouseout', function() { 
     document.body.style.cursor = 'default'; 
    }); 

    layer.add(box); 
    stage.add(layer); 

    $(stage.content).on('mousewheel', ui.zoom); 
});​ 
+0

Danke: Dies kann durch sie Subtrahieren von den Leinwand-Offsets erreicht werden! Das funktioniert. Entschuldigung für die späte Antwort. – Skarbo

+0

Hey danke, das funktioniert gut, aber ich habe viele Ebenen, so kann ich Ebenen nicht als "ziehbare" festlegen. deshalb setze ich die Bühne ziehbar. Wenn ich die Bühne beim Ziehen verschiebe, kann ich nicht auf den gewünschten Zoom-Punkt zoomen. Ich muss etwas neu berechnen, als zähle Stufe x und y, aber ich konnte nicht erreichen. Könntest du mir helfen? – magirtopcu

+0

@ user1645941 Bitte teilen Sie einige Arbeitsbeispiele des Problems, mit denen Sie es zu tun haben (vielleicht als [Geige] (http://jsfiddle.net/)) und ich werde tun, was ich kann, um zu helfen. –

3

Sie müssen auf die Bühne versetzt, so dass es Mittelpunkt ist am festen Punkt positioniert ist. Hier ein Beispiel, weil der Mittelpunkt der Bühne standardmäßig in der oberen linken Ecke der Leinwand positioniert ist. Nehmen wir an, Ihre Bühne ist 600 Pixel breit und 400 Pixel groß und Sie möchten, dass die Bühne von der Mitte her zoomt. Sie müßten dies tun:

var stage = new Kinetic.Stage({ 
    container: 'container', 
    width: 600, 
    height: 400, 
    offset: [300, 200] 
}; 
3

@juan.facorro ‚s Demo aktualisiert Form maßstabs statt Stufe

jsFiddle

var ui = { 
    stage: null, 
    box: null, 
    scale: 1, 
    zoomFactor: 1.1, 
    zoom: function(event) { 
     event.preventDefault(); 
     var evt = event.originalEvent, 
      mx = evt.offsetX, 
      my = evt.offsetY, 
      wheel = evt.wheelDelta/120; //n or -n 
     var zoom = (ui.zoomFactor - (evt.wheelDelta < 0 ? 0.2 : 0)); 
     var newscale = ui.scale * zoom; 

     var origin = ui.box.getPosition(); 
     origin.x = mx - (mx - origin.x) * zoom; 
     origin.y = my - (my - origin.y) * zoom; 

     ui.box.setPosition(origin.x, origin.y); 
     ui.box.setScale(newscale); 
     ui.stage.draw(); 

     ui.scale *= zoom; 
    } 
}; 

$(function() { 
    var width = $(document).width() - 2, 
     height = $(document).height() - 5; 
    var stage = ui.stage = new Kinetic.Stage({ 
     container: 'container', 
     width: width, 
     height: height 
    }); 
    var layer = new Kinetic.Layer(); 
    var rectX = stage.getWidth()/2 - 50; 
    var rectY = stage.getHeight()/2 - 25; 

    var box = ui.box = new Kinetic.Circle({ 
     x: 100, 
     y: 100, 
     radius: 50, 
     fill: '#00D200', 
     stroke: 'black', 
     strokeWidth: 2, 
     draggable: true 
    }); 

    // add cursor styling 
    box.on('mouseover', function() { 
     document.body.style.cursor = 'pointer'; 
    }); 
    box.on('mouseout', function() { 
     document.body.style.cursor = 'default'; 
    }); 

    layer.add(box); 
    stage.add(layer); 

    $(stage.content).on('mousewheel', ui.zoom); 
}); 
2

Die Demo oben nur dann, wenn die x- und y-Koordinaten arbeitet der Bühne sind 0. Wenn z Die Bühne ist ziehbar. Sie ändert diese Koordinaten beim Ziehen, sodass sie in die Offsetberechnung einbezogen werden müssen.

jsfiddle

zoom: function(event) { 
    event.preventDefault(); 
    var evt = event.originalEvent, 
     mx = evt.offsetX - ui.scale.getX(), 
     my = evt.offsetY - ui.scale.getY(), 
    var zoom = (ui.zoomFactor - (evt.wheelDelta < 0 ? 0.2 : 0)); 
    var newscale = ui.scale * zoom; 

    var origin = ui.box.getPosition(); 
    origin.x = mx - (mx - origin.x) * zoom; 
    origin.y = my - (my - origin.y) * zoom; 

    ui.box.setPosition(origin.x, origin.y); 
    ui.box.setScale(newscale); 
    ui.stage.draw(); 

    ui.scale *= zoom; 
} 
Verwandte Themen