为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

UYOU 2022-01-13 16:09:11
我正在使用 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 spotholdingSlotsLayer.add(new Konva.Rect({  x: 300,  y: 25,  width: 130,  height: 25,  fill: '#fff',  draggable: false,  rotation: 90,  stroke: '#000'}));//horizontal holding spotholdingSlotsLayer.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 rectanglecontrolLayer.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 intersectionsfunction 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    );  }}
查看完整描述

1 回答

?
宝慕林4294392

TA贡献2021条经验 获得超8个赞

这是一个在鼠标下旋转矩形的简单函数,无需使用 konva offset()。我使用补间来应用移动,但如果您更喜欢在没有补间的情况下使用它,只需应用 rect.rotate() 然后应用 newPos x & y 作为位置。


编辑:OP指出,如果您单击,在矩形完成动画时按住鼠标,然后拖动,则矩形会跳开。是什么赋予了 ?好吧,当 mousedown 事件运行时,Konva 会记录形状在其内部拖动功能中的初始位置。然后当我们开始实际拖动鼠标时,Konva 会尽职尽责地在它计算出的位置重新绘制形状。现在,“我们”知道我们将形状移入了代码,但我们没有让 Konva 参与我们的诡计。


解决方法是调用


 rect.stopDrag(); 

 rect.startDrag();

新位置确定后立即进行。因为我使用的是补间,所以我在其中一个补间的 onFinish() 回调函数中执行此操作 - 如果您应用多个补间,您将希望确保它是最终补间。我侥幸逃脱,因为我的补间在同一时期运行。如果您不使用补间,只需在对形状应用最后一个 rotate() 或 position() 调用时立即调用上述方法。


function rotateUnderMouse(){



  // Get the stage position of the mouse

  var mousePos = stage.getPointerPosition();


  // get the stage position of the mouse

  var shapePos = rect.position();


  // compute the vector for the difference

  var rel = {x: mousePos.x - shapePos.x, y: mousePos.y - shapePos.y} 


  // Now apply the rotation

  angle = angle + 90;



  // and reposition the shape to keep the same point in the shape under the mouse 

  var newPos = ({x: mousePos.x  + rel.y , y: mousePos.y - rel.x}) 


  // Just for fun, a tween to apply the move: See https://konvajs.org/docs/tweens/Linear_Easing.html

  var tween1 = new Konva.Tween({

    node: rect,

    duration: 0.25,

    x:  newPos.x,

    y: newPos.y,

    easing: Konva.Easings.Linear,

    onFinish: function() { rect.stopDrag(); rect.startDrag();}

  });

  

  // and a tween to apply the rotation 

  tween2 = new Konva.Tween({

    node: rect,

    duration: 0.25,

    rotation: angle,

    easing: Konva.Easings.Linear

  });

    

  

  tween2.play();

  tween1.play();



  

}



function setup() {


// Set up a stage and a shape

stage = new Konva.Stage({

  container: 'canvas-container',

  width: 650,

  height: 300

});



layer = new Konva.Layer();

stage.add(layer);


newPos = {x: 80, y: 40};

rect = new Konva.Rect({

   width: 140, height: 50, x: newPos.x, y: newPos.y, draggable: true, stroke: 'cyan', fill: 'cyan'

  })

layer.add(rect);


stage.draw()


rect.on('mousedown', function(){

  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>


查看完整回答
反对 回复 2022-01-13
  • 1 回答
  • 0 关注
  • 450 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信