猿问

KonvaJS - 围绕光标旋转矩形而不使用偏移

我正在使用 KonvaJS 将矩形拖放到预定义的插槽中。一些插槽需要旋转 90 度。我在垂直旋转的插槽周围有一个命中框,因此当用户将矩形拖入该区域时,它将自动旋转 90 度(以匹配方向)。当它旋转时,它会从鼠标下方移出。这可以通过偏移来解决,但是在捕捉后矩形不会在视觉上与框对齐。这可以(可能)通过附加代码来解决。


我试图旋转矩形,然后在鼠标下移动它。由于用户仍在拖动它,这似乎没有按我的计划工作。


是否可以在不使用偏移的情况下强制矩形在鼠标下旋转?


这是一个显示问题的小提琴 - 可以通过将第一个变量设置为 true 来演示偏移问题。 https://jsfiddle.net/ChaseRains/1k0aqs2j/78/


var width = window.innerWidth;

var height = window.innerHeight;


var rectangleLayer = new Konva.Layer();

var holdingSlotsLayer = new Konva.Layer();

var controlLayer = new Konva.Layer();

var stage = new Konva.Stage({

  container: 'container',

  width: width,

  height: height,

  draggable: true

});

//vertical holding spot

holdingSlotsLayer.add(new Konva.Rect({

  x: 300,

  y: 25,

  width: 130,

  height: 25,

  fill: '#fff',

  draggable: false,

  rotation: 90,

  stroke: '#000'

}));


//horizontal holding spot

holdingSlotsLayer.add(new Konva.Rect({

  x: 25,

  y: 75,

  width: 130,

  height: 25,

  fill: '#fff',

  draggable: false,

  rotation: 0,

  stroke: '#000'

}));


//mask to set boundaries around where we wannt to flip the rectangle

controlLayer.add(new Konva.Rect({

  x: 215,

  y: 15,

  width: 150,

  height: 150,

  fill: '#fff',

  draggable: false,

  name: 'A',

  opacity: 0.5

}));

stage.add(holdingSlotsLayer, controlLayer);


//function for finding intersections

function haveIntersection(placeHolder, rectangle, zone) {

  if (rectangle.rotation == 0 || zone == true) {

    return !(

      rectangle.x > placeHolder.x + placeHolder.width ||

      rectangle.x + rectangle.width < placeHolder.x ||

      rectangle.y > placeHolder.y + placeHolder.height ||

      rectangle.y + rectangle.height < placeHolder.y

    );

  } else {

    return !(

      rectangle.x > placeHolder.x + 25 ||

      rectangle.x + rectangle.width < placeHolder.x ||

      rectangle.y > placeHolder.y + placeHolder.height + 90 ||

      rectangle.y + rectangle.height < placeHolder.y

    );

  }

}


UYOU
浏览 560回答 1
1回答

宝慕林4294392

这是一个在鼠标下旋转矩形的简单函数,无需使用 konva offset()。我使用补间来应用移动,但如果您更喜欢在没有补间的情况下使用它,只需应用 rect.rotate() 然后应用 newPos x & y 作为位置。编辑:OP指出,如果您单击,在矩形完成动画时按住鼠标,然后拖动,则矩形会跳开。是什么赋予了 ?好吧,当 mousedown 事件运行时,Konva 会记录形状在其内部拖动功能中的初始位置。然后当我们开始实际拖动鼠标时,Konva 会尽职尽责地在它计算出的位置重新绘制形状。现在,“我们”知道我们将形状移入了代码,但我们没有让 Konva 参与我们的诡计。解决方法是调用&nbsp;rect.stopDrag();&nbsp;&nbsp;rect.startDrag();新位置确定后立即进行。因为我使用的是补间,所以我在其中一个补间的 onFinish() 回调函数中执行此操作 - 如果您应用多个补间,您将希望确保它是最终补间。我侥幸逃脱,因为我的补间在同一时期运行。如果您不使用补间,只需在对形状应用最后一个 rotate() 或 position() 调用时立即调用上述方法。function rotateUnderMouse(){&nbsp; // Get the stage position of the mouse&nbsp; var mousePos = stage.getPointerPosition();&nbsp; // get the stage position of the mouse&nbsp; var shapePos = rect.position();&nbsp; // compute the vector for the difference&nbsp; var rel = {x: mousePos.x - shapePos.x, y: mousePos.y - shapePos.y}&nbsp;&nbsp; // Now apply the rotation&nbsp; angle = angle + 90;&nbsp; // and reposition the shape to keep the same point in the shape under the mouse&nbsp;&nbsp; var newPos = ({x: mousePos.x&nbsp; + rel.y , y: mousePos.y - rel.x})&nbsp;&nbsp; // Just for fun, a tween to apply the move: See https://konvajs.org/docs/tweens/Linear_Easing.html&nbsp; var tween1 = new Konva.Tween({&nbsp; &nbsp; node: rect,&nbsp; &nbsp; duration: 0.25,&nbsp; &nbsp; x:&nbsp; newPos.x,&nbsp; &nbsp; y: newPos.y,&nbsp; &nbsp; easing: Konva.Easings.Linear,&nbsp; &nbsp; onFinish: function() { rect.stopDrag(); rect.startDrag();}&nbsp; });&nbsp;&nbsp;&nbsp; // and a tween to apply the rotation&nbsp;&nbsp; tween2 = new Konva.Tween({&nbsp; &nbsp; node: rect,&nbsp; &nbsp; duration: 0.25,&nbsp; &nbsp; rotation: angle,&nbsp; &nbsp; easing: Konva.Easings.Linear&nbsp; });&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tween2.play();&nbsp; tween1.play();&nbsp;&nbsp;}function setup() {// Set up a stage and a shapestage = new Konva.Stage({&nbsp; container: 'canvas-container',&nbsp; width: 650,&nbsp; height: 300});layer = new Konva.Layer();stage.add(layer);newPos = {x: 80, y: 40};rect = new Konva.Rect({&nbsp; &nbsp;width: 140, height: 50, x: newPos.x, y: newPos.y, draggable: true, stroke: 'cyan', fill: 'cyan'&nbsp; })layer.add(rect);stage.draw()rect.on('mousedown', function(){&nbsp; rotateUnderMouse()})}var stage, layer, rect, angle = 0;setup()<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/konva/4.0.13/konva.js"></script><p>Click the rectangle - it will rotate under the mouse.</p><div id="canvas-container"></div>
随时随地看视频慕课网APP

相关分类

JavaScript
我要回答