javascript - 出血区域适用于通过鼠标拖动移动的对象,但不适用于键盘的箭头键
问题描述
我有 2 个 FabricJS 画布和一些键盘移动功能。我可以在 2 个画布周围添加和拖动文本并且受到限制(根据需要)。但是,如果我选择一个对象并用我的箭头键移动它,它就不会绑定到“出血区域”。如何将限制应用于键盘移动?
var activeCanvas, front, back, canvas1, canvas2;
$(document).ready(function() {
canvas1 = new fabric.Canvas('front');
canvas2 = new fabric.Canvas('back');
canvas1.setHeight(360);
canvas1.setWidth(208);
canvas2.setHeight(360);
canvas2.setWidth(208);
changeView(1);
var padding = 20;
canvas1.on('object:moving', onObjectMoving);
canvas2.on('object:moving', onObjectMoving);
function onObjectMoving(e) {
var obj = e.target;
// if object is too big ignore
if (obj.currentHeight > obj.canvas.height - padding * 2 ||
obj.currentWidth > obj.canvas.width - padding * 2) {
return;
}
obj.setCoords();
// top-left corner
if (obj.getBoundingRect().top < padding ||
obj.getBoundingRect().left < padding) {
obj.top = Math.max(obj.top, obj.top - obj.getBoundingRect().top + padding);
obj.left = Math.max(obj.left, obj.left - obj.getBoundingRect().left + padding);
}
// bot-right corner
if (obj.getBoundingRect().top + obj.getBoundingRect().height > obj.canvas.height - padding ||
obj.getBoundingRect().left + obj.getBoundingRect().width > obj.canvas.width - padding) {
obj.top = Math.min(
obj.top,
obj.canvas.height - obj.getBoundingRect().height + obj.top - obj.getBoundingRect().top - padding);
obj.left = Math.min(
obj.left,
obj.canvas.width - obj.getBoundingRect().width + obj.left - obj.getBoundingRect().left - padding);
}
};
});
function changeView(value) {
if (value == 1) {
activeCanvas = canvas1;
$('#front').parent().css('display', 'block');
$('#back').parent().css('display', 'none');
}
if (value == 2) {
activeCanvas = canvas2;
$('#front').parent().css('display', 'none');
$('#back').parent().css('display', 'block');
}
}
function dropText() {
var text = new fabric.Text('test');
activeCanvas.add(text);
}
// Keyboard Movement
const STEP = 1;
var Direction = {
LEFT: 0,
UP: 1,
RIGHT: 2,
DOWN: 3
};
fabric.util.addListener(document.body, 'keydown', function(options) {
if (options.repeat) {
return;
}
var key = options.which || options.keyCode; // key detection
if (key === 37) { // handle Left key
moveSelected(Direction.LEFT);
} else if (key === 38) { // handle Up key
moveSelected(Direction.UP);
} else if (key === 39) { // handle Right key
moveSelected(Direction.RIGHT);
} else if (key === 40) { // handle Down key
moveSelected(Direction.DOWN);
}
});
function moveSelected(direction) {
var activeObject = activeCanvas.getActiveObject();
var activeGroup = activeCanvas.getActiveGroup();
if (activeObject) {
switch (direction) {
case Direction.LEFT:
activeObject.setLeft(activeObject.getLeft() - STEP);
break;
case Direction.UP:
activeObject.setTop(activeObject.getTop() - STEP);
break;
case Direction.RIGHT:
activeObject.setLeft(activeObject.getLeft() + STEP);
break;
case Direction.DOWN:
activeObject.setTop(activeObject.getTop() + STEP);
break;
}
activeObject.setCoords();
activeCanvas.renderAll();
console.log('selected objects was moved');
} else if (activeGroup) {
switch (direction) {
case Direction.LEFT:
activeGroup.setLeft(activeGroup.getLeft() - STEP);
break;
case Direction.UP:
activeGroup.setTop(activeGroup.getTop() - STEP);
break;
case Direction.RIGHT:
activeGroup.setLeft(activeGroup.getLeft() + STEP);
break;
case Direction.DOWN:
activeGroup.setTop(activeGroup.getTop() + STEP);
break;
}
activeGroup.setCoords();
activeCanvas.renderAll();
console.log('selected group was moved');
} else {
console.log('no object selected');
}
}
canvas {
border: 1px solid #dddddd;
margin-top: 10px;
border-radius: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<button onclick="changeView(1);">Front</button>
<button onclick="changeView(2);">Back</button>
<button onclick="dropText();">Add Text</button>
<div style="text-align: center">
<canvas id="front"></canvas>
<canvas id="back"></canvas>
</div>
解决方案
您需要object:moving
手动触发事件。
activeCanvas.trigger('object:moving', {
target: activeObject
})
查看演示(也在jsFiddle上):
var activeCanvas, front, back, canvas1, canvas2;
$(document).ready(function() {
canvas1 = new fabric.Canvas('front');
canvas2 = new fabric.Canvas('back');
canvas1.setHeight(360);
canvas1.setWidth(208);
canvas2.setHeight(360);
canvas2.setWidth(208);
changeView(1);
var padding = 20;
canvas1.on('object:moving', onObjectMoving);
canvas2.on('object:moving', onObjectMoving);
function onObjectMoving(e) {
var obj = e.target;
// if object is too big ignore
if (obj.currentHeight > obj.canvas.height - padding * 2 ||
obj.currentWidth > obj.canvas.width - padding * 2) {
return;
}
obj.setCoords();
// top-left corner
if (obj.getBoundingRect().top < padding ||
obj.getBoundingRect().left < padding) {
obj.top = Math.max(obj.top, obj.top - obj.getBoundingRect().top + padding);
obj.left = Math.max(obj.left, obj.left - obj.getBoundingRect().left + padding);
}
// bot-right corner
if (obj.getBoundingRect().top + obj.getBoundingRect().height > obj.canvas.height - padding ||
obj.getBoundingRect().left + obj.getBoundingRect().width > obj.canvas.width - padding) {
obj.top = Math.min(
obj.top,
obj.canvas.height - obj.getBoundingRect().height + obj.top - obj.getBoundingRect().top - padding);
obj.left = Math.min(
obj.left,
obj.canvas.width - obj.getBoundingRect().width + obj.left - obj.getBoundingRect().left - padding);
}
};
});
function changeView(value) {
if (value == 1) {
activeCanvas = canvas1;
$('#front').parent().css('display', 'block');
$('#back').parent().css('display', 'none');
}
if (value == 2) {
activeCanvas = canvas2;
$('#front').parent().css('display', 'none');
$('#back').parent().css('display', 'block');
}
}
function dropText() {
var text = new fabric.Text('test');
activeCanvas.add(text);
}
// Keyboard Movement
const STEP = 1;
var Direction = {
LEFT: 0,
UP: 1,
RIGHT: 2,
DOWN: 3
};
fabric.util.addListener(document.body, 'keydown', function(options) {
if (options.repeat) {
return;
}
var key = options.which || options.keyCode; // key detection
if (key === 37) { // handle Left key
moveSelected(Direction.LEFT);
} else if (key === 38) { // handle Up key
moveSelected(Direction.UP);
} else if (key === 39) { // handle Right key
moveSelected(Direction.RIGHT);
} else if (key === 40) { // handle Down key
moveSelected(Direction.DOWN);
}
});
function moveSelected(direction) {
var activeObject = activeCanvas.getActiveObject();
var activeGroup = activeCanvas.getActiveGroup();
if (activeObject) {
switch (direction) {
case Direction.LEFT:
activeObject.setLeft(activeObject.getLeft() - STEP);
break;
case Direction.UP:
activeObject.setTop(activeObject.getTop() - STEP);
break;
case Direction.RIGHT:
activeObject.setLeft(activeObject.getLeft() + STEP);
break;
case Direction.DOWN:
activeObject.setTop(activeObject.getTop() + STEP);
break;
}
activeObject.setCoords();
activeCanvas.trigger('object:moving', {
target: activeObject
})
activeCanvas.renderAll();
console.log('selected objects was moved');
} else if (activeGroup) {
switch (direction) {
case Direction.LEFT:
activeGroup.setLeft(activeGroup.getLeft() - STEP);
break;
case Direction.UP:
activeGroup.setTop(activeGroup.getTop() - STEP);
break;
case Direction.RIGHT:
activeGroup.setLeft(activeGroup.getLeft() + STEP);
break;
case Direction.DOWN:
activeGroup.setTop(activeGroup.getTop() + STEP);
break;
}
activeGroup.setCoords();
activeCanvas.trigger('object:moving', {
target: activeGroup
})
activeCanvas.renderAll();
console.log('selected group was moved');
} else {
console.log('no object selected');
}
}
canvas {
border: 1px solid #dddddd;
margin-top: 10px;
border-radius: 3px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.7.20/fabric.min.js"></script>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<button onclick="changeView(1);">Front</button>
<button onclick="changeView(2);">Back</button>
<button onclick="dropText();">Add Text</button>
<div style="text-align: center">
<canvas id="front"></canvas>
<canvas id="back"></canvas>
</div>
推荐阅读
- java - 将对象从另一个类绘制到同一个 JFrame
- java - 每次进行计算时,我如何打印出我的 RPN 计算器的堆栈?
- http - 指定 HTTP 请求的本地端点
- typescript - 如何定义柯里化函数的返回类型?
- c - C Api 和 Matlab Simulink 模型集成
- amazon-web-services - 使用 for_each 和 ARN 列表输出的 Terraform 模块调用
- firebase - 无法将数据从 firestore 检索到 listview 扑扑
- javascript - 如何减少对象数组
- android - 在 Android 10(及更高版本)上,如何以编程方式检测哪个应用程序在外部/辅助屏幕的前台运行?
- javascript - 如何为购物车制作数量变化功能?