Группа контролирует смещение при повороте fabric.js - PullRequest
0 голосов
/ 20 декабря 2018

Я создал пользовательский класс ткани "VectorPlaceholder", который в основном представляет собой группу, содержащую прямоугольник и вектор:

// Fabric.js custom vector EPS object
fabric.VectorPlaceholder = fabric.util.createClass(fabric.Group, {
    async: true,
    type: 'vector-placeholder',
    lockUniScalingWithSkew: false,
    noScaleCache: true,


    initialize: function (options) {                

        boundsRectangle = new fabric.Rect({            
            strokeDashArray: [10,10],
            originX: 'center',
            originY: 'center',
            stroke: '#000000',
            strokeWidth: 1,
            width: options.width || 300,
            height: options.height || 300,
            fill: 'rgba(0, 0, 0, 0)',            
        });

        this.setControlsVisibility({            
            ml: false,
            mb: false,
            mr: false,
            mt: false,            
        });

        this.originX = 'center',
        this.originY = 'center',

        this.callSuper('initialize', [boundsRectangle], options);

    },

    setVector: function (vector) {        
        //We remove any EPS that was in that position
        var EPSGroup = this;
        EPSGroup.forEachObject(function (object) {
            if (object && object.type != "rect") {
                EPSGroup.remove(object);
            }
        });

        var scale = 1;        
        var xOffset = EPSGroup.getScaledWidth() / 2;
        var yOffset = EPSGroup.getScaledHeight() / 2;
        if (vector.height > vector.width) {            
            scale = EPSGroup.getScaledHeight() / vector.height;
            xOffset = xOffset - (EPSGroup.getScaledWidth() - vector.width * scale) / 2

        }
        else {
            scale = EPSGroup.getScaledWidth() / vector.width;
            yOffset = yOffset - (EPSGroup.getScaledHeight() - vector.height * scale) / 2

        }

        vector.left = EPSGroup.left - xOffset;
        vector.top = EPSGroup.top - yOffset;        
        vector.set('scaleY', scale);
        vector.set('scaleX', scale);
        var angle = 0;        
        if (EPSGroup.get('angle')) {
            angle = EPSGroup.get('angle');
            vector.setAngle(angle);                        
        }        
        EPSGroup.addWithUpdate(vector);
        EPSGroup.setCoords();      
    },

});

Идея этого класса состоит в том, чтобы иметь заполнитель, куда пользователи могут загружатьSVGs.Это делается путем вызова fabric.loadSVGFromString, а затем передачи результата в функцию в моем пользовательском классе (setVector)

fabric.loadSVGFromString(svgString, function(objects, options) {
   // Group the SVG objects to make a single element
   var a = fabric.util.groupSVGElements(objects, options);
   var EPSGroup = new fabric.VectorPlaceholder({});
   EPSGroup.setVector(a);   

. Это прекрасно работает, когда я создаю свой пользовательский объект и не поворачиваю его.Как видите, элементы управления группы выровнены по пунктирному прямоугольнику.

enter image description here

Проблема заключается в том, что я создаю пустой объект VectorPlaceholder и вращаю его вручную.После ручного вращения, когда вызывается setVector, вот что происходит:

enter image description here

Я не могу понять, почему группы управления игнорируют вращение, что яя делаю неправильно?Как сделать так, чтобы элементы управления группы были выровнены по повернутому прямоугольнику?

1 Ответ

0 голосов
/ 20 декабря 2018

Вам нужно установить угол после выполнения setVector метода http://jsfiddle.net/2segrwx0/1/

// Fabric.js custom vector EPS object
fabric.VectorPlaceholder = fabric.util.createClass(fabric.Group, {
    async: true,
    type: 'vector-placeholder',
    lockUniScalingWithSkew: false,
    noScaleCache: true,


    initialize: function (options) {                

        boundsRectangle = new fabric.Rect({            
            strokeDashArray: [10,10],
            originX: 'center',
            originY: 'center',
            stroke: '#000000',
            strokeWidth: 1,
            width: options.width || 300,
            height: options.height || 300,
            fill: 'rgba(0, 0, 0, 0)',            
        });

        this.setControlsVisibility({            
            ml: false,
            mb: false,
            mr: false,
            mt: false,            
        });

        this.originX = 'center',
        this.originY = 'center',

        this.callSuper('initialize', [boundsRectangle], options);

    },

    setVector: function (vector) {        
        //We remove any EPS that was in that position
        var EPSGroup = this;
        EPSGroup.forEachObject(function (object) {
            if (object && object.type != "rect") {
                EPSGroup.remove(object);
            }
        });

        var scale = 1;        
        var xOffset = EPSGroup.getScaledWidth() / 2;
        var yOffset = EPSGroup.getScaledHeight() / 2;
        if (vector.height > vector.width) {            
            scale = EPSGroup.getScaledHeight() / vector.height;
            xOffset = xOffset - (EPSGroup.getScaledWidth() - vector.width * scale) / 2

        }
        else {
            scale = EPSGroup.getScaledWidth() / vector.width;
            yOffset = yOffset - (EPSGroup.getScaledHeight() - vector.height * scale) / 2

        }

        vector.left = EPSGroup.left - xOffset;
        vector.top = EPSGroup.top - yOffset;        
        vector.set('scaleY', scale);
        vector.set('scaleX', scale);
        /*var angle = 0;        
        if (EPSGroup.get('angle')) {
            angle = EPSGroup.get('angle');
            vector.setAngle(angle);                        
        }       */ 
        EPSGroup.addWithUpdate(vector);
        EPSGroup.setCoords();      
    },

});

 canvas = new fabric.Canvas('c', {
 
});


fabric.loadSVGFromString('<svg height="210" width="500"><polygon points="100,10 40,198 190,78 10,78 160,198" style="fill:lime;stroke:purple;stroke-width:5;fill-rule:nonzero;" /></svg>', function(objects, options) {
   // Group the SVG objects to make a single element
   var a = fabric.util.groupSVGElements(objects, options);
   var EPSGroup = new fabric.VectorPlaceholder({});
   EPSGroup.left=200;
   EPSGroup.top=200;

   EPSGroup.setVector(a);  
    EPSGroup.angle=45;
   canvas.add(EPSGroup);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.4.5/fabric.js"></script>
<canvas id="c" width=500 height=300 ></canvas>
...