如何为形状设置所需的 clientRect x 和 y?
How to set a desired clientRect x and y for a Shape?
假设我有 2 个 Rect
,一大一小,都在同一个 Layer
中。没有 Group
,也没有其他 Shape
。小的 Rect
可拖动、可调整大小和旋转,大的是静态的。
我想确保你不能将小的拖到大的外面,我希望小的 Rect
的任何旋转或缩放都得到尊重。
我在两个 Rect
上都使用 getClientRect
来定义拖动范围。现在,当我知道我的小 Rect
的边界矩形所需的 x
和 y
时,我该如何设置它?我不能做 setAbsolutePosition({ x, y })
,因为小矩形可能会旋转,这意味着 getAbsolutePosition().x !== getClientRect().x
。我尝试使用 getAbsoluteTransform().point()
来转换坐标,但我没有运气。
提前致谢。
这可能会让您一路顺风。使用变换器旋转矩形,使其碰到红色矩形,或拖动它,以查看边界检查与客户端矩形效果。我在转换器 boundBoxFunc 和 rect.dragBoundFunc 中使用了客户端 rect。
注意:存在一个问题,重叠的计算以某种方式使矩形与边界重叠。一个可能要解决的错误。
var stage = new Konva.Stage({
container: 'canvas-container',
width: 650,
height: 300
});
var layer = new Konva.Layer();
stage.add(layer);
var rectOuter = new Konva.Rect({
width: 240, height: 150, x: 80, y: 80, draggable: true, stroke: 'red'
})
layer.add(rectOuter);
var rect = new Konva.Rect({
width: 40, height: 50, x: 140, y: 140, draggable: true, fill: 'cyan',
dragBoundFunc: function(newBoundBox) {
var pos = rect.getClientRect();
if (intersectRect(pos, rectOuter.getClientRect())){
return {
x: oldBoundBox.x,
y: oldBoundBox.y
}
}
oldBoundBox.x = newBoundBox.x; // note old box for use if we deny the drag
oldBoundBox.y = newBoundBox.y;
return {
x: newBoundBox.x,
y: newBoundBox.y
}
}
})
layer.add(rect);
var oldBoundBox = rect.getAbsolutePosition();
var rect2 = new Konva.Rect ({
stroke: 'magenta', listening: false,
})
layer.add(rect2);
var text = new Konva.Text({
x: 5,
y: 5,
});
layer.add(text);
updateText();
// make the transformer for the image
var transformer = new Konva.Transformer({
node: rect,
enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
boundBoxFunc: function (oldBoundBox, newBoundBox) {
var pos = rect.getClientRect();
if (intersectRect(pos, rectOuter.getClientRect())){
return oldBoundBox;
}
return newBoundBox
}
});
layer.add(transformer);
rect.on('dragmove', function () {
updateText();
})
rect.on('transform', function () {
updateText();
});
function updateText() {
var pos = rect.getClientRect();
var lines = [
'x: ' + rect.x(),
'y: ' + rect.y(),
'rotation: ' + rect.rotation(),
'width: ' + rect.width(),
'height: ' + rect.height(),
'scaleX: ' + rect.scaleX(),
'scaleY: ' + rect.scaleY(),
'client: ' + pos.x + ', ' + pos.y
];
text.text(lines.join('\n'));
// use rect2 to give a view on what is happening as we translate
rect2.position({x: pos.x, y: pos.y});
rect2.width(pos.width);
rect2.height(pos.height);
layer.batchDraw();
}
layer.draw()
stage.draw()
// check if the rects overlap
function intersectRect(kr1, kr2) {
var r1 = makeGeomRect(kr1, 0); // add left & right properties
var r2 = makeGeomRect(kr2, 10);
return !(r2.left <= r1.left &&
r2.right > r1.right &&
r2.top < r1.top &&
r2.bottom > r1.bottom);
}
// make a handier rect - takes a rect with x, y, width, height and gives it left and right
function makeGeomRect (r, padding){
var out = {
left: r.x + padding,
right: r.x + r.width - padding,
top: r.y + padding,
bottom: r.y + r.height - padding
}
return out;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.6.0/konva.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="image-editor">
<div id="canvas-container"></div>
</div>
运行 片段全屏看全荣耀
假设我有 2 个 Rect
,一大一小,都在同一个 Layer
中。没有 Group
,也没有其他 Shape
。小的 Rect
可拖动、可调整大小和旋转,大的是静态的。
我想确保你不能将小的拖到大的外面,我希望小的 Rect
的任何旋转或缩放都得到尊重。
我在两个 Rect
上都使用 getClientRect
来定义拖动范围。现在,当我知道我的小 Rect
的边界矩形所需的 x
和 y
时,我该如何设置它?我不能做 setAbsolutePosition({ x, y })
,因为小矩形可能会旋转,这意味着 getAbsolutePosition().x !== getClientRect().x
。我尝试使用 getAbsoluteTransform().point()
来转换坐标,但我没有运气。
提前致谢。
这可能会让您一路顺风。使用变换器旋转矩形,使其碰到红色矩形,或拖动它,以查看边界检查与客户端矩形效果。我在转换器 boundBoxFunc 和 rect.dragBoundFunc 中使用了客户端 rect。
注意:存在一个问题,重叠的计算以某种方式使矩形与边界重叠。一个可能要解决的错误。
var stage = new Konva.Stage({
container: 'canvas-container',
width: 650,
height: 300
});
var layer = new Konva.Layer();
stage.add(layer);
var rectOuter = new Konva.Rect({
width: 240, height: 150, x: 80, y: 80, draggable: true, stroke: 'red'
})
layer.add(rectOuter);
var rect = new Konva.Rect({
width: 40, height: 50, x: 140, y: 140, draggable: true, fill: 'cyan',
dragBoundFunc: function(newBoundBox) {
var pos = rect.getClientRect();
if (intersectRect(pos, rectOuter.getClientRect())){
return {
x: oldBoundBox.x,
y: oldBoundBox.y
}
}
oldBoundBox.x = newBoundBox.x; // note old box for use if we deny the drag
oldBoundBox.y = newBoundBox.y;
return {
x: newBoundBox.x,
y: newBoundBox.y
}
}
})
layer.add(rect);
var oldBoundBox = rect.getAbsolutePosition();
var rect2 = new Konva.Rect ({
stroke: 'magenta', listening: false,
})
layer.add(rect2);
var text = new Konva.Text({
x: 5,
y: 5,
});
layer.add(text);
updateText();
// make the transformer for the image
var transformer = new Konva.Transformer({
node: rect,
enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right'],
boundBoxFunc: function (oldBoundBox, newBoundBox) {
var pos = rect.getClientRect();
if (intersectRect(pos, rectOuter.getClientRect())){
return oldBoundBox;
}
return newBoundBox
}
});
layer.add(transformer);
rect.on('dragmove', function () {
updateText();
})
rect.on('transform', function () {
updateText();
});
function updateText() {
var pos = rect.getClientRect();
var lines = [
'x: ' + rect.x(),
'y: ' + rect.y(),
'rotation: ' + rect.rotation(),
'width: ' + rect.width(),
'height: ' + rect.height(),
'scaleX: ' + rect.scaleX(),
'scaleY: ' + rect.scaleY(),
'client: ' + pos.x + ', ' + pos.y
];
text.text(lines.join('\n'));
// use rect2 to give a view on what is happening as we translate
rect2.position({x: pos.x, y: pos.y});
rect2.width(pos.width);
rect2.height(pos.height);
layer.batchDraw();
}
layer.draw()
stage.draw()
// check if the rects overlap
function intersectRect(kr1, kr2) {
var r1 = makeGeomRect(kr1, 0); // add left & right properties
var r2 = makeGeomRect(kr2, 10);
return !(r2.left <= r1.left &&
r2.right > r1.right &&
r2.top < r1.top &&
r2.bottom > r1.bottom);
}
// make a handier rect - takes a rect with x, y, width, height and gives it left and right
function makeGeomRect (r, padding){
var out = {
left: r.x + padding,
right: r.x + r.width - padding,
top: r.y + padding,
bottom: r.y + r.height - padding
}
return out;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.6.0/konva.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="image-editor">
<div id="canvas-container"></div>
</div>
运行 片段全屏看全荣耀