2016-01-27 2 views
0

Я использую KonvaJs в моем проекте. Мне нужно реализовать привязку привязки к Konva.Layer. У моего слоя много других фигур и образов. Мне нужно ограничить перемещение слоя до 50% его ширины и высоты. То, как я это сделал в этом plunkr. Проблема возникает, когда пользователь приближается или уменьшает масштаб с помощью колеса мыши. После масштабирования я не знаю, почему привязка перетаскивания ведет себя по-другому. Похоже, я не в состоянии правильно выполнить математику. Мне нужно иметь такое же поведение, то есть способ перемещения слоя ограничен, когда пользователь не выполняет масштабирование. Это то, что я делаю:Drag Bound wiith Konva.Layer

//... a helper object for zooming 
var zoomHelper = { 
    stage: null, 
    scale: 1, 
    zoomFactor: 1.1, 
    origin: { 
     x: 0, 
     y: 0 
    }, 
    zoom: function(event) { 
     event.preventDefault(); 
     var delta; 
     if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) { 
      if (event.originalEvent.detail > 0) { 
       //scroll down 
       delta = 0.2; 
      } else { 
       //scroll up 
       delta = 0; 
      } 
     } else { 
      if (event.originalEvent.wheelDelta < 0) { 
       //scroll down 
       delta = 0.2; 
      } else { 
       //scroll up 
       delta = 0; 
      } 
     } 
     var evt = event.originalEvent, 
      mx = evt.clientX - zoomHelper.stage.getX(), 
      my = evt.clientY - zoomHelper.stage.getY(), 
      zoom = (zoomHelper.zoomFactor - delta), 
      newscale = zoomHelper.scale * zoom; 
     zoomHelper.origin.x = mx/zoomHelper.scale + zoomHelper.origin 
      .x - mx/newscale; 
     zoomHelper.origin.y = my/zoomHelper.scale + zoomHelper.origin 
      .y - my/newscale; 
     zoomHelper.stage.setOffset({ 
      x: zoomHelper.origin.x, 
      y: zoomHelper.origin.y 
     }); 
     zoomHelper.stage.setScale({ 
      x: newscale, 
      y: newscale 
     }); 
     zoomHelper.stage.draw(); 
     zoomHelper.scale *= zoom; 
     preCalculation(); 
    } 
}; 


// Code goes here 
var w = window.innerWidth; 
var h = window.innerHeight; 
var height, minX, minY, maxX, maxY; 
var stage = new Konva.Stage({ 
    container: 'container', 
    width: w, 
    height: h 
}); 
zoomHelper.stage =stage; 
var layer = new Konva.Layer({ 
    draggable: true, 
    dragBoundFunc: function(pos) { 
    console.log('called'); 
    var X = pos.x; 
    var Y = pos.y; 
    if (X < minX) { 
     X = minX; 
    } 
    if (X > maxX) { 
     X = maxX; 
    } 
    if (Y < minY) { 
     Y = minY; 
    } 
    if (Y > maxY) { 
     Y = maxY; 
    } 
    return ({ 
     x: X, 
     y: Y 
    }); 
    } 
}); 

stage.add(layer); 

function preCalculation(){ 
    // pre-calc some bounds so dragBoundFunc has less calc's to do 
height = layer.getHeight(); 
minX = stage.getX() - layer.getWidth()/2; 
maxX = stage.getX() + stage.getWidth() - layer.getWidth()/2; 
minY = stage.getY() - layer.getHeight()/2; 
maxY = stage.getY() + stage.getHeight() - layer.getHeight()/2; 
console.log(height, minX, minY, maxX, maxY); 
} 
preCalculation(); 

var img = new Image(); 
img.onload = function() { 
    var floorImage = new Konva.Image({ 
    image: img, 
    width: w, 
    height: h 
    }); 
    layer.add(floorImage); 
    layer.draw(); 
}; 
img.src = 'https://s.yimg.com/pw/images/coverphoto02_h.jpg.v3'; 

$(stage.container).on('mousewheel DOMMouseScroll', zoomHelper.zoom); 

ответ

1

При использовании dragBoundFunc вы должны вернуть абсолютное положение слоя. По мере изменения атрибутов верхнего узла (стадии) может быть трудно поддерживать абсолютное положение. Таким образом, вы можете попытаться установить связанную функцию внутри '' dragmove события:

layer.on('dragmove', function() { 
    var x = Math.max(minX, Math.min(maxX, layer.x())); 
    var y = Math.max(minY, Math.min(maxY, layer.y())); 
    layer.x(x); 
    layer.y(y); 
}); 

http://plnkr.co/edit/31MUmOjXBUVuaHVJsL3c?p=preview

+0

Спасибо за ответ lavrton. Вы сказали, что я должен установить связанную функцию внутри 'dragmove' так же, как вы. Я в порядке, я сделаю это. Но проблема в том, что при операции масштабирования область, в которой пользователь может перетаскивать, сокращается. Мне нужно ограничить перемещение перетаскивания до 50% ширины и высоты слоя. Если слой масштабируется, область масштабирования следует масштабировать соответствующим образом. –

+0

Что значит 50% высоты слоя? Это 50% стадии? Или это 50% содержимого слоя (изображение)? Какая высота будет после масштабирования? – lavrton

+0

Содержимое слоя, которое является изображением, и в моем случае высота и ширина сцены и изображения одинаковы. –