2012-09-11 68 views
8

我在將容器縮放到固定點時遇到了一些問題。
在我的情況下,我試圖縮放(縮放)到鼠標光標的舞臺。在KineticJS中縮放到固定點

這裏是一個方式做純帆布: http://phrogz.net/tmp/canvas_zoom_to_cursor.html(截至Zoom Canvas to Mouse Cursor討論)

我只是不能找出如何同時使用KineticJS API應用相同的邏輯。

示例代碼:

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

回答

16

很多掙扎,尋找和嘗試之後,利用@Eric Rowell提供的尖端和張貼在代碼,以便質疑Zoom in on a point (using scale and translate)我終於得到了放大和縮小固定的點使用KineticJS工作。

這裏有一個工作DEMO

而這裏的代碼:

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

謝謝!這工作。回覆晚了非常抱歉。 – Skarbo

+0

嘿,謝謝,這工作正常,但我有很多層,所以我不能將圖層設置爲「可拖動」。因此我設置階段可拖動。當我拖動舞臺時,我無法縮放到所需的縮放點。我不得不重新計算一些數字來計算階段x和y,但我無法完成。你能幫我嗎? – magirtopcu

+0

@ user1645941請分享您正在處理的問題的一些工作示例(也許作爲[小提琴](http://jsfiddle.net/)),我會盡我所能提供幫助。 –

3

您需要抵消階段,使得它的中心點位於固定點。下面是一個例子,因爲舞臺的中心點默認設置在畫布的左上角。假設您的舞臺寬600px,高400px,並且您希望舞臺從中心放大。你需要做的是:

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

更新@juan.facorro的示範規模,而不是舞臺形狀

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

只有上面的演示工作,如果X和Y座標的階段是0.如果例如該階段是可拖動的,它將在拖動時更改這些座標,以便它們需要包含在偏移計算中。這可以通過從畫布偏移量減去它們來實現:

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