Правильный подход к загружаемым маскам в Fabric.js - PullRequest
0 голосов
/ 26 октября 2018

У меня есть эта награда за открытие Маска объекта Fabricjs с преобразованием при попытке маскировать объекты с помощью Fabric.js.

Инструмент, который я разрабатываю, должен позволять пользователям рисовать маску поверх изображенияобъекты и применять преобразования (поворот наклона и т. д.) к этому объекту до или после маски.Я близок к получению этого результата, но объекты с углом по-прежнему не работают.

Я также пытаюсь сохранить этот объект в базе данных, используя toJSON и loadFromJSON, но через несколько днейпытаясь достичь этого, я понимаю, что это решение не будет работать, поскольку при загрузке из JSON невозможно получить доступ к любым ссылкам вне области действия ctx, поэтому они выдают ошибку.

    clipTo: function(ctx) {
        mask.set({
            left:
                -object.width / 2 -
                (mask.width / 2) * originalMaskScaleX -
                originalObjLeft / originalObjScaleX,
            top:
                -object.height / 2 -
                (mask.height / 2) * originalMaskScaleY -
                originalObjTop / originalObjScaleY,
            objectCaching: false
        });
        mask.render(ctx);
    }

Is Fabric.jsправильное решение этой проблемы?Должен ли я использовать что-то еще?Если это можно сделать с помощью Fabric.js, каков правильный подход?

1 Ответ

0 голосов
/ 26 октября 2018

Я расширил fabric.Image с некоторыми пользовательскими атрибутами.Также я прикрепил маску на fabric.Image.Для fabric.Image.fromObject после загрузки изображения мне нужно также загрузить маску (я знаю, что это путь) и прикрепить к изображению.Это быстрая реализация.Я уверен, что этот код может быть упрощен.Пожалуйста, скажите мне, если что-то не понятно

 

    canvas = new fabric.Canvas("canvas", {
   backgroundColor: "lightgray",
   width: 1280,
   height: 720,
   preserveObjectStacking: true,
   selection: false,
   stateful: true
 });

 canvas.isDrawingMode = true;
 canvas.freeDrawingBrush.color = "black";
 canvas.freeDrawingBrush.width = 2;

 canvas.on("path:created", function(options) {

   clip(options.path);
 });

 function clip(path) {
   canvas.isDrawingMode = false;
   canvas.remove(path);

   let mask = new fabric.Path(path.path, {
     top: object.top,
     left: object.left,
     objectCaching: false,
     strokeWidth: 0,
     scaleX: 1 / object.scaleX,
     scaleY: 1 / object.scaleY,
     pathOffset: {
       x: 0,
       y: 0
     }
   });
   object = canvas.getObjects()[0];
   object.originalObjLeft = object.left,
     object.originalObjTop = object.top,
     object.originalMaskScaleX = mask.scaleX,
     object.originalMaskScaleY = mask.scaleY,
     object.originalObjScaleX = object.scaleX,
     object.originalObjScaleY = object.scaleY;
     var transformedTranslate = object.translateToGivenOrigin({
        x: object.left,
        y: object.top
    }, object.originX, object.originY, 'center', 'center');
    object.originalTransformLeft = transformedTranslate.x - object.getCenterPoint().x;
    object.originalTransformTop = transformedTranslate.y - object.getCenterPoint().y;
    object.originalAngle = object.angle;
    
    
   object.clipMask = mask;
   object.set({
     clipTo: function(ctx) {
			 
        ctx.save();
        ctx.rotate(-this.originalAngle * Math.PI / 180);

        ctx.translate(this.originalTransformLeft / this.originalObjScaleX, this.originalTransformTop / this.originalObjScaleY)

       
       
       this.clipMask.set({
         left: -object.width / 2 - (this.clipMask.width / 2 * this.originalMaskScaleX) - this.originalObjLeft / this.originalObjScaleX,
         top: -object.height / 2 - (this.clipMask.height / 2 * this.originalMaskScaleY) - this.originalObjTop / this.originalObjScaleY,
         objectCaching: false
       });
       this.clipMask.render(ctx);
        ctx.restore();
     }
   });

   canvas.requestRenderAll();
 }

 // image

 let image = new Image();


 image.onload = function() {
   object = new fabric.Image(image, {
     width: 500,
     height: 500,
     scaleX: 0.8,
     scaleY: 0.8,
      angle: 45,
     top: 50,
     left: 100
   });

   canvas.add(object);
 };

 image.src = "http://i.imgur.com/8rmMZI3.jpg";

 fabric.util.object.extend(fabric.Image.prototype, {
   clipMask: null,
   originalObjLeft: 0,
   originalObjTop: 0,
   originalMaskScaleX: 1,
   originalMaskScaleY: 1,
   originalObjScaleX: 1,
   originalObjScaleY: 1,
   originalAngle:0,
   originalTransformLeft:0,
   originalTransformTop:0
 });
 fabric.Image.prototype.toObject = (function(toObject) {
   return function(propertiesToInclude) {
     return fabric.util.object.extend(toObject.call(this, propertiesToInclude), {
       clipMask: this.clipMask ? this.clipMask.toObject(propertiesToInclude) : null,
       originalObjLeft: this.originalObjLeft,
       originalObjTop: this.originalObjTop,
       originalMaskScaleX: this.originalMaskScaleX,
       originalMaskScaleY: this.originalMaskScaleY,
       originalObjScaleX: this.originalObjScaleX,
       originalObjScaleY: this.originalObjScaleY,
       originalAngle:this.originalAngle,
       originalTransformLeft:this.originalTransformLeft,
       originalTransformTop:this.originalTransformTop
     });
   }
 })(fabric.Image.prototype.toObject);

 fabric.Image.fromObject = (function(fromObject) {
   return function(_object, callback) {
     fromObject.call(this, _object, (function(callback, _object) {
       return function(image) {
         if (image.clipMask) {
           fabric.Path.fromObject(image.clipMask, (function(callback) {
             return function(path) {
               path.pathOffset.x = 0;
               path.pathOffset.y = 0;
               image.clipMask = path;
               callback(image);
             }
           })(callback))
         } else {
           callback(image);
         }
       }
     })(callback, _object));
     return;
   }
 })(fabric.Image.fromObject)




 $("#button1").on('click', function() {
   let dataJSON = canvas.toJSON();
   canvas.clear();
   canvas.loadFromJSON(
     dataJSON,
     canvas.renderAll.bind(canvas));
 })
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.6/fabric.js"></script>
<script src="https://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<button id="button1">SAve/Load JSON</button>
<div class="canvas__wrapper">
  <canvas id="canvas" width="1280" height="720"></canvas>
</div>

ОБНОВЛЕНИЕ Я обновил код, чтобы устранить проблему с углом от здесь :

...