2012-09-28 66 views
9

有沒有一種方法可以使用KineticJS在畫布上縮放和平移?我發現這個庫kineticjs-viewport,但只是想知道是否有任何其他的方式來實現這一目標,因爲這個庫似乎使用這麼多額外的庫,並不確定哪些是完成工作絕對必要的。在KineticJS中縮放和平移

另外,我甚至可以打開圍繞感興趣區域繪製矩形並放大該特定區域的想法。任何想法如何實現這一目標?一個JSFiddle例子會很棒!

回答

25

您可以簡單地將.setDraggable("draggable")添加到圖層,只要光標下有對象,您就可以拖動它。你可以添加一個大的,透明的rect,使一切都可以拖動。縮放可以通過設置圖層的比例來實現。在這個例子中,我通過鼠標滾輪來控制它,但它只是一個功能,您可以在其中傳遞想要縮放的數量(正數放大,負數縮小)。下面是代碼:

var stage = new Kinetic.Stage({ 
    container: "canvas", 
    width: 500, 
    height: 500 
}); 

var draggableLayer = new Kinetic.Layer(); 
draggableLayer.setDraggable("draggable"); 

//a large transparent background to make everything draggable 
var background = new Kinetic.Rect({ 
    x: -1000, 
    y: -1000, 
    width: 2000, 
    height: 2000, 
    fill: "#000000", 
    opacity: 0 
}); 

draggableLayer.add(background); 


//don't mind this, just to create fake elements 
var addCircle = function(x, y, r){ 
    draggableLayer.add(new Kinetic.Circle({ 
     x: x*700, 
     y: y*700, 
     radius: r*20, 
     fill: "rgb("+ parseInt(255*r) +",0,0)" 
    }) 
); 
} 

var circles = 300 
while (circles) { 
    addCircle(Math.random(),Math.random(), Math.random()) 
    circles--; 
} 

var zoom = function(e) { 
    var zoomAmount = e.wheelDeltaY*0.001; 
    draggableLayer.setScale(draggableLayer.getScale().x+zoomAmount) 
    draggableLayer.draw(); 
} 

document.addEventListener("mousewheel", zoom, false) 

stage.add(draggableLayer) 

http://jsfiddle.net/zAUYd/

+0

這個工程很好,除了在IE9。你有什麼想法,爲什麼?調試控制檯不會引發任何錯誤... – Legend

+0

如果我使用'e.wheelDelta'而不是'e.wheelDeltaY',看起來像是有效。任何想法爲什麼? – Legend

+1

我認爲IE使用deltaY。鼠標縮放只是一個例子,如果你打算保留它,那麼你應該使用一個墊片來彌補瀏覽器實現的不同,例如https://github.com/cobbweb/jquery-mousewheel – Duopixel

2

因爲我今天在與Kinetic合作,我發現了一個可能會讓你感興趣的SO question

我知道這會更好,但我沒有足夠的代表,無論如何,我希望有所幫助。

4

這裏是一個非常快速和簡單的實現縮放和平移一個層。如果您有更多的圖層需要同時平移和縮放,我會建議將它們分組,然後對該組應用on(「click」)以獲得相同的效果。

http://jsfiddle.net/renyn/56/

如果不是很明顯,在左上角的淡藍色方格被點擊放大和縮小,並在左下方的粉紅色方格被點擊平移左右。

編輯:作爲一個說明,這當然可以改變,以支持「mousedown」或其他事件,我不明白爲什麼轉換不能作爲Kinetic.Animations實現,以使它們更平滑。

+0

真棒!這正是我想要的。我嘗試在舞臺上使用鼠標事件,但沒有太多運氣,所以我很想問你 - 你能夠更多地指導我支持mousedown事件並支持更流暢的動畫嗎? – Legend

+0

我不會建議將它們應用於整個舞臺,這將捕獲所有鼠標事件,而不會帶來任何偏見。嘗試將它們分配給像我一樣的單個形狀。我不確定你需要什麼指導,但Kinetic的API和教程是非常有幫助的。 –

+0

我並不感到驚訝,5.0.0和5.0.1有很多來自4.0.2的重大更改。 –

1

不幸的是,設置狀態或層可拖動防止物體不能拖動。 Duopixel的縮放解決方案很好,但我寧願將它設置爲舞臺級別,而不是層級。

她是我的解決方案

var stage = new Kinetic.Stage({ 
    container : 'container', 
    width: $("#container").width(), 
    height: $("#container").height(), 
}); 
var layer = new Kinetic.Layer(); 

//layer.setDraggable("draggable"); 
var center = { x:stage.getWidth()/2, y: stage.getHeight()/2}; 

var circle = new Kinetic.Circle({ 
    x: center.x-100, 
    y: center.y, 
    radius: 50, 
    fill: 'green', 
    draggable: true 
}); 
layer.add(circle); 
layer.add(circle.clone({x: center.x+100})); 

// zoom by scrollong 
document.getElementById("container").addEventListener("mousewheel", function(e) { 
    var zoomAmount = e.wheelDeltaY*0.0001; 
    stage.setScale(stage.getScale().x+zoomAmount) 
    stage.draw(); 
    e.preventDefault(); 
}, false) 

// pan by mouse dragging on stage 
stage.on("dragstart dragmove", function(e) {window.draggingNode = true;}); 
stage.on("dragend", function(e) { window.draggingNode = false;}); 
$("#container").on("mousedown", function(e) { 
    if (window.draggingNode) return false; 
    if (e.which==1) { 
     window.draggingStart = {x: e.pageX, y: e.pageY, stageX: stage.getX(), stageY: stage.getY()}; 
     window.draggingStage = true; 
    } 
}); 
$("#container").on("mousemove", function(e) { 
    if (window.draggingNode || !window.draggingStage) return false; 
    stage.setX(window.draggingStart.stageX+(e.pageX-window.draggingStart.x)); 
    stage.setY(window.draggingStart.stageY+(e.pageY-window.draggingStart.y)); 
    stage.draw(); 
}); 
$("#container").on("mouseup", function(e) { window.draggingStage = false }); 

stage.add(layer); 

http://jsfiddle.net/bighostkim/jsqJ2/

3

其實我寫kineticjs視口。我很高興聽到你對此感興趣。

它實際上不僅僅是用於拖動。它也允許縮放和以性能爲焦點的裁剪。剪輯區域以外的東西根本不會渲染,所以即使您有大量對象的巨大圖層,您仍然可以獲得出色的渲染性能。

這就是我的用例。例如,您可以通過較小的視口區域查看大型RTS地圖 - 請思考Starcraft。

我希望這會有所幫助。

+1

你可以添加一個關於如何使用視口的例子嗎? – PiTheNumber

+1

回購中有一個演示頁面:https://kineticjs-viewport.googlecode.com/git/demo.html –

2

這些答案似乎不適用於KineticJS 5.1.0。這些不工作主要是針對規模函數的簽名更改:

stage.setScale(newscale); --> stage.setScale({x:newscale,y:newscale}); 

但是,下面的解決方案似乎與KineticJS 5.1.0工作:

的jsfiddle:http://jsfiddle.net/rpaul/ckwu7u86/3/