valor tiene style saber propiedades obtener modificar elemento ejemplo data con cambiar boton atributos atributo agregar javascript html5 canvas html5-canvas fabricjs

javascript - tiene - obtener atributo class jquery



Adición de un botón Eliminar personalizado(Atrás, al frente) a los controles (5)

Me gustaría saber si hay una manera fácil de agregar una eliminación, traer al frente, traer la función hacia atrás a los controles de objetos fabric.js existentes.

En este momento solo puedo hacer clic en los botones que eliminan el objeto, lo traen al frente, etc.

Estoy trabajando para encontrar una solución para poder presionar X (en la esquina superior derecha) del objeto y eliminar el objeto.

Supongo que tendrá que ver con sobrescribir, ajustar o subclasificar el objeto de control existente.

Tal vez he supervisado algo y hay una solución fácil? Por favor, no div envoltorio.


Fabric.js no ofrece ningún medio simple para agregar controles a los objetos. Si desea crear sus propios controles, tendrá que sobrescribir la clase Objeto, en particular:

  • anular drawControls , para dibujar su botón personalizado
  • Deberá almacenar las coordenadas del botón, de modo que pueda detectar cuándo el usuario hace clic en ellas. Cf _setCornerCoords y _findTargetCorner
  • Incorpora tu acción en algún lugar en __onMouseDown

No es necesario que se ocupe de "desenganchar" los controles, ya que todo el lienzo se vuelve a representar cuando se deselecciona un objeto.

Espero que esto ayude. Mucha suerte :)


Lo he implementado mediante el posicionamiento de un elemento 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">&#10005;</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">&#10005;</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(); } })


Puede sobrescribir la función __onMouseDown, por ejemplo, como esta.

el objeto de destino contiene __corner elemento target.__corner

Compruebe si esto es ''tr'' (arriba a la derecha) y elimine activeObject

if (target.__corner === ''tr'') { if(canvas.getActiveObject()){ canvas.remove(canvas.getActiveObject()); } }

Código completo:

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 }); } };


Puedes probar con los botones html. Mira el ejemplo:

http://fabricjs.com/interaction-with-objects-outside-canvas/

Aquí está el ejemplo del código:

(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); }); })();


creo que la solución con los elementos de dom no es tan estable, pero está bien si cubre sus necesidades, también necesitaba cambiar los botones de esquina predeterminados del objeto, a mis botones personalizados para mi aplicación web. Yo suelo ,

  1. botón ''alterar tamaño'', / no lo uso más por mis razones /
  2. botón ''eliminar objeto''
  3. botón ''editar objeto''
  4. botón ''rotar objeto''

así que tienes que cambiar 2 cosas para tener éxito que:

1. Cambie la función privada ''_drawControl'' del archivo fabric.js. Esto es sobre la línea 13367 (en mi fabric.js). En esa función, la estructura dibuja los botones de red predeterminados de los objetos y los muestra en selec. Podemos cambiar fácilmente el png a nuestros personalizados.

debajo está mi _drawControl cambiado (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''s 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''s 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''s 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; } } } },

  1. Como mencionó Toon Nelissen , superé la función fabric.Canvas.prototype.__onMouseDown y fabric.Canvas.prototype.__onMouseDown mis botones personalizados.

    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 }); }

    };

Para las demás esquinas, también escribimos el fragmento apropiado (dentro de __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'' }

A continuación se muestra una captura de pantalla de las imágenes personalizadas de mi aplicación web.