Добавление кнопки Custom Delete (Back, toFront) для элементов управления
Я хотел бы знать, есть ли простой способ добавить удаление, вывести на передний план, вернуть назад
в существующие элементы управления fabric.js.
В данный момент я могу только нажимать на кнопки, которые удаляли бы объект, доставляли бы на передний план и т.д.
Я работаю над поиском решения, чтобы иметь возможность нажимать X (в верхнем правом углу) на объект и удалять объект.
Я предполагаю, что это будет связано с переписыванием, оберткой или подклассом существующего объекта управления.
Возможно, я что-то контролировал, и есть простое решение? Пожалуйста, нет Div Wrapper.
![Fabric.js Canvas Object Selection Delete X]()
Ответы
Ответ 1
Fabric.js не предлагает простого средства добавления элементов управления к объектам.
Если вы хотите создать свои собственные элементы управления, вам придется перезаписать класс Object, в частности:
- переопределить
drawControls
, чтобы нарисовать пользовательскую кнопку
- вам нужно будет сохранить координаты кнопок, чтобы вы могли обнаружить, когда пользователь нажимает на них. C.F.
_setCornerCoords
и _findTargetCorner
- включить свое действие где-нибудь в
__onMouseDown
Вам не нужно заботиться о том, чтобы "разворачивать" элементы управления, поскольку весь холст повторно отображается, когда объект не выбран.
Надеюсь, это поможет, и удачи:)
Ответ 2
Я реализовал его с помощью позиционирования элемента html
canvas.on('object:selected',function(e){
jQuery(".deleteBtn").remove();
var btnLeft = e.target.oCoords.mt.x;
var btnTop = e.target.oCoords.mt.y - 25;
var widthadjust=e.target.width/2;
btnLeft=widthadjust+btnLeft-10;
var deleteBtn = '<p" class="deleteBtn" title="Delete" style="position:absolute;top:'+btnTop+'px;left:'+btnLeft+'px;cursor:pointer;" title="Remove object">✕</p>';
jQuery(".canvas-container").append(deleteBtn);
//.canvas-container is the parent div to the canvas positioned relative via CSS
});
canvas.on('mouse:down',function(e){
if(canvas.getActiveObject())
{
}
else
{
jQuery(".deleteBtn").remove();
}
});
canvas.on('object:modified',function(e){
jQuery(".deleteBtn").remove();
var btnLeft = e.target.oCoords.mt.x;
var btnTop = e.target.oCoords.mt.y - 25;
var widthadjust=e.target.width/2;
btnLeft=widthadjust+btnLeft-10;
var deleteBtn = '<p" class="deleteBtn" title="Delete" style="position:absolute;top:'+btnTop+'px;left:'+btnLeft+'px;cursor:pointer;" title="Remove object">✕</p>';
jQuery(".canvas-container").append(deleteBtn);
//.canvas-container is the parent div to the canvas positioned relative via CSS
});
//THE DELETE BUTTON CLICK EVENT
jQuery(document).on('click',".deleteBtn",function(){
if(canvas.getActiveObject())
{
canvas.remove(canvas.getActiveObject());
//this would remove the currently active object on stage,
jQuery(this).remove();
jQuery(".deleteBtn").remove();
}
})
Ответ 3
Я считаю, что решение с элементами dom не так стабильно, но оно нормально, если оно покрывает ваши потребности,
Мне также нужно было изменить кнопки угла объекта по умолчанию, на мои пользовательские кнопки для моего веб-приложения.
Я использую
- 'изменить размер',/я больше не использую его по причинам /
- кнопка "удалить объект"
- кнопка "редактировать объект"
- кнопка "поворот объекта"
поэтому вам нужно изменить 2 вещи, чтобы добиться успеха:
1. изменить частную функцию '_drawControl' из файла fabric.js. Это примерно в строке 13367 (на моем fabric.js). На этой функции ткань рисует кнопки cornet по умолчанию объектов и показывает их на seleced.
Мы можем легко изменить png на наши пользовательские.
ниже мой измененный _drawControl (fabric.js):
_drawControl: function(control, ctx, methodName, left, top, flipiX, flipiY) {
var sizeX = this.cornerSize / this.scaleX,
sizeY = this.cornerSize / this.scaleY;
if (this.isControlVisible(control)) {
isVML || this.transparentCorners || ctx.clearRect(left, top, sizeX, sizeY);
var SelectedIconImage = new Image();
var lx='';
var ly='';
var n='';
switch (control)
{
case 'tl':
if (flipiY) { ly='b'; } else { ly = 't'; }
if (flipiX) { lx='r'; } else { lx = 'l'; }
break;
case 'tr':
if (flipiY) { ly='b'; } else { ly = 't'; }
if (flipiX) { lx='l'; } else { lx = 'r'; }
break;
case 'bl':
if (flipiY) { ly='t'; } else { ly = 'b'; }
if (flipiX) { lx='r'; } else { lx = 'l'; }
break;
case 'br':
if (flipiY) { ly='t'; } else { ly = 'b'; }
if (flipiX) { lx='l'; } else { lx = 'r'; }
break;
default:
ly=control.substr(0, 1);
lx=control.substr(1, 1);
break;
}
control=ly+lx;
switch (control)
{
case 'tl':
//my custom png for the object top left corner
SelectedIconImage.src = 'assets/img/icons/draw_control/icon_rotate.png';
break;
case 'tr':
if (flipiX && !flipiY) { n='2'; }
if (!flipiX && flipiY) { n='3'; }
if (flipiX && flipiY) { n='4'; }
//my custom png for the object top right corner
SelectedIconImage.src = 'assets/img/icons/draw_control/icon_delete.png';
break;
case 'mt':
SelectedIconImage.src = //add your png here if you want middle top custom image;
break;
case 'bl':
if (flipiY) { n='2'; }
SelectedIconImage.src = //add your png here if you want bottom left corner custom image;
break;
case 'br':
if (flipiX || flipiY) { n='2'; }
if (flipiX && flipiY) { n=''; }
//my custom png for the object bottom right corner
SelectedIconImage.src = 'assets/img/icons/draw_control/icon_settings.png';
break;
case 'mb':
SelectedIconImage.src = //middle bottom png here ;
break;
case 'ml':
SelectedIconImage.src = 'assets/img/icons/draw_control/icono_escala_horizontal'+n+'.jpg';
break;
case 'mr':
SelectedIconImage.src = //middle right png here;
break;
default:
ctx[methodName](left, top, sizeX, sizeY);
break;
}
// keep middle buttons size fixed
if (control == 'tl' || control == 'tr' || control == 'bl' || control == 'br'
|| control == 'mt' || control == 'mb' || control == 'ml' || control == 'mr')
{
sizeX = 19;
sizeY = 19;
ctx.drawImage(SelectedIconImage, left, top, sizeX, sizeY);
}
try {
ctx.drawImage(SelectedIconImage, left, top, sizeX, sizeY);
} catch (e) {
if (e.name != "NS_ERROR_NOT_AVAILABLE") {
throw e;
}
}
}
},
-
Как упоминалось ранее Toon Nelissen, я переопределяю функцию fabric.Canvas.prototype.__onMouseDown
и управляю своими пользовательскими кнопками.
fabric.Canvas.prototype.__onMouseDown = function (e) {
// accept only left clicks
var isLeftClick = 'which' in e ? e.which === 1 : e.button === 1;
if (!isLeftClick && !fabric.isTouchSupported) {
return;
}
if (this.isDrawingMode) {
this._onMouseDownInDrawingMode(e);
return;
}
// ignore if some object is being transformed at this moment
if (this._currentTransform) {
return;
}
var target = this.findTarget(e),
pointer = this.getPointer(e, true);
//if user clicked on the top right corner image
if (target && target.__corner === 'tr') {
//my code goes here
}
} else {
// save pointer for check in __onMouseUp event
this._previousPointer = pointer;
var shouldRender = this._shouldRender(target, pointer),
shouldGroup = this._shouldGroup(e, target);
if (this._shouldClearSelection(e, target)) {
this._clearSelection(e, target, pointer);
} else if (shouldGroup) {
this._handleGrouping(e, target);
target = this.getActiveGroup();
}
if (target && target.selectable && !shouldGroup) {
this._beforeTransform(e, target);
this._setupCurrentTransform(e, target);
}
// we must renderAll so that active image is placed on the top canvas
shouldRender && this.renderAll();
this.fire('mouse:down', { target: target, e: e });
target && target.fire('mousedown', { e: e });
}
};
Для остальных углов мы также напишем соответствующий фрагмент (внутри __onMouseDown):
//if user clicked on the bottom right corner image
if (target && target.__corner === 'br') {
//my code here
}else{
//the same as 'tr'
}
//if user clicked on the top left corner image
if (target && target.__corner === 'tl') {
//my code here
}else{
//the same as 'tr'
}
//if user clicked on the bottom left corner image
if (target && target.__corner === 'bl') {
//my code here
}else{
//the same as 'tr'
}
ниже - снимок экрана моих пользовательских изображений веб-приложения
![введите описание изображения здесь]()
Ответ 4
Вы можете перезаписать функцию __onMouseDown, например, следующим образом.
целевой объект содержит элемент __corner target.__corner
Проверьте, является ли это 'tr' (вверху справа) и удаляет activeObject
if (target.__corner === 'tr') {
if(canvas.getActiveObject()){
canvas.remove(canvas.getActiveObject());
}
}
Полный код:
fabric.Canvas.prototype.__onMouseDown = function (e) {
// accept only left clicks
var isLeftClick = 'which' in e ? e.which === 1 : e.button === 1;
if (!isLeftClick && !fabric.isTouchSupported) {
return;
}
if (this.isDrawingMode) {
this._onMouseDownInDrawingMode(e);
return;
}
// ignore if some object is being transformed at this moment
if (this._currentTransform) {
return;
}
var target = this.findTarget(e),
pointer = this.getPointer(e, true);
if (target && target.__corner === 'tr') {
if(this.getActiveObject()){
this.remove(this.getActiveObject());
}
} else {
// save pointer for check in __onMouseUp event
this._previousPointer = pointer;
var shouldRender = this._shouldRender(target, pointer),
shouldGroup = this._shouldGroup(e, target);
if (this._shouldClearSelection(e, target)) {
this._clearSelection(e, target, pointer);
} else if (shouldGroup) {
this._handleGrouping(e, target);
target = this.getActiveGroup();
}
if (target && target.selectable && !shouldGroup) {
this._beforeTransform(e, target);
this._setupCurrentTransform(e, target);
}
// we must renderAll so that active image is placed on the top canvas
shouldRender && this.renderAll();
this.fire('mouse:down', { target: target, e: e });
target && target.fire('mousedown', { e: e });
}
};
Ответ 5
Вы можете попробовать с помощью кнопок html. Посмотрите на пример:
http://fabricjs.com/interaction-with-objects-outside-canvas/
Вот пример кода:
(function() {
var canvas = this.__canvas = new fabric.Canvas('c');
fabric.Object.prototype.transparentCorners = false;
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
fabric.Canvas.prototype.getAbsoluteCoords = function(object) {
return {
left: object.left + this._offset.left,
top: object.top + this._offset.top
};
}
var btn = document.getElementById('inline-btn'),
btnWidth = 85,
btnHeight = 18;
function positionBtn(obj) {
var absCoords = canvas.getAbsoluteCoords(obj);
btn.style.left = (absCoords.left - btnWidth / 2) + 'px';
btn.style.top = (absCoords.top - btnHeight / 2) + 'px';
}
fabric.Image.fromURL('../lib/pug.jpg', function(img) {
canvas.add(img.set({ left: 250, top: 250, angle: 30 }).scale(0.25));
img.on('moving', function() { positionBtn(img) });
positionBtn(img);
});
})();