gpt4 book ai didi

javascript - 动力学.js : Prevent draggable stage from going off-boundaries

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:34:43 26 4
gpt4 key购买 nike

我正在尝试制作一个平移和缩放 Canvas 以用作游戏中的迷你 map 。我已将舞台设置为可拖动,以便玩家可以使用鼠标四处移动,以及移动舞台图层上的单个对象。但是,我不希望能够将舞台拖到周围的白色空间中。换句话说,我只想在放大时允许平移,这样您就永远不会遇到那个空白区域。为了尝试限制舞台,我设置了一个 dragBoundFunc:

        dragBoundFunc: function(pos) {
return {
x: (pos.x < 0 ? 0 : pos.x > width ? width : pos.x),
y: (pos.y < 0 ? 0 : pos.y > height ? height : pos.y)
};
}

(完整的 JSFiddle 示例:http://jsfiddle.net/4Brry/)

我遇到了两个问题:

  • 首先, Canvas 仍然可以向上和向左移动。
  • 其次,更烦人的是,当我们开始缩放时,约束开始出现异常。缩放时,约束不会考虑这一事实。那么,如果我们添加阶段偏移会怎么样?

            dragBoundFunc: function(pos) {
    return {
    x: ((ui.stage.getOffset().x+pos.x) < 0 ? 0 : pos.x > width ? width : pos.x),
    y: ((ui.stage.getOffset().y+pos.y) < 0 ? 0 : pos.y > height ? height : pos.y)
    };
    }

    (完整的 JSFiddle 示例:http://jsfiddle.net/2fLCd/)

这好多了,但是现在当您走得太远时, View 会“迅速恢复”。如果它只是停止向不允许的方向移动会更好。

有人知道我该如何解决这些问题吗?

最佳答案

好的,我将 Zynga Scroller 功能与 KineticJS 框架集成在一起以获得我想要的东西。

Code in action

让我们看一下代码,这是我在网上找到的东西和自己写的东西的结合。

首先,我们使用 KineticJS 生成 Canvas :

var width = 700;
var height = 700;
var stage = new Kinetic.Stage({
container: 'container',
width: width,
height: height
});

var layer = new Kinetic.Layer({});
stage.add(layer);

/* I skipped some circle generation code. */

然后,我们定义了一些在图层上拖放某些东西时触发的事件。我们将使用这些来填充一个名为 somethingIsBeingDraggedInKinetic 的全局变量。我们将在 Zynga Scroller 的平移代码中使用这个变量,这样当您拖动 KineticJS 形状时整个舞台就不会四处移动。

var somethingIsBeingDraggedInKinetic = false;
layer.on('dragstart', function(evt) {
// get the thing that is being dragged
var thing = evt.targetNode;
if( thing )
somethingIsBeingDraggedInKinetic = true;
});

layer.on('dragend', function(evt) {
// get the thing that is being dragged
var thing = evt.targetNode;
if( thing )
somethingIsBeingDraggedInKinetic = false;
});

接下来是 Zynga Scroller 初始化代码。 Zynga Scroller 代码处理输入和转换,然后将三个值传递给渲染函数:topleftzoom。这些值非常适合传递给 KineticJS 框架:

// Canvas renderer
var render = function(left, top, zoom) {

// Constrain the stage from going too far to the right
if( (left + (width / zoom)) > width )
left = width - (width / zoom );

// Constrain the stage from going too far to the left
if( (top + (height / zoom)) > height )
top = height - (height / zoom );

stage.setOffset(left, top);
stage.setScale(zoom);
stage.draw();
};

// Initialize Scroller
this.scroller = new Scroller(render, {
zooming: true,
animating: false,
bouncing: false,
locking: false,
minZoom: 1
});

之后,我们需要正确定位 Zynga Scroller。我承认这部分对我来说有点黑魔法。我从“asset/ui.js”文件中复制了其余代码。

var container = document.getElementById("container");
var rect = container.getBoundingClientRect();
scroller.setPosition(rect.left + container.clientLeft, rect.top + container.clientTop);
scroller.setDimensions(700, 700, width, height);

最后,我也复制了平移代码,并添加了一些代码来检查 KineticJS 框架是否在移动某些东西:

var mousedown = false;

container.addEventListener("mousedown", function(e) {
if (e.target.tagName.match(/input|textarea|select/i)) {
return;
}

scroller.doTouchStart([{
pageX: e.pageX,
pageY: e.pageY
}], e.timeStamp);

mousedown = true;
}, false);

document.addEventListener("mousemove", function(e) {
if (somethingIsBeingDraggedInKinetic)
return;

if (!mousedown) {
return;
}

scroller.doTouchMove([{
pageX: e.pageX,
pageY: e.pageY
}], e.timeStamp);

mousedown = true;
}, false);

document.addEventListener("mouseup", function(e) {
if (!mousedown) {
return;
}

scroller.doTouchEnd(e.timeStamp);

mousedown = false;
}, false);

哦,还有缩放处理程序。

container.addEventListener(navigator.userAgent.indexOf("Firefox") > -1 ? "DOMMouseScroll" :  "mousewheel", function(e) {
scroller.doMouseZoom(e.detail ? (e.detail * -120) : e.wheelDelta, e.timeStamp, e.pageX, e.pageY);
}, false);

这非常适合作为可缩放 map 的基础!

关于javascript - 动力学.js : Prevent draggable stage from going off-boundaries,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16402561/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com