좋아, 내가 원하는 것을 얻기 위해 Zynga Scroller 기능을 KineticJS 프레임 워크와 통합했다. 내가 온라인으로 발견하고 자신을 쓴 것들의 융합이 코드에서
Code in action
하자 단계 모양.
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. */
그런 다음, 우리가 불 끌어 층에 뭔가를 포기하면 어떤 이벤트를 정의 :
첫째, 우리는 KineticJS를 사용하여 캔버스를 생성합니다. 이를 사용하여 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 코드는 입력과 변환을 처리 한 다음 렌더링 함수에 세 개의 값, 즉 top
, left
및 zoom
을 전달합니다. 이러한 값은 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);
확대/축소 가능지도의 기초로 완벽합니다.
"스테이지를 제약합니다"란 무엇입니까? 스테이지의 알레 디가 창과 같이 너비와 높이를 갖고 있다면? – lavrton
JSFiddles를 확인하면 원에서 주변의 공백으로 이동할 수 있습니다. 확대하는 동안 패닝 만 허용하므로 공백이 발생하지 않습니다. – Beerdude26
이 jsfiddles로 장난을 치고 난 후에, 나는 당신이 확대 할 때 실제로 무대의 위치를 바꾸는 것이 아니라, 단지 규모라고 생각합니다. 따라서 x, y 좌표는 실제로 변경되지 않습니다. 당신이 원하는 것은 스케일링 후에 그 x, y를 계산하고 드래그 함수에서 0보다 커지지 않게하는 것입니다. – SoluableNonagon