Konva - 使用旋转并保持在界限内

时间:2018-02-03 13:19:11

标签: javascript html5-canvas konvajs

我正在使用Konva在网页上创建一个区域。我为我的矩形创建了一个dragBoundFunc函数,检查pos.x和pos.y以及画布和rect的宽度,这很好用 - 矩形只停留在这个区域,就像我想要的那样拖动。

当我将矩形旋转90度时出现问题。当我检查getClientRect()。width和getClientRect()。height时,宽度小于高度,这是预期的但现在它不会一直拖到画布的末尾,除非我检测到旋转结束并改变我的形状offsetY值为65然后它工作正常。

在轮换后更改offsetY和offsetX以正确解决此问题的方法,如果是,我该如何计算设置它们?

           dragBoundFunc: function(pos) {
        var iw = 600 - (my_shape.getClientRect().width);
        var ih = 400 - my_shape.getClientRect().height;
        var newX = pos.x > iw  ? iw : pos.x;
        var newY = pos.y > ih ? ih : pos.y;
        return {
            x: newX > 0 ? newX : 0,
            y: newY > 0 ? newY : 0
        };

    }

1 个答案:

答案 0 :(得分:0)

这是一个有效的解决方案。请注意,这仅适用于0度,90度,180度和270度的固定旋转或倍数。 “任意角度旋转”的解决方案;将要求三角或矩阵数学计算点的旋转值等

CreateMap<Product, ViewModelProduct>();

CreateMap<ProductCategory, ViewModelProductCategory>()
    .ForMember(dst => dst.Products, opt => opt.MapFrom(
        src => src.ProductInCategory.Select(pc => pc.Product)));
/*
 This is the drag bounds func
*/
function theDragFunc(pos) {

var thisRect = {x: this.x(), y: this.y(), width: this.width(), height: this.height()};

// copy the boundary rect into a testRect which defines the extent of the dragbounds 
// without accounting for the width and height of dragging rectangle.
// This is changed below depending on rotation.
var testRect={
  left: boundary.x, 
  top: boundary.y, 
  right: boundary.x + boundary.width,
  bottom: boundary.y + boundary.height
};


// the userRotation value is calculated in the rotation button onclick 
// to be one of 0, 90, 180, 270
switch (userRotation){

  case 0: // for 0 degrees compute as per a normal bounds rect
    testRect.right = testRect.right - thisRect.width;
    testRect.bottom = testRect.bottom - thisRect.height;
    break;

  case 90:  // for 90 degs we have to modify the test boundary left and bottom 
    testRect.left = testRect.left + thisRect.height;
    testRect.bottom = testRect.bottom - thisRect.width;
    break;

  case 180:  // for 180 degs we have to modify the test boundary left and top 
    testRect.left = testRect.left + thisRect.width;
    testRect.top = testRect.top + thisRect.height;
    break;

  case 270:  // for 270 degs we have to modify the test boundary right and top 
    testRect.right = testRect.right - thisRect.height;
    testRect.top = testRect.top + thisRect.width;
    break;

}

// get new pos as: if pos inside bounday ranges then use it, otherwise user boundary

// left edge check
var newX = (pos.x < testRect.left ? testRect.left : pos.x);

// right edge check
newX = (newX > testRect.right ? testRect.right : newX);

// top edge check
var newY = (pos.y < testRect.top ? testRect.top : pos.y);

// bottom edge check
newY = (newY > testRect.bottom ? testRect.bottom : newY);

// return the point we calculated
return {
    x: newX,
    y: newY
  }
}

// From here on is just the canvas setup etc.



// set ub the main rect - the one we drag and rotate
var target = {x: 70, y: 70, width: 70, height: 40};

// set ub the boundary rect - used in the rectfunc later
var boundary = {x: 20, y: 20, width: 460, height: 160};

// Set up the stage
var s1 = new Konva.Stage({container: 'container1', width: 500, height: 200});

// add a layer.
var layer1 = new Konva.Layer({draggable: false});
s1.add(layer1);

// show the extent of the boundary
var funcRect = new Konva.Rect({
    x:boundary.x, 
    y: boundary.y, 
    width: boundary.width, 
    height: boundary.height, 
    stroke: 'red'})
layer1.add(funcRect)

// Make some easy-to-grok values for the boundary func.
boundary.minX =  boundary.x;
boundary.maxX =  boundary.x + boundary.width;
boundary.minY =  boundary.y;
boundary.maxY =  boundary.y + boundary.height;

// show the target rect

var targetRect = new Konva.Rect({
    x:target.x, 
    y: target.y, 
    width: target.width, 
    height: target.height, 
    stroke: 'green',
    draggable: true,
    
    // Apply a linear graient fill to give a sense of rotation.
    fillLinearGradientStartPoint: { x : -50, y : -50},
    fillLinearGradientEndPoint: { x : 50, y : 50},
    fillLinearGradientColorStops: [0, 'red', 1, 'yellow'],
            
    dragBoundFunc: theDragFunc  // the function is at the bottom top of the code
        
    })
layer1.add(targetRect)

// Draw the stage
s1.draw();

var userRotation = 0;
$('#btnRotate').on('click', function(e){

  targetRect.rotate(90)
  s1.draw();
  
  var rectRotation = targetRect.rotation();

  // user can rotate > 360 so we will nomalise the rotation down to range 0 - 270
  userRotation = (rectRotation / 90);
  userRotation = (userRotation  % 4) * 90;

  $('#info').html("Rect rotation " + rectRotation + " same as " + userRotation);

})
p
{
  padding: 4px;
  
}
#container1
{
  display: inline-block;
  width: 500px; 
  height: 200px; 
  background-color: silver;
  overflow: hidden; 
}
#pallette
{
 height: 52px; width: 500px; 
 border: 1px solid #666;
  margin-bottom: 10px;
  z-index: 10;
}
.draggable
{
  width:50px;
  height: 50px;
  display: inline-block;
  border: 1px solid #666;
}