9

有没有一种方法可以使用 KineticJS 在画布上缩放和平移?我找到了这个库kineticjs-viewport,但只是想知道是否有任何其他方法可以实现这一点,因为这个库似乎使用了很多额外的库,并且不确定哪些是完成工作绝对必要的。

或者,我什至愿意在感兴趣的区域周围绘制一个矩形并放大该特定区域。关于如何实现这一目标的任何想法?一个 JSFiddle 的例子会很棒!

4

7 回答 7

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/

于 2012-10-06T10:19:57.463 回答
4

这是缩放和平移图层的非常快速和简单的实现。如果您有更多需要同时平移和缩放的图层,我建议将它们分组,然后将 on("click") 应用于该组以获得相同的效果。

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

如果不明显,点击左上角的浅蓝色方块进行放大缩小,点击左下角的粉色方块进行左右平移。

编辑:作为说明,这当然可以更改为支持“mousedown”或其他事件,我不明白为什么不能将转换实现为 Kinetic.Animations 以使其更平滑。

于 2012-10-04T12:38:21.467 回答
3

这就是我到目前为止所做的......希望它会对你有所帮助。

http://jsfiddle.net/v1r00z/ZJE7w/

于 2012-10-02T02:19:38.307 回答
3

我实际上写了 kineticjs-viewport。我很高兴听到你对此感兴趣。

它实际上不仅仅用于拖动。它还允许缩放和以性能为中心的剪辑。剪辑区域之外的东西根本不会被渲染,因此即使您有一个包含大量对象的巨大图层,您也可以获得出色的渲染性能。

这就是我的用例。例如,您通过较小的视口区域查看的大型 RTS 地图——想想星际争霸。

我希望这有帮助。

于 2013-04-02T02:25:22.797 回答
2

当我今天与 Kinetic 合作时,我发现了一个您可能感兴趣的SO 问题。

我知道作为评论会更好,但我没有足够的代表,无论如何,我希望这会有所帮助。

于 2012-10-01T20:54:10.837 回答
2

这些答案似乎不适用于 KineticJS 5.1.0。这些主要不适用于 scale 函数的签名更改:

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

但是,以下解决方案似乎适用于 KineticJS 5.1.0:

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

于 2014-11-12T05:53:44.933 回答
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/

于 2012-12-20T21:30:00.440 回答